svn commit: r282731 - head/sys/boot/arm/uboot
Ian Lepore
ian at FreeBSD.org
Sun May 10 19:14:29 UTC 2015
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()
*/
More information about the svn-src-all
mailing list