[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