diff options
Diffstat (limited to 'sys/boot/arm')
-rw-r--r-- | sys/boot/arm/uboot/Makefile | 40 | ||||
-rw-r--r-- | sys/boot/arm/uboot/ldscript.arm | 18 | ||||
-rw-r--r-- | sys/boot/arm/uboot/start.S | 48 |
3 files changed, 72 insertions, 34 deletions
diff --git a/sys/boot/arm/uboot/Makefile b/sys/boot/arm/uboot/Makefile index 8f718be..b4c5463 100644 --- a/sys/boot/arm/uboot/Makefile +++ b/sys/boot/arm/uboot/Makefile @@ -2,7 +2,8 @@ .include <bsd.own.mk> -PROG= ubldr +FILES= ubldr ubldr.bin + NEWVERSWHAT= "U-Boot loader" ${MACHINE_ARCH} BINDIR?= /boot INSTALLFLAGS= -b @@ -12,7 +13,7 @@ WARNS?= 1 UBLDR_LOADADDR?= 0x1000000 # Architecture-specific loader code -SRCS= start.S conf.c vers.c +SRCS= start.S conf.c self_reloc.c vers.c .if !defined(LOADER_NO_DISK_SUPPORT) LOADER_DISK_SUPPORT?= yes @@ -93,9 +94,7 @@ CLEANFILES+= vers.c loader.help CFLAGS+= -ffreestanding -msoft-float -LDFLAGS= -nostdlib -static -LDFLAGS+= -T ldscript.generated -LDFLAGS+= -T ${.CURDIR}/ldscript.${MACHINE_CPUARCH} +LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.${MACHINE_CPUARCH} # Pull in common loader code .PATH: ${.CURDIR}/../../uboot/common @@ -116,6 +115,8 @@ NO_WERROR.clang= DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSTAND} LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} -lstand +OBJS+= ${SRCS:N*.h:R:S/$/.o/g} + vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} @@ -123,17 +124,24 @@ loader.help: help.common help.uboot ${.CURDIR}/../../fdt/help.fdt cat ${.ALLSRC} | \ awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} -${PROG}: ldscript.generated ${.CURDIR}/ldscript.${MACHINE_CPUARCH} - -ldscript.generated:: - rm -f ldscript.generated.tmp - echo "UBLDR_LOADADDR = ${UBLDR_LOADADDR};" >ldscript.generated.tmp - if diff ldscript.generated ldscript.generated.tmp > /dev/null; then \ - true; \ - else \ - rm -f ldscript.generated; \ - mv ldscript.generated.tmp ldscript.generated; \ - fi +ldscript.abs: + echo "UBLDR_LOADADDR = ${UBLDR_LOADADDR};" >${.TARGET} + +ldscript.pie: + echo "UBLDR_LOADADDR = 0;" >${.TARGET} + +ubldr: ${OBJS} ldscript.abs ${.CURDIR}/ldscript.${MACHINE_CPUARCH} ${DPADD} + ${CC} ${CFLAGS} -T ldscript.abs ${LDFLAGS} \ + -o ${.TARGET} ${OBJS} ${LDADD} + +ubldr.pie: ${OBJS} ldscript.pie ${.CURDIR}/ldscript.${MACHINE_CPUARCH} ${DPADD} + ${CC} ${CFLAGS} -T ldscript.pie ${LDFLAGS} -pie -Wl,-Bsymbolic \ + -o ${.TARGET} ${OBJS} ${LDADD} + +ubldr.bin: ubldr.pie + ${OBJCOPY} -S -O binary ubldr.pie ${.TARGET} + +CLEANFILES+= ldscript.abs ldscript.pie ubldr ubldr.pie ubldr.bin .if !defined(LOADER_ONLY) .PATH: ${.CURDIR}/../../forth diff --git a/sys/boot/arm/uboot/ldscript.arm b/sys/boot/arm/uboot/ldscript.arm index b3be119..1eb10a8 100644 --- a/sys/boot/arm/uboot/ldscript.arm +++ b/sys/boot/arm/uboot/ldscript.arm @@ -6,6 +6,15 @@ SECTIONS { /* Read-only sections, merged into text segment: */ . = UBLDR_LOADADDR + SIZEOF_HEADERS; + .text : + { + *(.text) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =0 + _etext = .; + PROVIDE (etext = .); .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } @@ -32,15 +41,6 @@ SECTIONS .rela.sbss : { *(.rela.sbss) } .rela.sdata2 : { *(.rela.sdata2) } .rela.sbss2 : { *(.rela.sbss2) } - .text : - { - *(.text) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.gnu.linkonce.t*) - } =0 - _etext = .; - PROVIDE (etext = .); .init : { *(.init) } =0 .fini : { *(.fini) } =0 .rodata : { *(.rodata) *(.gnu.linkonce.r*) } diff --git a/sys/boot/arm/uboot/start.S b/sys/boot/arm/uboot/start.S index 6e8f117..1ef21f3 100644 --- a/sys/boot/arm/uboot/start.S +++ b/sys/boot/arm/uboot/start.S @@ -29,12 +29,38 @@ #include <machine/asm.h> #include <machine/armreg.h> + .text + .extern _C_LABEL(self_reloc), _C_LABEL(main) + .weak _DYNAMIC + /* * Entry point to the loader that U-Boot passes control to. */ - .text .globl _start _start: + +#ifdef _ARM_ARCH_6 + mrc p15, 0, ip, c1, c0, 0 + orr ip, ip, #(CPU_CONTROL_UNAL_ENABLE) + orr ip, ip, #(CPU_CONTROL_AFLT_ENABLE) + mcr p15, 0, ip, c1, c0, 0 +#endif + /* + * Do self-relocation when the weak external symbol _DYNAMIC is non-NULL. + * When linked as a dynamic relocatable file, the linker automatically + * defines _DYNAMIC with a value that is the offset of the dynamic + * relocation info section. + * Note that we're still on u-boot's stack here, but the self_reloc + * code uses only a couple dozen bytes of stack space. + */ + adr ip, .here_off /* .here_off is a symbol whose value */ + ldr r0, [ip] /* is its own offset in the text seg. */ + sub r0, ip, r0 /* Get its pc-relative address and */ + ldr r1, .dynamic_off /* subtract its value and we get */ + teq r1, #0 /* r0 = physaddr we were loaded at. */ + addne r1, r1, r0 /* r1 = dynamic section physaddr. */ + blne _C_LABEL(self_reloc) /* Do reloc if _DYNAMIC is non-NULL. */ + /* Hint where to look for the API signature */ ldr ip, =uboot_address str sp, [ip] @@ -44,16 +70,20 @@ _start: str r8, [ip, #0] str r9, [ip, #4] -#ifdef _ARM_ARCH_6 - mrc p15, 0, r2, c1, c0, 0 - orr r2, r2, #(CPU_CONTROL_UNAL_ENABLE) - orr r2, r2, #(CPU_CONTROL_AFLT_ENABLE) - mcr p15, 0, r2, c1, c0, 0 -#endif - - /* Start loader */ + /* + * Start loader. This is basically a tail-recursion call; if main() + * returns, it returns to u-boot (which reports the value returned r0). + */ b main + /* + * Data for self-relocation, in the text segment for pc-rel access. + */ +.here_off: + .word . +.dynamic_off: + .word _DYNAMIC + /* * syscall() */ |