summaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/bootloader.h55
-rw-r--r--boot/ldscript22
-rw-r--r--boot/simple.c10
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);
+}
+