diff --git a/kernel.ld b/kernel.ld new file mode 100644 index 0000000..8bd2f25 --- /dev/null +++ b/kernel.ld @@ -0,0 +1,49 @@ +/* + * This is the entry point + * `boot` should be a defined label + */ +ENTRY(boot) + +/* SECTIONS tells to linker how to arrange sections inside the memory */ +SECTIONS { + /* + * This is the base address (start address of the kernel) + * OpenSBI takes little ram + */ + . = 0x80200000; + + /* This section contains the code of the program */ + .text :{ + /* + * Take the .text.boot before everything + * KEEP() prevents the linker to mark it as "unused" + */ + KEEP(*(.text.boot)); + /* Include everything else inside the .text section */ + *(.text .text.*); + } + + /* + * Contains constant read-only data + * Align the start of the section at 4 byte + */ + .rodata : ALIGN(4) { + *(.rodata .rodata.*); + } + + /* Contains read/write data */ + .data : ALIGN(4) { + *(.data .data.*); + } + + /* Contains read/data with an initial value of zero */ + .bss : ALIGN(4) { + __bss = .; + *(.bss .bss.* .sbss .sbss.*); + __bss_end = .; + } + + . = ALIGN(4); + . += 128 * 1024; /* 128KB */ + __stack_top = .; +} diff --git a/src/kernel.c b/src/kernel.c new file mode 100644 index 0000000..e501bb3 --- /dev/null +++ b/src/kernel.c @@ -0,0 +1,28 @@ +typedef unsigned char u8; +typedef unsigned int u32; +typedef u32 size_t; + +extern char __bss[], __bss_end[], __stack_top[]; + +void *memset(void *buf, char c, size_t n) { + u8 *p = (u8 *)buf; + while (n--) { + *p++ = c; + } + + return buf; +} + +void kernel_main(void) { + memset(__bss, 0, __bss_end - __bss); + + for (;;) + ; +} + +__attribute__((section(".text.boot"))) __attribute__((naked)) void boot(void) { + __asm__ __volatile__("mv sp, %[stack_top]\n" + "j kernel_main\n" + : + : [stack_top] "r"(__stack_top)); +}