Minimal viable kernel

This commit is contained in:
Imbus 2025-06-26 02:43:43 +02:00
commit e4d9be3aa7
5 changed files with 166 additions and 0 deletions

22
.gitignore vendored Normal file
View file

@ -0,0 +1,22 @@
*~
_*
*.o
*.d
*.asm
*.sym
*.img
*.elf
vectors.S
bootblock
entryother
initcode
initcode.out
kernelmemfs
mkfs
kernel/kernel
user/usys.S
.gdbinit
.vscode
.cache
compile_commands.json
tags

48
Makefile Normal file
View file

@ -0,0 +1,48 @@
TOOLPREFIX = riscv-none-elf
CC = $(TOOLPREFIX)-gcc
AS = $(TOOLPREFIX)-as
LD = $(TOOLPREFIX)-ld
OBJCOPY = $(TOOLPREFIX)-objcopy
OBJDUMP = $(TOOLPREFIX)-objdump
ASFLAGS = -march=rv64gc -mabi=lp64
LDFLAGS = -Tlink.ld
LDFLAGS += -m elf64lriscv
CFLAGS = -Wall -Werror -O
CFLAGS += -mcmodel=medany
CFLAGS += -march=rv64gc -mabi=lp64
CFLAGS += -ffreestanding -fno-common -nostdlib -mno-relax
CFLAGS += -I.
CFLAGS += -fno-stack-protector # Prevents code that needs libc / runtime support
CFLAGS += -MD # Generate header dependency files (.d)
CFLAGS += -fno-pie -no-pie # Fixed address linking
CFLAGS += -ggdb -gdwarf-2 # GDB debug info
CFLAGS += -fno-omit-frame-pointer # More reliable backtraces in GDB
all: kernel.elf
kernel.elf: entry.o start.o
@echo LD $@
@$(LD) $(LDFLAGS) -o $@ $^
%.o: %.c
@echo CC $@
@$(CC) $(CFLAGS) -nostdinc -I. -c $< -o $@
%.o: %.S
@echo AS $@
@$(AS) $(ASFLAGS) -o $@ $<
qemu: kernel.elf
@echo QEMU $@
@qemu-system-riscv64 -machine virt -bios none -nographic -kernel kernel.elf
clean:
rm -f *.o *.elf *.d
-include *.d

62
entry.S Normal file
View file

@ -0,0 +1,62 @@
.section .text
.globl _start
_start:
li x1, 0x0
li x2, 0x0
li x3, 0x0
li x4, 0x0
li x5, 0x0
li x6, 0x0
li x7, 0x0
li x8, 0x0
li x9, 0x0
li x10, 0x0
li x11, 0x0
li x12, 0x0
li x13, 0x0
li x14, 0x0
li x15, 0x0
li x16, 0x0
li x17, 0x0
li x18, 0x0
li x19, 0x0
li x20, 0x0
li x21, 0x0
li x22, 0x0
li x23, 0x0
li x24, 0x0
li x25, 0x0
li x26, 0x0
li x27, 0x0
li x28, 0x0
li x29, 0x0
li x30, 0x0
li x31, 0x0
li t0, 0x10000000 # UART base address
li t1, 'E' # Character to print
sb t1, 0(t0)
li t1, 'n'
sb t1, 0(t0)
li t1, 't'
sb t1, 0(t0)
li t1, 'r'
sb t1, 0(t0)
li t1, 'y'
sb t1, 0(t0)
li t1, '\n'
sb t1, 0(t0)
# Set up a stack for C.
la sp, stack0
li a0, 1024*4 # a0 = 4096
csrr a1, mhartid # a1 = hart id
addi a1, a1, 1 # hartid + 1
mul a0, a0, a1 # a0 *= hartid+1
add sp, sp, a0 # sp += a0
# Jump to start() in start.c
call start
1:
j 1b # Infinite loop

14
link.ld Normal file
View file

@ -0,0 +1,14 @@
ENTRY(_start)
SECTIONS {
. = 0x80000000;
.text : {
*(.text)
} :text
}
PHDRS {
text PT_LOAD FLAGS(0x5); /* R + X */
}

20
start.c Normal file
View file

@ -0,0 +1,20 @@
#define NCPU 3
#define UART ((char *)0x10000000)
void uart_putc(char c) {
*UART = c;
}
void uart_puts(const char *s) {
while (*s) {
uart_putc(*s++);
}
}
// Entry.S needs one stack per CPU.
__attribute__((aligned(16))) char stack0[4096 * NCPU];
void start() {
uart_puts("Hello Neptune!\n");
}