Add a relocation implementation as the first thing in the generic board library. This library is needed by SPL also.
Signed-off-by: Simon Glass <s...@chromium.org> --- Makefile | 1 + board/Makefile | 45 ++++++++++++++++++++++++ board/reloc.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/common.h | 2 +- include/reloc.h | 37 ++++++++++++++++++++ spl/Makefile | 1 + 6 files changed, 186 insertions(+), 1 deletions(-) create mode 100644 board/Makefile create mode 100644 board/reloc.c create mode 100644 include/reloc.h diff --git a/Makefile b/Makefile index fb658f4..d313481 100644 --- a/Makefile +++ b/Makefile @@ -221,6 +221,7 @@ LIBS = lib/libgeneric.o LIBS += lib/lzma/liblzma.o LIBS += lib/lzo/liblzo.o LIBS += lib/zlib/libz.o +LIBS += board/libboard.o LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \ "board/$(VENDOR)/common/lib$(VENDOR).o"; fi) LIBS += $(CPUDIR)/lib$(CPU).o diff --git a/board/Makefile b/board/Makefile new file mode 100644 index 0000000..e7f8b17 --- /dev/null +++ b/board/Makefile @@ -0,0 +1,45 @@ +# +# (C) Copyright 2002-2006 +# Wolfgang Denk, DENX Software Engineering, w...@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)libboard.o + +ifndef CONFIG_SYS_LEGACY_BOARD +COBJS += reloc.o +endif + +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/reloc.c b/board/reloc.c new file mode 100644 index 0000000..abd9c0b --- /dev/null +++ b/board/reloc.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm-generic/link_symbols.h> +#include <reloc.h> +#include <nand.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int reloc_make_copy(void) +{ + ulong *dst_addr = (ulong *)gd->relocaddr; + + /* TODO: __text_start would be better when we have it */ + ulong *src_addr = (ulong *)_start; + /* TODO: switch over to __image_copy_end when we can */ +#ifdef CONFIG_SPL_BUILD + ulong *end_addr = (ulong *)&__image_copy_end; +#else + ulong *end_addr = (ulong *)&__rel_dyn_start; +#endif + + if (dst_addr != src_addr) { + while (src_addr < end_addr) + *dst_addr++ = *src_addr++; + } + return 0; +} + +static int reloc_clear_bss(void) +{ + ulong *dst_addr = (ulong *)&__bss_start; + + /* TODO: change to __bss_end */ + ulong *end_addr = (ulong *)&__bss_end__; + +#ifndef CONFIG_SPL_BUILD + /* No relocation for SPL */ + dst_addr += gd->reloc_off / sizeof(ulong); + end_addr += gd->reloc_off / sizeof(ulong); +#endif + + while (dst_addr < end_addr) + *dst_addr++ = 0; + + return 0; +} + +static int reloc_elf(void) +{ +#ifndef CONFIG_SPL_BUILD + const Elf32_Rel *ptr; + Elf32_Addr *addr; + + /* scan the relocation table for relevant entries */ + for (ptr = __rel_dyn_start; ptr < __rel_dyn_end; ptr++) { + /* CONFIG_TEXT_BASE on x86 */ + if (ptr->r_offset < CONFIG_SYS_TEXT_BASE) + continue; + + addr = (Elf32_Addr *)(ptr->r_offset + gd->reloc_off); + if (arch_elf_relocate_entry(addr, ptr->r_info, __dynsym_start, + gd->reloc_off)) + return -1; + } +#endif + return 0; +} + +void relocate_code(ulong dest_addr_sp, gd_t *new_gd, ulong dest_addr) +{ + reloc_make_copy(); + reloc_elf(); + reloc_clear_bss(); + /* TODO: tidy this up */ +#ifdef CONFIG_NAND_SPL + nand_boot(); +#else + proc_call_board_init_r(new_gd, dest_addr, board_init_r, dest_addr_sp); +#endif +} diff --git a/include/common.h b/include/common.h index 5ca8820..223bf52 100644 --- a/include/common.h +++ b/include/common.h @@ -469,7 +469,7 @@ int dcache_status (void); void dcache_enable (void); void dcache_disable(void); void mmu_disable(void); -void relocate_code (ulong, gd_t *, ulong) __attribute__ ((noreturn)); +#include <reloc.h> ulong get_endaddr (void); void trap_init (ulong); #if defined (CONFIG_4xx) || \ diff --git a/include/reloc.h b/include/reloc.h new file mode 100644 index 0000000..7a4f7aa --- /dev/null +++ b/include/reloc.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __RELOC_H +#define __RELOC_H + +#include <elf.h> + +void proc_call_board_init_r(gd_t *new_gd, ulong dest_addr, + void (*board_init_r_func)(gd_t *, ulong), ulong dest_addr_sp) + __attribute__ ((noreturn)); + +int arch_elf_relocate_entry(Elf32_Addr *addr, Elf32_Word info, + Elf32_Sym *symtab, ulong reloc_off); + +void relocate_code(ulong dest_sp, gd_t *new_gd, ulong dest_addr) + __attribute__ ((noreturn)); +#endif diff --git a/spl/Makefile b/spl/Makefile index 6ac42a2..103f773 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -39,6 +39,7 @@ LIBS-y += $(CPUDIR)/lib$(CPU).o ifdef SOC LIBS-y += $(CPUDIR)/$(SOC)/lib$(SOC).o endif +LIBS-y += board/libboard.o LIBS-y += board/$(BOARDDIR)/lib$(BOARD).o LIBS-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/lib$(VENDOR).o -- 1.7.3.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot