diff options
Diffstat (limited to 'boot')
-rw-r--r-- | boot/bootloader.h | 55 | ||||
-rw-r--r-- | boot/ldscript | 22 | ||||
-rw-r--r-- | boot/simple.c | 10 |
3 files changed, 87 insertions, 0 deletions
diff --git a/boot/bootloader.h b/boot/bootloader.h new file mode 100644 index 0000000..e5c013d --- /dev/null +++ b/boot/bootloader.h @@ -0,0 +1,55 @@ +#include "../src/bootinfo.h" + +/* to be provider by the bootloader including this header */ +_Noreturn void bootloader(struct systemid *boot); + +__asm__( +".text \n" +".extern __bss_start \n" +".extern __bss_end \n" +".global __start \n" +".type __start, @function \n" +"__start: \n" + +/* zero any bss section */ +" mov #0, r0 \n" +" mov.l 1f, r1 \n" +" mov.l 2f, r2 \n" +"0: cmp/hi r1, r2 \n" +" bf 0f \n" +" bra 0b \n" +" mov.l r0, @-r2 \n" + +/* cannibalize code before this for stack space, and pass control to C */ +"0: mov.l 3f, r15 \n" +" mov.l 4f, r4 \n" +" bra bootloader \n" +" nop \n" + +".align 2 \n" +"1: .long __bss_start \n" +"2: .long __bss_end \n" +"3: .long __start \n" +"4: .long 0x06002000 \n" +); + +/* helper to jump to the specified code with the specified stack */ +static inline _Noreturn void jump(const void *code, long *stack) +{ + __asm__ __volatile__( + " jmp @%0\n" + " mov %1, r15\n" + : : "r"(code), "r"(stack) + ); + __builtin_unreachable(); +} + +/* helper to abort by repeatedly executing an illegal instruction */ +static inline _Noreturn void fail(void) +{ + __asm__ __volatile__( + "0: bra 0b\n" + " .word 0xfffd\n" + ); + __builtin_unreachable(); +} diff --git a/boot/ldscript b/boot/ldscript new file mode 100644 index 0000000..53a20bf --- /dev/null +++ b/boot/ldscript @@ -0,0 +1,22 @@ +OUTPUT_FORMAT(elf32-shbig-linux) +ENTRY(__start) +SECTIONS +{ + . = 0x06002f00; + .text : + { + *(.text); + } + .data : + { + *(.data); + *(.rodata); + } + .bss ALIGN(4) : + { + __bss_start = .; + *(.bss); + __bss_end = (. + 3) & ~ 3; + } +} + diff --git a/boot/simple.c b/boot/simple.c new file mode 100644 index 0000000..ca3e796 --- /dev/null +++ b/boot/simple.c @@ -0,0 +1,10 @@ +#include "bootloader.h" + +_Noreturn void bootloader(struct systemid *boot) +{ + if (!boot->load_addr) fail(); + + long *stack = (long*) (boot->stack_master ? boot->stack_master : 0x06002000); + jump((void*) boot->load_addr, stack); +} + |