Date: Sun, 10 May 2015 19:14:28 +0000 (UTC) From: Ian Lepore <ian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r282731 - head/sys/boot/arm/uboot Message-ID: <201505101914.t4AJESCC006158@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ian Date: Sun May 10 19:14:28 2015 New Revision: 282731 URL: https://svnweb.freebsd.org/changeset/base/282731 Log: Create a relocatable instance of ubldr for ARM. The original ubldr, static-linked to run at a fixed position, is still installed to maintain compatibility with existing configurations. The makefile now also creates and installs ubldr.bin, a stripped binary (no elf headers) with an entry point offset of 0 that can be loaded by u-boot at any address and launched with "go ${loadaddr}". To use ubldr.bin, U-Boot must still be built with the CONFIG_API option, but no longer needs the CONFIG_ELF option. Modified: head/sys/boot/arm/uboot/Makefile head/sys/boot/arm/uboot/start.S Modified: head/sys/boot/arm/uboot/Makefile ============================================================================== --- head/sys/boot/arm/uboot/Makefile Sun May 10 17:11:04 2015 (r282730) +++ head/sys/boot/arm/uboot/Makefile Sun May 10 19:14:28 2015 (r282731) @@ -2,7 +2,8 @@ .include <src.opts.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 ${.C cat ${.ALLSRC} | \ awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET} -${PROG}: ldscript.generated ${.CURDIR}/ldscript.${MACHINE_CPUARCH} +ldscript.abs: + echo "UBLDR_LOADADDR = ${UBLDR_LOADADDR};" >${.TARGET} + +ldscript.pie: + echo "UBLDR_LOADADDR = 0;" >${.TARGET} + +ubldr: ${OBJS} ldscript.abs ${.CURDIR}/ldscript.${MACHINE_CPUARCH} + ${CC} ${CFLAGS} -T ldscript.abs ${LDFLAGS} \ + -o ${.TARGET} ${OBJS} ${LDADD} + +ubldr.pie: ${OBJS} ldscript.pie ${.CURDIR}/ldscript.${MACHINE_CPUARCH} + ${CC} ${CFLAGS} -T ldscript.pie ${LDFLAGS} -pie -Wl,-Bsymbolic \ + -o ${.TARGET} ${OBJS} ${LDADD} + +ubldr.bin: ubldr.pie + ${OBJCOPY} -S -O binary ubldr.pie ${.TARGET} -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 +CLEANFILES+= ldscript.abs ldscript.pie ubldr ubldr.pie ubldr.bin .if !defined(LOADER_ONLY) .PATH: ${.CURDIR}/../../forth Modified: head/sys/boot/arm/uboot/start.S ============================================================================== --- head/sys/boot/arm/uboot/start.S Sun May 10 17:11:04 2015 (r282730) +++ head/sys/boot/arm/uboot/start.S Sun May 10 19:14:28 2015 (r282731) @@ -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() */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505101914.t4AJESCC006158>