[U-Boot] [RFC PATCH 3/7] reboard: Add generic relocation feature
Simon Glass
sjg at chromium.org
Tue Nov 22 00:57:56 CET 2011
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 <sjg at 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, wd at 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
More information about the U-Boot
mailing list