summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby Bingham <koorogi@koorogi.info>2015-07-19 17:17:06 -0500
committerBobby Bingham <koorogi@koorogi.info>2015-09-15 22:43:32 -0500
commitf3885c4b23b0e13d7fe9ef4674a07e746acca320 (patch)
treebaece81713adf89b3c162be7c06dce3a8764747f
parente3cbe8f7712fe97d90ff1fb5c675df9a1632eb45 (diff)
build bootloaders from code
This adds the infrastructure for building from source the bootloaders which will go into the application initial program, in the boot sector. As a simple test case, it includes a simple bootloader which merely jumpts to the code address specified in the AIP, with the stack address specified there.
-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);
+}
+