
This change adds an upper bound for symbols which are fixed up after u-boot is relocated into RAM. This way portions that are left at their original location can be referred to without having to manually fix up any pointers.
Signed-off-by: Gabe Black gabeblack@chromium.org --- Changes in v2: Merge in a fix in a later patch which gets rid of some unintentional pointer arithmetic.
Changes in v3: Update x86 tag.
arch/x86/lib/bios_setup.c | 7 ++----- arch/x86/lib/board.c | 15 ++++++++++++--- arch/x86/lib/realmode.c | 7 ++----- 3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/arch/x86/lib/bios_setup.c b/arch/x86/lib/bios_setup.c index 6c6b0fe..8112f33 100644 --- a/arch/x86/lib/bios_setup.c +++ b/arch/x86/lib/bios_setup.c @@ -140,11 +140,8 @@ static void setvector(int vector, u16 segment, void *handler)
int bios_setup(void) { - /* - * The BIOS section is not relocated and still in the ROM. The - * __bios_start symbol was adjusted, though, so adjust it back. - */ - ulong bios_start = (ulong)&__bios_start - gd->reloc_off; + /* The BIOS section is not relocated and still in the ROM. */ + ulong bios_start = (ulong)&__bios_start; ulong bios_size = (ulong)&__bios_size;
static int done=0; diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c index 8963580..cf20703 100644 --- a/arch/x86/lib/board.c +++ b/arch/x86/lib/board.c @@ -227,10 +227,19 @@ static int do_elf_reloc_fixups(void) Elf32_Rel *re_src = (Elf32_Rel *)(&__rel_dyn_start); Elf32_Rel *re_end = (Elf32_Rel *)(&__rel_dyn_end);
+ /* The size of the region of u-boot that runs out of RAM. */ + uintptr_t size = (uintptr_t)&__bss_end - + (uintptr_t)&__text_start; + do { - if (re_src->r_offset >= CONFIG_SYS_TEXT_BASE) - if (*(Elf32_Addr *)(re_src->r_offset + gd->reloc_off) >= CONFIG_SYS_TEXT_BASE) - *(Elf32_Addr *)(re_src->r_offset + gd->reloc_off) += gd->reloc_off; + if (re_src->r_offset >= CONFIG_SYS_TEXT_BASE) { + Elf32_Addr *addr = (Elf32_Addr *) + (re_src->r_offset + gd->reloc_off); + if (*addr >= CONFIG_SYS_TEXT_BASE && + *addr < (CONFIG_SYS_TEXT_BASE + size)) { + *addr += gd->reloc_off; + } + } } while (re_src++ < re_end);
return 0; diff --git a/arch/x86/lib/realmode.c b/arch/x86/lib/realmode.c index f8f2251..7637e2c 100644 --- a/arch/x86/lib/realmode.c +++ b/arch/x86/lib/realmode.c @@ -34,11 +34,8 @@ extern char realmode_enter;
int realmode_setup(void) { - /* - * The realmode section is not relocated and still in the ROM. The - * __realmode_start symbol was adjusted, though, so adjust it back. - */ - ulong realmode_start = (ulong)&__realmode_start - gd->reloc_off; + /* The realmode section is not relocated and still in the ROM. */ + ulong realmode_start = (ulong)&__realmode_start; ulong realmode_size = (ulong)&__realmode_size;
/* copy the realmode switch code */