diff options
-rw-r--r-- | Makefile | 15 | ||||
-rw-r--r-- | boot/bootloader.h | 55 | ||||
-rw-r--r-- | boot/ldscript | 22 | ||||
-rw-r--r-- | boot/simple.c | 10 |
4 files changed, 99 insertions, 3 deletions
@@ -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); +} + |