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:
parent
cf94a1d327
commit
07da022233
@ -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
|
||||
|
@ -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()
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user