Currently the bootwrapper only works for Fast Models, as the Versatile Express BootMonitor doesn't allow execution of elf files with multiple program headers. A workaround is to load the kernel image separately from the bootwrapper elf file, using BootMonitor. Note that BootMonitor will crash, when trying to load a uImage kernel, zImage is needed instead. The same applies for the actual elf file, it should be flashed, instead of loaded from the MMC. - A new make target has been added (board), which uses a different linker script (board.lds.S), without including the kernel image. - A major difference between the real target and Fast Models, is that BootMonitor has already placed CPU1 in wfi state. - In order to run the bootwrapper on CPU1 we have to generate a software interrupt first and point it to jump to the right location, by writing the address to SYS_FLAGS. - Monitor location has been updated to the last 8MBs of the 2GB memory address space. Previously it was on the last 256MBs. - Code relocation for CPU1 wfe state, has been moved behind the monitor section, instead of the initrd region. --- Makefile | 23 +++++++++++++++++++---- board.lds.S | 24 ++++++++++++++++++++++++ boot.S | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- model.lds.S | 5 +++-- 4 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 board.lds.S diff --git a/Makefile b/Makefile index 995fd8f..92f013f 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,9 @@ KERNEL = uImage IMAGE = linux-system.axf SEMIIMG = linux-system-semi.axf +BOARD = board.axf LD_SCRIPT = model.lds.S +B_LD_SCRIPT = board.lds.S CC = $(CROSS_COMPILE)gcc @@ -32,14 +34,18 @@ LD = $(CROSS_COMPILE)ld export CROSS_COMPILE ARCH # Build all wrappers -all: $(IMAGE) $(SEMIIMG) +all: $(IMAGE) $(SEMIIMG) $(BOARD) # Build just the semihosting wrapper semi: $(SEMIIMG) +# Build wrapper for the versatile express board +board: $(BOARD) + clean distclean: - rm -f $(IMAGE) $(SEMIIMG) \ - model.lds modelsemi.lds $(OBJS) $(KERNEL) + rm -f $(IMAGE) $(SEMIIMG) $(BOARD) \ + model.lds modelsemi.lds board.lds \ + board.o $(OBJS) $(KERNEL) $(KERNEL): $(KERNEL_SRC)/arch/arm/boot/uImage cp $< $@ @@ -50,12 +56,18 @@ $(IMAGE): $(OBJS) model.lds $(KERNEL) $(FILESYSTEM) Makefile $(SEMIIMG): $(OBJS) modelsemi.lds $(LD) -o $@ $(OBJS) --script=modelsemi.lds +$(BOARD): board.o monitor.o board.lds Makefile + $(LD) -o board.axf --script=board.lds + boot.o: $(BOOTLOADER) $(CC) $(CPPFLAGS) -DKCMD='$(KCMD)' -c -o $@ $< monitor.o: $(MONITOR) $(CC) $(CPPFLAGS) -c -o $@ $< +board.o: $(BOOTLOADER) + $(CC) $(CPPFLAGS) -DKCMD='$(KCMD)' -DBOARD -c -o $@ $< + %.o: %.c $(CC) $(CPPFLAGS) -O2 -ffreestanding -Ilibfdt -c -o $@ $< @@ -65,6 +77,9 @@ model.lds: $(LD_SCRIPT) Makefile modelsemi.lds: $(LD_SCRIPT) Makefile $(CC) $(CPPFLAGS) -DSEMIHOSTING=1 -E -P -C -o $@ $< +board.lds: $(B_LD_SCRIPT) Makefile + $(CC) $(CPPFLAGS) -DBOARD -E -P -C -o $@ $< + $(KERNEL_SRC)/arch/arm/boot/uImage: force $(MAKE) -C $(KERNEL_SRC) -j4 uImage @@ -79,4 +94,4 @@ force: ; Makefile: ; -.PHONY: all semi clean distclean config.mk config-default.mk +.PHONY: all semi board clean distclean config.mk config-default.mk \ No newline at end of file diff --git a/board.lds.S b/board.lds.S new file mode 100644 index 0000000..62bcede --- /dev/null +++ b/board.lds.S @@ -0,0 +1,24 @@ +OUTPUT_FORMAT("elf32-littlearm") +OUTPUT_ARCH(arm) +TARGET(binary) + +INPUT(./board.o) +INPUT(./monitor.o) + +PHYS_OFFSET = 0x80000000; +MON_OFFSET = 0xff800000; + +SECTIONS +{ + . = PHYS_OFFSET + 0x8000; + kernel = .; + + . = PHYS_OFFSET + 0x10000000; + fs_start = .; + + . = MON_OFFSET; + monitor = .; + + .monitor : { monitor.o } + .text : { board.o } +} diff --git a/boot.S b/boot.S index 61cd93f..f65446d 100644 --- a/boot.S +++ b/boot.S @@ -12,10 +12,24 @@ .arch_extension virt .text + .equ GICD_CTLR, 0x2c001000 + .equ VE_SYS_FLAGS, 0x1c010030 .globl start start: #ifdef SMP +#ifdef BOARD + @ Update SYS_FLAGS with the address that CPU1 will jump to + ldr r0, =VE_SYS_FLAGS + ldr r1, =CPU1_ENTRY + str r1, [r0] + + @ Generate Software Interrupt to wake CPU1 from wfi state + ldr r0, =GICD_CTLR + ldr r1, =0x01000001 + str r1, [r0, #0xf00] +CPU1_ENTRY: +#endif #ifdef VEXPRESS @ @ Program architected timer frequency @@ -39,7 +53,7 @@ start: @ @ Set all interrupts to be non-secure - ldr r0, =0x2c001000 @ Dist GIC base + ldr r0, =GICD_CTLR @ Dist GIC base ldr r1, [r0, #0x04] @ Type Register cmp r4, #0 andeq r1, r1, #0x1f @@ -64,7 +78,7 @@ start: mcr p15, 0, r0, c1, c1, 2 @ Leave monitor.S trap in place for the transition... - mov r0, #0xf0000000 + ldr r0, =monitor mcr p15, 0, r0, c12, c0, 1 @ Monitor vector base address @ Set up hvbar so hvc comes back here. @@ -100,13 +114,19 @@ into_hyp_mode: @ @ Secondary CPUs (following the RealView SMP booting protocol) @ +#ifdef BOARD + @ Clear SYS_FLAGS to let the kernel wake CPU1 properly + ldr r0, =VE_SYS_FLAGS + ldr r1, =0xffffffff + str r1, [r0, 0x04] +#endif - ldr r1, =fs_start - 0x100 + ldr r1, =monitor - 0x100 adr r2, 1f ldmia r2, {r3 - r7} @ move the code to a location stmia r1, {r3 - r7} @ less likely to be overridden #ifdef VEXPRESS - ldr r0, =0x1c010030 @ VE SYS_FLAGS register + ldr r0, =VE_SYS_FLAGS @ VE SYS_FLAGS register #else ldr r0, =0x10000030 @ RealView SYS_FLAGS register #endif @@ -122,6 +142,7 @@ into_hyp_mode: #endif 2: +#ifndef BOARD @ @ UART initialisation (38400 8N1) @ @@ -174,3 +195,31 @@ kernel_cmd: .asciz KCMD #endif kernel_cmd_end: +#else /* BOARD */ +run_kernel: + @ + @ Kernel parameters + @ + mov r0, #0 + ldr r1, =2272 @ Versatile Express + adr r2, atags + mov r3, #0 + ldr lr, =kernel + mov pc, lr @ jump to the kernel + +atags: + @ ATAG_CORE + .long 2 + .long 0x54410001 + + @ ATAG_CMDLINE + .long (1f - .) >> 2 + .long 0x54410009 + /* The kernel boot command line is defined in config.mk */ + .asciz KCMD + .align 2 +1: + @ ATAG_NONE + .long 0 + .long 0x00000000 +#endif /* BOARD */ diff --git a/model.lds.S b/model.lds.S index 07fae8c..af3f326 100644 --- a/model.lds.S +++ b/model.lds.S @@ -21,8 +21,8 @@ INPUT(./uImage) PHYS_OFFSET = 0x80000000; -MON_OFFSET = 0xf0000000; -STACKTOP = 0xff000000; +MON_OFFSET = 0xff800000; +STACKTOP = 0xfff00000; SECTIONS @@ -47,6 +47,7 @@ SECTIONS . = MON_OFFSET; + monitor = .; .monitor : { monitor.o } /* Put most of the actual boot loader code up in high memory -- 1.7.9.5