summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile15
-rw-r--r--boot/bootloader.h55
-rw-r--r--boot/ldscript22
-rw-r--r--boot/simple.c10
4 files changed, 99 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index af28deb..de590e8 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,10 @@
CFLAGS = -Os -pipe -std=c99 -D_POSIX_C_SOURCE=200809L
LDFLAGS =
+BOOTSRCS = $(sort $(wildcard boot/*.c))
+BOOTELFS = $(patsubst %.c,%.elf,$(BOOTSRCS))
+BOOTBINS = $(patsubst boot/%.c,share/%.boot,$(BOOTSRCS))
+
SRCS = $(sort $(wildcard src/*.c))
DATA = $(sort $(wildcard src/*.bin))
OBJS = $(SRCS:.c=.o) $(DATA:.bin=.o)
@@ -8,17 +12,22 @@ BINS = bin/satmkboot
.PHONY: all clean
-all: $(BINS)
+all: $(BINS) $(BOOTBINS)
clean:
- rm -f $(BINS)
- rm -f $(OBJS)
+ rm -f $(BINS) $(OBJS) $(BOOTBINS) $(BOOTELFS)
bin/satmkboot: \
src/satmkboot.o \
src/securitycode.o \
src/symbols.o
+share/%.boot: boot/%.elf
+ saturn-objcopy -O binary $< $@
+
+%.elf: %.c boot/ldscript
+ saturn-gcc -nostdlib -T boot/ldscript $(CFLAGS) $< -o $@
+
%.c: %.bin
tools/bin2c $< > $@
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);
+}
+