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.
This commit is contained in:
ian 2015-05-10 19:14:28 +00:00
parent cf94a1d327
commit 07da022233
2 changed files with 62 additions and 24 deletions

View File

@ -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 ${.CURDIR}/../../fdt/help.fdt
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.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.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}
CLEANFILES+= ldscript.abs ldscript.pie ubldr ubldr.pie ubldr.bin
.if !defined(LOADER_ONLY)
.PATH: ${.CURDIR}/../../forth

View File

@ -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()
*/