All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 12/26] ARM: add relocation support
@ 2010-08-11 18:16 Heiko Schocher
  2010-09-15 21:06 ` Albert ARIBAUD
  0 siblings, 1 reply; 25+ messages in thread
From: Heiko Schocher @ 2010-08-11 18:16 UTC (permalink / raw)
  To: u-boot

!! This breaks support for all arm boards !!

To compile in old style, you must define
CONFIG_SYS_ARM_WITHOUT_RELOC or you can compile
with "CONFIG_SYS_ARM_WITHOUT_RELOC=1 ./MAKEALL board"

!! This define will be removed soon, so convert your
board to use relocation support

Signed-off-by: Heiko Schocher <hs@denx.de>
---
- changes since previous patch set
  - as introducing CONFIG_SYS_ARM_WITHOUT_RELOC, seperate
    common arm changes in this patch

 arch/arm/config.mk                 |    8 +
 arch/arm/include/asm/config.h      |    3 +-
 arch/arm/include/asm/global_data.h |   11 +
 arch/arm/include/asm/u-boot-arm.h  |   14 +-
 arch/arm/lib/board.c               |  468 +++++++++++++++++++++++++++++++++++-
 arch/arm/lib/cache-cp15.c          |   37 +++-
 arch/arm/lib/interrupts.c          |   19 ++-
 common/cmd_bdinfo.c                |   11 +-
 common/cmd_bmp.c                   |    6 +
 common/cmd_i2c.c                   |    6 +
 doc/README.arm-relocation          |  321 ++++++++++++++++++++++++
 nand_spl/nand_boot.c               |    7 +
 nand_spl/nand_boot_fsl_nfc.c       |    7 +
 13 files changed, 910 insertions(+), 8 deletions(-)
 create mode 100644 doc/README.arm-relocation

diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index e10dafc..6923f6d 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -33,6 +33,14 @@ STANDALONE_LOAD_ADDR = 0xc100000
 endif
 endif

+ifndef CONFIG_SYS_ARM_WITHOUT_RELOC
+# needed for relocation
+PLATFORM_RELFLAGS += -fPIC
+endif
+
+ifdef CONFIG_SYS_ARM_WITHOUT_RELOC
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_ARM_WITHOUT_RELOC
+endif
 PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__

 # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h
index b76fd8e..4e8dfd7 100644
--- a/arch/arm/include/asm/config.h
+++ b/arch/arm/include/asm/config.h
@@ -21,7 +21,8 @@
 #ifndef _ASM_CONFIG_H_
 #define _ASM_CONFIG_H_

+#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
 /* Relocation to SDRAM works on all ARM boards */
 #define CONFIG_RELOC_FIXUP_WORKS
-
+#endif
 #endif
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index 02cfe45..488bae7 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -53,6 +53,17 @@ typedef	struct	global_data {
 	phys_size_t	ram_size;	/* RAM size */
 	unsigned long	reset_status;	/* reset status register at boot */
 #endif
+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+	unsigned long	relocaddr;	/* Start address of U-Boot in RAM */
+	phys_size_t	ram_size;	/* RAM size */
+	unsigned long	mon_len;	/* monitor len */
+	unsigned long	irq_sp;		/* irq stack pointer */
+	unsigned long	start_addr_sp;	/* start_addr_stackpointer */
+	unsigned long	reloc_off;
+#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE))
+	unsigned long	tlb_addr;
+#endif
+#endif
 	void		**jt;		/* jump table */
 } gd_t;

diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h
index 6d2f8bc..faf800a 100644
--- a/arch/arm/include/asm/u-boot-arm.h
+++ b/arch/arm/include/asm/u-boot-arm.h
@@ -30,11 +30,20 @@
 #define _U_BOOT_ARM_H_	1

 /* for the following variables, see start.S */
-extern ulong _armboot_start;	/* code start */
 extern ulong _bss_start;	/* code + data end == BSS start */
 extern ulong _bss_end;		/* BSS end */
 extern ulong IRQ_STACK_START;	/* top of IRQ stack */
 extern ulong FIQ_STACK_START;	/* top of FIQ stack */
+#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+extern ulong _armboot_start;	/* code start */
+#else
+extern ulong _TEXT_BASE;	/* code start */
+extern ulong _datarel_start;
+extern ulong _datarelrolocal_start;
+extern ulong _datarellocal_start;
+extern ulong _datarelro_start;
+extern ulong IRQ_STACK_START_IN;	/* 8 bytes in IRQ stack */
+#endif

 /* cpu/.../cpu.c */
 int	cpu_init(void);
@@ -47,6 +56,9 @@ int	arch_misc_init(void);
 /* board/.../... */
 int	board_init(void);
 int	dram_init (void);
+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+void	dram_init_banksize (void);
+#endif
 void	setup_serial_tag (struct tag **params);
 void	setup_revision_tag (struct tag **params);

diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 54519b0..88c6427 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -126,7 +126,12 @@ static int init_baudrate (void)
 {
 	char tmp[64];	/* long enough for environment variables */
 	int i = getenv_f("baudrate", tmp, sizeof (tmp));
+
+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+	gd->baudrate = (i > 0)
+#else
 	gd->bd->bi_baudrate = gd->baudrate = (i > 0)
+#endif
 			? (int) simple_strtoul (tmp, NULL, 10)
 			: CONFIG_BAUDRATE;

@@ -137,7 +142,12 @@ static int display_banner (void)
 {
 	printf ("\n\n%s\n\n", version_string);
 	debug ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",
-	       _armboot_start, _bss_start, _bss_end);
+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+	       _TEXT_BASE,
+#else
+	       _armboot_start,
+#endif
+	       _bss_start, _bss_end);
 #ifdef CONFIG_MODEM_SUPPORT
 	debug ("Modem Support enabled\n");
 #endif
@@ -180,6 +190,7 @@ static int display_dram_config (void)
 	return (0);
 }

+#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
 #ifndef CONFIG_SYS_NO_FLASH
 static void display_flash_config (ulong size)
 {
@@ -187,6 +198,7 @@ static void display_flash_config (ulong size)
 	print_size (size, "\n");
 }
 #endif /* CONFIG_SYS_NO_FLASH */
+#endif

 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
 static int init_func_i2c (void)
@@ -234,6 +246,7 @@ typedef int (init_fnc_t) (void);

 int print_cpuinfo (void);

+#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
 init_fnc_t *init_sequence[] = {
 #if defined(CONFIG_ARCH_CPU_INIT)
 	arch_cpu_init,		/* basic arch cpu dependent setup */
@@ -444,6 +457,459 @@ extern void davinci_eth_set_mac_addr (const u_int8_t *addr);

 	/* NOTREACHED - no way out of command loop except booting */
 }
+#else
+void __dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+	gd->bd->bi_dram[0].size =  gd->ram_size;
+}
+void dram_init_banksize(void)
+	__attribute__((weak, alias("__dram_init_banksize")));
+
+init_fnc_t *init_sequence[] = {
+#if defined(CONFIG_ARCH_CPU_INIT)
+	arch_cpu_init,		/* basic arch cpu dependent setup */
+#endif
+#if defined(CONFIG_BOARD_EARLY_INIT_F)
+	board_early_init_f,
+#endif
+	timer_init,		/* initialize timer */
+#ifdef CONFIG_FSL_ESDHC
+	get_clocks,
+#endif
+	env_init,		/* initialize environment */
+	init_baudrate,		/* initialze baudrate settings */
+	serial_init,		/* serial communications setup */
+	console_init_f,		/* stage 1 init of console */
+	display_banner,		/* say that we are here */
+#if defined(CONFIG_DISPLAY_CPUINFO)
+	print_cpuinfo,		/* display cpu info (and speed) */
+#endif
+#if defined(CONFIG_DISPLAY_BOARDINFO)
+	checkboard,		/* display board info */
+#endif
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+	init_func_i2c,
+#endif
+	dram_init,		/* configure available RAM banks */
+#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
+	arm_pci_init,
+#endif
+	NULL,
+};
+
+void board_init_f (ulong bootflag)
+{
+	bd_t *bd;
+	init_fnc_t **init_fnc_ptr;
+	gd_t *id;
+	ulong addr, addr_sp;
+
+	/* Pointer is writable since we allocated a register for it */
+	gd = (gd_t *) (CONFIG_SYS_INIT_SP_ADDR);
+	/* compiler optimization barrier needed for GCC >= 3.4 */
+	__asm__ __volatile__("": : :"memory");
+
+	memset ((void*)gd, 0, sizeof (gd_t));
+
+	gd->mon_len = _bss_end - _TEXT_BASE;
+
+	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+		if ((*init_fnc_ptr)() != 0) {
+			hang ();
+		}
+	}
+
+	debug ("monitor len: %08lX\n", gd->mon_len);
+	/*
+	 * Ram is setup, size stored in gd !!
+	 */
+	debug ("ramsize: %08lX\n", gd->ram_size);
+#if defined(CONFIG_SYS_MEM_TOP_HIDE)
+	/*
+	 * Subtract specified amount of memory to hide so that it won't
+	 * get "touched" at all by U-Boot. By fixing up gd->ram_size
+	 * the Linux kernel should now get passed the now "corrected"
+	 * memory size and won't touch it either. This should work
+	 * for arch/ppc and arch/powerpc. Only Linux board ports in
+	 * arch/powerpc with bootwrapper support, that recalculate the
+	 * memory size from the SDRAM controller setup will have to
+	 * get fixed.
+	 */
+	gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
+#endif
+
+	addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
+
+#ifdef CONFIG_LOGBUFFER
+#ifndef CONFIG_ALT_LB_ADDR
+	/* reserve kernel log buffer */
+	addr -= (LOGBUFF_RESERVE);
+	debug ("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, addr);
+#endif
+#endif
+
+#ifdef CONFIG_PRAM
+	/*
+	 * reserve protected RAM
+	 */
+	i = getenv_r ("pram", (char *)tmp, sizeof (tmp));
+	reg = (i > 0) ? simple_strtoul ((const char *)tmp, NULL, 10) : CONFIG_PRAM;
+	addr -= (reg << 10);		/* size is in kB */
+	debug ("Reserving %ldk for protected RAM@%08lx\n", reg, addr);
+#endif /* CONFIG_PRAM */
+
+#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE))
+	/* reserve TLB table */
+	addr -= (4096 * 4);
+
+	/* round down to next 64 kB limit */
+	addr &= ~(0x10000 - 1);
+
+	gd->tlb_addr = addr;
+	debug ("TLB table at: %08lx\n", addr);
+#endif
+
+	/* round down to next 4 kB limit */
+	addr &= ~(4096 - 1);
+	debug ("Top of RAM usable for U-Boot at: %08lx\n", addr);
+
+#ifdef CONFIG_VFD
+#	ifndef PAGE_SIZE
+#	  define PAGE_SIZE 4096
+#	endif
+	/*
+	 * reserve memory for VFD display (always full pages)
+	 */
+	addr -= vfd_setmem (addr);
+	gd->fb_base = addr;
+#endif /* CONFIG_VFD */
+
+#ifdef CONFIG_LCD
+	/* reserve memory for LCD display (always full pages) */
+	addr = lcd_setmem (addr);
+	gd->fb_base = addr;
+#endif /* CONFIG_LCD */
+
+	/*
+	 * reserve memory for U-Boot code, data & bss
+	 * round down to next 4 kB limit
+	 */
+	addr -= gd->mon_len;
+	addr &= ~(4096 - 1);
+
+	debug ("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr);
+
+#ifndef CONFIG_PRELOADER
+	/*
+	 * reserve memory for malloc() arena
+	 */
+	addr_sp = addr - TOTAL_MALLOC_LEN;
+	debug ("Reserving %dk for malloc() at: %08lx\n",
+			TOTAL_MALLOC_LEN >> 10, addr_sp);
+	/*
+	 * (permanently) allocate a Board Info struct
+	 * and a permanent copy of the "global" data
+	 */
+	addr_sp -= sizeof (bd_t);
+	bd = (bd_t *) addr_sp;
+	gd->bd = bd;
+	debug ("Reserving %zu Bytes for Board Info at: %08lx\n",
+			sizeof (bd_t), addr_sp);
+	addr_sp -= sizeof (gd_t);
+	id = (gd_t *) addr_sp;
+	debug ("Reserving %zu Bytes for Global Data at: %08lx\n",
+			sizeof (gd_t), addr_sp);
+
+	/* setup stackpointer for exeptions */
+	gd->irq_sp = addr_sp;
+#ifdef CONFIG_USE_IRQ
+	addr_sp -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);
+	debug ("Reserving %zu Bytes for IRQ stack at: %08lx\n",
+		CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp);
+#endif
+	/* leave 3 words for abort-stack    */
+	addr_sp -= 3;
+
+	/* 8-byte alignment for ABI compliance */
+	addr_sp &= ~0x07;
+#else
+	addr_sp += 128;	/* leave 32 words for abort-stack   */
+	gd->irq_sp = addr_sp;
+#endif
+
+	debug ("New Stack Pointer is: %08lx\n", addr_sp);
+
+#ifdef CONFIG_POST
+	post_bootmode_init();
+	post_run (NULL, POST_ROM | post_bootmode_get(0));
+#endif
+
+	gd->bd->bi_baudrate = gd->baudrate;
+	/* Ram ist board specific, so move it to board code ... */
+	dram_init_banksize();
+	display_dram_config();	/* and display it */
+
+	gd->relocaddr = addr;
+	gd->start_addr_sp = addr_sp;
+	gd->reloc_off = addr - _TEXT_BASE;
+	debug ("relocation Offset is: %08lx\n", gd->reloc_off);
+	memcpy (id, (void *)gd, sizeof (gd_t));
+
+	relocate_code (addr_sp, id, addr);
+
+	/* NOTREACHED - relocate_code() does not return */
+}
+
+#if !defined(CONFIG_SYS_NO_FLASH)
+static char *failed = "*** failed ***\n";
+#endif
+
+/************************************************************************
+ *
+ * This is the next part if the initialization sequence: we are now
+ * running from RAM and have a "normal" C environment, i. e. global
+ * data can be written, BSS has been cleared, the stack size in not
+ * that critical any more, etc.
+ *
+ ************************************************************************
+ */
+void board_init_r (gd_t *id, ulong dest_addr)
+{
+	char *s;
+	bd_t *bd;
+	ulong malloc_start;
+#if !defined(CONFIG_SYS_NO_FLASH)
+	ulong flash_size;
+#endif
+#if !defined(CONFIG_RELOC_FIXUP_WORKS)
+	extern void malloc_bin_reloc (void);
+#if defined(CONFIG_CMD_BMP)
+	extern void bmp_reloc(void);
+#endif
+#if defined(CONFIG_CMD_I2C)
+	extern void i2c_reloc(void);
+#endif
+#endif
+
+	gd = id;
+	bd = gd->bd;
+
+	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
+
+	monitor_flash_len = _bss_start - _TEXT_BASE;
+	debug ("monitor flash len: %08lX\n", monitor_flash_len);
+	board_init();	/* Setup chipselects */
+
+#ifdef CONFIG_SERIAL_MULTI
+	serial_initialize();
+#endif
+
+	debug ("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
+
+#if !defined(CONFIG_RELOC_FIXUP_WORKS)
+	/*
+	 * We have to relocate the command table manually
+	 */
+	fixup_cmdtable(&__u_boot_cmd_start,
+		(ulong)(&__u_boot_cmd_end - &__u_boot_cmd_start));
+#if defined(CONFIG_CMD_BMP)
+	bmp_reloc();
+#endif
+#if defined(CONFIG_CMD_I2C)
+	i2c_reloc();
+#endif
+#endif /* !defined(CONFIG_RELOC_FIXUP_WORKS) */
+
+#ifdef CONFIG_LOGBUFFER
+	logbuff_init_ptrs ();
+#endif
+#ifdef CONFIG_POST
+	post_output_backlog ();
+#ifndef CONFIG_RELOC_FIXUP_WORKS
+	post_reloc ();
+#endif
+#endif
+
+	/* The Malloc area is immediately below the monitor copy in DRAM */
+	malloc_start = dest_addr - TOTAL_MALLOC_LEN;
+	mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN);
+#if !defined(CONFIG_RELOC_FIXUP_WORKS)
+	malloc_bin_reloc ();
+#endif
+
+#if !defined(CONFIG_SYS_NO_FLASH)
+	puts ("FLASH: ");
+
+	if ((flash_size = flash_init ()) > 0) {
+# ifdef CONFIG_SYS_FLASH_CHECKSUM
+		print_size (flash_size, "");
+		/*
+		 * Compute and print flash CRC if flashchecksum is set to 'y'
+		 *
+		 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
+		 */
+		s = getenv ("flashchecksum");
+		if (s && (*s == 'y')) {
+			printf ("  CRC: %08X",
+				crc32 (0, (const unsigned char *) CONFIG_SYS_FLASH_BASE, flash_size)
+			);
+		}
+		putc ('\n');
+# else	/* !CONFIG_SYS_FLASH_CHECKSUM */
+		print_size (flash_size, "\n");
+# endif /* CONFIG_SYS_FLASH_CHECKSUM */
+	} else {
+		puts (failed);
+		hang ();
+	}
+#endif
+
+#if defined(CONFIG_CMD_NAND)
+	puts ("NAND:  ");
+	nand_init();		/* go init the NAND */
+#endif
+
+#if defined(CONFIG_CMD_ONENAND)
+	onenand_init();
+#endif
+
+#ifdef CONFIG_HAS_DATAFLASH
+	AT91F_DataflashInit();
+	dataflash_print_info();
+#endif
+
+	/* initialize environment */
+	env_relocate ();
+
+#ifdef CONFIG_VFD
+	/* must do this after the framebuffer is allocated */
+	drv_vfd_init();
+#endif /* CONFIG_VFD */
+
+	/* IP Address */
+	gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
+
+	stdio_init ();	/* get the devices list going. */
+
+	jumptable_init ();
+
+#if defined(CONFIG_API)
+	/* Initialize API */
+	api_init ();
+#endif
+
+	console_init_r ();	/* fully init console as a device */
+
+#if defined(CONFIG_ARCH_MISC_INIT)
+	/* miscellaneous arch dependent initialisations */
+	arch_misc_init ();
+#endif
+#if defined(CONFIG_MISC_INIT_R)
+	/* miscellaneous platform dependent initialisations */
+	misc_init_r ();
+#endif
+
+	 /* set up exceptions */
+	interrupt_init ();
+	/* enable exceptions */
+	enable_interrupts ();
+
+	/* Perform network card initialisation if necessary */
+#ifdef CONFIG_DRIVER_TI_EMAC
+	/* XXX: this needs to be moved to board init */
+extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
+	if (getenv ("ethaddr")) {
+		uchar enetaddr[6];
+		eth_getenv_enetaddr("ethaddr", enetaddr);
+		davinci_eth_set_mac_addr(enetaddr);
+	}
+#endif
+
+#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
+	/* XXX: this needs to be moved to board init */
+	if (getenv ("ethaddr")) {
+		uchar enetaddr[6];
+		eth_getenv_enetaddr("ethaddr", enetaddr);
+		smc_set_mac_addr(enetaddr);
+	}
+#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */
+
+	/* Initialize from environment */
+	if ((s = getenv ("loadaddr")) != NULL) {
+		load_addr = simple_strtoul (s, NULL, 16);
+	}
+#if defined(CONFIG_CMD_NET)
+	if ((s = getenv ("bootfile")) != NULL) {
+		copy_filename (BootFile, s, sizeof (BootFile));
+	}
+#endif
+
+#ifdef BOARD_LATE_INIT
+	board_late_init ();
+#endif
+
+#ifdef CONFIG_GENERIC_MMC
+	puts ("MMC:   ");
+	mmc_initialize (gd->bd);
+#endif
+
+#ifdef CONFIG_BITBANGMII
+	bb_miiphy_init();
+#endif
+#if defined(CONFIG_CMD_NET)
+#if defined(CONFIG_NET_MULTI)
+	puts ("Net:   ");
+#endif
+	eth_initialize(gd->bd);
+#if defined(CONFIG_RESET_PHY_R)
+	debug ("Reset Ethernet PHY\n");
+	reset_phy();
+#endif
+#endif
+
+#ifdef CONFIG_POST
+	post_run (NULL, POST_RAM | post_bootmode_get(0));
+#endif
+
+#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
+	/*
+	 * Export available size of memory for Linux,
+	 * taking into account the protected RAM at top of memory
+	 */
+	{
+		ulong pram;
+		uchar memsz[32];
+#ifdef CONFIG_PRAM
+		char *s;
+
+		if ((s = getenv ("pram")) != NULL) {
+			pram = simple_strtoul (s, NULL, 10);
+		} else {
+			pram = CONFIG_PRAM;
+		}
+#else
+		pram=0;
+#endif
+#ifdef CONFIG_LOGBUFFER
+#ifndef CONFIG_ALT_LB_ADDR
+		/* Also take the logbuffer into account (pram is in kB) */
+		pram += (LOGBUFF_LEN+LOGBUFF_OVERHEAD)/1024;
+#endif
+#endif
+		sprintf ((char *)memsz, "%ldk", (bd->bi_memsize / 1024) - pram);
+		setenv ("mem", (char *)memsz);
+	}
+#endif
+
+	/* main_loop() can return to retry autoboot, if so just run it again. */
+	for (;;) {
+		main_loop ();
+	}
+
+	/* NOTREACHED - no way out of command loop except booting */
+}
+#endif /* defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */

 void hang (void)
 {
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index b2811f3..fe6d459 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -44,17 +44,44 @@ static void cp_delay (void)
 	asm volatile("" : : : "memory");
 }

-/* to activate the MMU we need to set up virtual memory: use 1M areas in bss */
+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+static inline void dram_bank_mmu_setup(int bank)
+{
+	u32 *page_table = (u32 *)gd->tlb_addr;
+	bd_t *bd = gd->bd;
+	int	i;
+
+	debug("%s: bank: %d\n", __func__, bank);
+	for (i = bd->bi_dram[bank].start >> 20;
+	     i < (bd->bi_dram[bank].start + bd->bi_dram[bank].size) >> 20;
+	     i++) {
+		page_table[i] = i << 20 | (3 << 10) | CACHE_SETUP;
+	}
+}
+#endif
+
+/* to activate the MMU we need to set up virtual memory: use 1M areas */
 static inline void mmu_setup(void)
 {
+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+	u32 *page_table = (u32 *)gd->tlb_addr;
+#else
 	static u32 __attribute__((aligned(16384))) page_table[4096];
 	bd_t *bd = gd->bd;
-	int i, j;
+	int j;
+#endif
+	int i;
 	u32 reg;

 	/* Set up an identity-mapping for all 4GB, rw for everyone */
 	for (i = 0; i < 4096; i++)
 		page_table[i] = i << 20 | (3 << 10) | 0x12;
+
+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		dram_bank_mmu_setup(i);
+	}
+#else
 	/* Then, enable cacheable and bufferable for RAM only */
 	for (j = 0; j < CONFIG_NR_DRAM_BANKS; j++) {
 		for (i = bd->bi_dram[j].start >> 20;
@@ -63,6 +90,7 @@ static inline void mmu_setup(void)
 			page_table[i] = i << 20 | (3 << 10) | CACHE_SETUP;
 		}
 	}
+#endif

 	/* Copy the page table address to cp15 */
 	asm volatile("mcr p15, 0, %0, c2, c0, 0"
@@ -74,7 +102,6 @@ static inline void mmu_setup(void)
 	reg = get_cr();	/* get control reg. */
 	cp_delay();
 	set_cr(reg | CR_M);
-
 }

 /* cache_bit must be either CR_I or CR_C */
@@ -96,6 +123,10 @@ static void cache_disable(uint32_t cache_bit)
 	uint32_t reg;

 	if (cache_bit == CR_C) {
+		/* if cache isn;t enabled no need to disable */
+		reg = get_cr();
+		if ((reg & CR_C) != CR_C)
+			return;
 		/* if disabling data cache, disable mmu too */
 		cache_bit |= CR_M;
 		flush_cache(0, ~0);
diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c
index 1f2b815..9a21e7b 100644
--- a/arch/arm/lib/interrupts.c
+++ b/arch/arm/lib/interrupts.c
@@ -38,15 +38,20 @@
 #include <common.h>
 #include <asm/proc-armv/ptrace.h>

-#ifdef CONFIG_USE_IRQ
 DECLARE_GLOBAL_DATA_PTR;

+#ifdef CONFIG_USE_IRQ
 int interrupt_init (void)
 {
 	/*
 	 * setup up stacks if necessary
 	 */
+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+	IRQ_STACK_START = gd->irq_sp - 4;
+	IRQ_STACK_START_IN = gd->irq_sp + 8;
+#else
 	IRQ_STACK_START = _armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4;
+#endif
 	FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;

 	return arch_interrupt_init();
@@ -81,6 +86,18 @@ int disable_interrupts (void)
 	return (old & 0x80) == 0;
 }
 #else
+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+int interrupt_init (void)
+{
+	/*
+	 * setup up stacks if necessary
+	 */
+	IRQ_STACK_START_IN = gd->irq_sp + 8;
+
+	return 0;
+}
+#endif
+
 void enable_interrupts (void)
 {
 	return;
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c
index cc81543..4c3040a 100644
--- a/common/cmd_bdinfo.c
+++ b/common/cmd_bdinfo.c
@@ -343,7 +343,16 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	printf ("ip_addr     = %pI4\n", &bd->bi_ip_addr);
 #endif
 	printf ("baudrate    = %d bps\n", bd->bi_baudrate);
-
+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE))
+	print_num ("TLB addr", gd->tlb_addr);
+#endif
+	print_num ("relocaddr", gd->relocaddr);
+	print_num ("reloc off", gd->reloc_off);
+	print_num ("irq_sp", gd->irq_sp);	/* irq stack pointer */
+	print_num ("sp start ", gd->start_addr_sp);
+	print_num ("FB base  ", gd->fb_base);
+#endif
 	return 0;
 }

diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
index d51cc55..6fa8a15 100644
--- a/common/cmd_bmp.c
+++ b/common/cmd_bmp.c
@@ -137,6 +137,12 @@ static cmd_tbl_t cmd_bmp_sub[] = {
 	U_BOOT_CMD_MKENT(display, 5, 0, do_bmp_display, "", ""),
 };

+#ifndef CONFIG_RELOC_FIXUP_WORKS
+void bmp_reloc(void) {
+	fixup_cmdtable(cmd_bmp_sub, ARRAY_SIZE(cmd_bmp_sub));
+}
+#endif
+
 /*
  * Subroutine:  do_bmp
  *
diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index 5e9135e..48de54b 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -1287,6 +1287,12 @@ static cmd_tbl_t cmd_i2c_sub[] = {
 	U_BOOT_CMD_MKENT(speed, 1, 1, do_i2c_bus_speed, "", ""),
 };

+#ifndef CONFIG_RELOC_FIXUP_WORKS
+void i2c_reloc(void) {
+	fixup_cmdtable(cmd_i2c_sub, ARRAY_SIZE(cmd_i2c_sub));
+}
+#endif
+
 static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
 	cmd_tbl_t *c;
diff --git a/doc/README.arm-relocation b/doc/README.arm-relocation
new file mode 100644
index 0000000..6be1a12
--- /dev/null
+++ b/doc/README.arm-relocation
@@ -0,0 +1,321 @@
+To make relocation on arm working, the following changes are done:
+
+Add new compilerflag:
+
+-fPIC
+
+	-> compiler generates position independent code
+
+changes in board code:
+
+- dram_init:
+  - bd pointer is now at this point not accessible, so only
+    detect the real dramsize, and store it in gd->ram_size.
+    best detected with get_ram_size();
+    ToDo: move there also the dram initialization on boards where
+          it is possible.
+  - setup the bd_t dram bank info in the new function
+    dram_init_banksize().
+
+- board.c code is adapted from ppc code
+
+- undef CONFIG_RELOC_FIXUP_WORKS
+
+  -> cmdtabl, and subcommand table must be handled from "hand"
+     collected in section "__datarellocal_start".
+
+  - How To fixup the sections:
+
+    __datarel_start, __datarelrolocal_start, __datarellocal_start and
+    __datarelro_start
+
+    automatically? Then it should be possible to define again
+    CONFIG_RELOC_FIXUP_WORKS
+
+- irq stack setup is now not longer on a fix position, instead it is
+  calculated in board_init_f, and stored in gd->irq_sp
+
+-------------------------------------------------------------------------------------
+
+To compile a board without relocation, define CONFIG_SYS_ARM_WITHOUT_RELOC
+This possibility will removed!! So please fix your board to compile without
+CONFIG_SYS_ARM_WITHOUT_RELOC defined!!!
+
+-------------------------------------------------------------------------------------
+
+ToDo:
+
+- fill in bd_t infos (check)
+- adapt all boards
+
+- maybe adapt TEXT_BASE (this must be checked from board maintainers)
+  This *must* be done for boards, which boot from NOR flash
+
+  on other boards if TEXT_BASE = relocation baseaddr, this saves
+  one copying from u-boot code.
+
+- new function dram_init_banksize() is actual board specific. Maybe
+  we make a weak default function in arch/arm/lib/board.c ?
+
+-------------------------------------------------------------------------------------
+
+Relocation with NAND_SPL (example for the tx25):
+
+- cpu copies the first page from NAND to 0xbb000000 (IMX_NFC_BASE)
+  and start with code execution on this address.
+
+- The First page contains u-boot code from u-boot:nand_spl/nand_boot_fsl_nfc.c
+  which inits the dram, cpu registers, reloacte itself to TEXT_BASE  and loads
+  the "real" u-boot to CONFIG_SYS_NAND_U_BOOT_DST and starts execution
+  @CONFIG_SYS_NAND_U_BOOT_START
+
+- This u-boot does no ram int, nor cpu register setup. Just looks
+  where it have to relocate and relocate itself to this address.
+  If relocate address = TEXT_BASE(not the same, as the TEXT_BASE
+  from the nand_spl code), no need to copy, just go on with bss clear
+  and jump to board_init_r.
+
+-------------------------------------------------------------------------------------
+
+Relocation:
+How to translate flash addresses in GOT to ram addresses.
+This is automagically done from code, but this example
+shows, how this magic code works ;-)
+(example on the qong board)
+
+Find a variable:
+
+a) search it in System.map
+(for example flash_info)
+
+a005b4c0 B BootpID
+a005b4c4 B BootpTry
+a005b4c8 b slave
+a005b4cc B flash_info
+^^^^^^^^
+a005c908 b saved_sector.4002
+a005c910 b cfi_mtd_info
+a005c9c0 b cfi_mtd_names
+a005c9d0 B mtd_table
+
+---------------------------------------
+
+b) create hexdump from u-boot code:
+
+hexdump -C u-boot > gnlmpfhex
+
+---------------------------------------
+
+c) search the variables address in the hexdump
+
+
+*
+0005fc80  00 00 00 00 00 00 00 00  2c 06 01 a0 18 cd 05 a0  |........,.......|
+0005fc90  9c d4 05 a0 bc b4 05 a0  1c 7f 05 a0 f0 05 01 a0  |................|
+0005fca0  08 5a 04 a0 1c ab 05 a0  ec a4 05 a0 98 c3 01 a0  |.Z..............|
+0005fcb0  a0 d6 05 a0 04 71 05 a0  c0 f9 00 a0 3c cd 05 a0  |.....q......<...|
+0005fcc0  cc b4 05 a0 f0 fa 00 a0  f0 d6 05 a0 10 86 05 a0  |................|
+          ^^^^^^^^^^^
+0005fcd0  a4 16 06 a0 dc 64 05 a0  18 86 05 a0 52 48 05 a0  |.....d......RH..|
+0005fce0  c0 86 05 a0 24 6e 02 a0  b4 6c 05 a0 b0 94 01 a0  |....$n...l......|
+0005fcf0  1c 86 05 a0 50 85 05 a0  d4 0c 06 a0 bc 0b 06 a0  |....P...........|
+
+
+-> 0005fcc0
+
+----------------------------------------
+
+d) know we calculate this address in RAM
+
+
+  8ff08000	(new address of code in RAM *1)
+
++ 0005fcc0
+
+- 00008000	(offset of text *2)
+
+----------
+
+  8ff5fcc0	-> Addr GOT in RAM
+
+*1:
+activate debug and look for the line:
+Now running in RAM - U-Boot at: 8ff08000
+                                ^^^^^^^^
+                                new address of u-boot code in RAM
+
+*2:
+Section Headers:
+  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
+  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
+  [ 1] .text             PROGBITS        a0000000 008000 04599c 00  AX  0   0 32
+                                                  ^^^^^^
+                                                  Offset of text
+
+----------------------------------------
+
+e) now we look in 8ff5fcc0 (RAM)
+
+
+QongEVB>md 0x8ff5fcc0
+8ff5fcc0 : a005b4cc a000faf0 a005d6f0 a0058610  ................
+           ^^^^^^^^
+           Bingo, here we have the old flash address (when relocation
+           is working, here is the fixed ram address. see @ f, how
+           it gets calculated)
+
+
+----------------------------------------
+
+f) now translate it in the new RAM address
+
+  a005b4cc
+
+- a0000000     TextBase
+
++ 8ff08000     new address of u-boot in ram
+----------
+  8ff634cc
+
+QongEVB>mm 0x8ff5fcc0 0x8ff634cc 1
+QongEVB>md 0x8ff5fcc0
+8ff5fcc0 : 8ff634cc a000faf0 a005d6f0 a0058610  .4..............
+8ff5fcd0 : a00616a4 a00564dc a0058618 a0054852  .....d......RH..
+
+As this must be done for all address in the GOT, the u-boot
+code did this automagically ... :-)
+
+----------------------------------------------
+
+g) check if the new address is really in the bss section:
+
+bss start:
+8ff6054c	(8ff08000 + 0005854C monitorlen)
+
+bss end:
+8ff698ac	(8ff08000 + 618AC)
+
+8ff634cc is in bss :-)
+
+----------------------------------------------
+
+h) u-boot prints:
+
+important  addresses:
+
+U-Boot code: A0000000 -> A005854C  BSS: -> A00618AC	TextBase 0xa0000000
+Now running in RAM - U-Boot at: 8ff08000		relocBase 0x8ff08000
+
+
+---------
+
+U-Boot 2010.06-rc2-00002-gf8fbb25-dirty (Jun 18 2010 - 17:07:19)
+
+U-Boot code: A0000000 -> A005854C  BSS: -> A00618AC
+CPU:   Freescale i.MX31 at 398 MHz
+Board: DAVE/DENX Qong
+mon: FFFFFFFF gd->monLen: 000618AC
+Top of RAM usable for U-Boot at: 90000000
+LCD panel info: 640 x 480, 16 bit/pix
+Reserving 600k for LCD Framebuffer at: 8ff6a000
+Reserving 390k for U-Boot at: 8ff08000
+Reserving 1280k for malloc() at: 8fdc8000
+Reserving 28 Bytes for Board Info at: 8fdc7fe4
+Reserving 48 Bytes for Global Data at: 8fdc7fb4
+New Stack Pointer is: 8fdc7fb0
+RAM Configuration:
+Bank #0: 80000000 256 MiB
+mon: 0005854C gd->monLen: 000618AC
+Now running in RAM - U-Boot at: 8ff08000
+
+-------------------------------------------------------------------------------------
+
+Debugging u-boot in RAM:
+(example on the qong board)
+
+a) add in config.mk:
+
+PLATFORM_CPPFLAGS += -DDEBUG
+
+-----------------
+
+b) start debugger
+
+arm-linux-gdb u-boot
+
+[hs at pollux u-boot]$ arm-linux-gdb u-boot
+GNU gdb Red Hat Linux (6.7-2rh)
+Copyright (C) 2007 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
+and "show warranty" for details.
+This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-linux".
+The target architecture is set automatically (currently arm)
+..
+(gdb)
+
+-----------------
+
+c) connect to target
+
+target remote bdi10:2001
+
+(gdb) target remote bdi10:2001
+Remote debugging using bdi10:2001
+0x8ff17f10 in ?? ()
+(gdb)
+
+-----------------
+
+d) discard symbol-file
+
+(gdb) symbol-file
+Discard symbol table from `/home/hs/celf/u-boot/u-boot'? (y or n) y
+No symbol file now.
+(gdb)
+
+-----------------
+
+e) load new symbol table:
+
+(gdb) add-symbol-file u-boot 0x8ff08000
+add symbol table from file "u-boot" at
+        .text_addr = 0x8ff08000
+(y or n) y
+Reading symbols from /home/hs/celf/u-boot/u-boot...done.
+(gdb) c
+Continuing.
+^C
+Program received signal SIGSTOP, Stopped (signal).
+0x8ff17f18 in serial_getc () at serial_mxc.c:192
+192             while (__REG(UART_PHYS + UTS) & UTS_RXEMPTY);
+(gdb)
+
+add-symbol-file u-boot 0x8ff08000
+                       ^^^^^^^^^^
+                       get this address from u-boot debug printfs
+
+U-Boot 2010.06-rc2-00009-gf77b8b8-dirty (Jun 22 2010 - 09:43:46)
+
+U-Boot code: A0000000 -> A0058BAC  BSS: -> A0061F10
+CPU:   Freescale i.MX31 at 398 MHz
+Board: DAVE/DENX Qong
+mon: FFFFFFFF gd->monLen: 00061F10
+Top of RAM usable for U-Boot at: 90000000
+LCD panel info: 640 x 480, 16 bit/pix
+Reserving 600k for LCD Framebuffer at: 8ff6a000
+Reserving 391k for U-Boot at: 8ff08000
+                              ^^^^^^^^
+Reserving 1280k for malloc() at: 8fdc8000
+Reserving 24 Bytes for Board Info at: 8fdc7fe8
+Reserving 52 Bytes for Global Data at: 8fdc7fb4
+New Stack Pointer is: 8fdc7fb0
+RAM Configuration:
+Bank #0: 80000000 256 MiB
+relocation Offset is: eff08000
+mon: 00058BAC gd->monLen: 00061F10
+Now running in RAM - U-Boot at: 8ff08000
+                                ^^^^^^^^
+
+Now you can use gdb as usual :-)
diff --git a/nand_spl/nand_boot.c b/nand_spl/nand_boot.c
index b9fd6f5..18ecbe1 100644
--- a/nand_spl/nand_boot.c
+++ b/nand_spl/nand_boot.c
@@ -221,6 +221,13 @@ static int nand_load(struct mtd_info *mtd, unsigned int offs,
 	return 0;
 }

+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+void board_init_f (ulong bootflag)
+{
+	relocate_code (TEXT_BASE - TOTAL_MALLOC_LEN, NULL, TEXT_BASE);
+}
+#endif
+
 /*
  * The main entry for NAND booting. It's necessary that SDRAM is already
  * configured and available since this code loads the main U-Boot image
diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c
index ea3566b..3105657 100644
--- a/nand_spl/nand_boot_fsl_nfc.c
+++ b/nand_spl/nand_boot_fsl_nfc.c
@@ -263,6 +263,13 @@ static int nand_load(unsigned int from, unsigned int size, unsigned char *buf)
 	return 0;
 }

+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+void board_init_f (ulong bootflag)
+{
+	relocate_code (TEXT_BASE - TOTAL_MALLOC_LEN, NULL, TEXT_BASE);
+}
+#endif
+
 /*
  * The main entry for NAND booting. It's necessary that SDRAM is already
  * configured and available since this code loads the main U-Boot image
-- 
1.6.2.5

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-08-11 18:16 [U-Boot] [PATCH 12/26] ARM: add relocation support Heiko Schocher
@ 2010-09-15 21:06 ` Albert ARIBAUD
  2010-09-16  5:09   ` Heiko Schocher
  2010-09-16  6:23   ` Alessandro Rubini
  0 siblings, 2 replies; 25+ messages in thread
From: Albert ARIBAUD @ 2010-09-15 21:06 UTC (permalink / raw)
  To: u-boot

Le 11/08/2010 20:16, Heiko Schocher a ?crit :

> diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
> index 54519b0..88c6427 100644
> --- a/arch/arm/lib/board.c
> +++ b/arch/arm/lib/board.c

> +init_fnc_t *init_sequence[] = {

Tested this code tonight, and I noticed that if the image is run from 
another location than the one it was linked for, then access to 
init_sequence is not made at the right location. To get correct access 
regardless of the image location, init_sequence has to be defined const.

I suspect that the same applies to all globals used by any function 
called during board_init_f execution.

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-15 21:06 ` Albert ARIBAUD
@ 2010-09-16  5:09   ` Heiko Schocher
  2010-09-16 10:50     ` Albert ARIBAUD
  2010-09-16  6:23   ` Alessandro Rubini
  1 sibling, 1 reply; 25+ messages in thread
From: Heiko Schocher @ 2010-09-16  5:09 UTC (permalink / raw)
  To: u-boot

Hello Albert,

Albert ARIBAUD wrote:
> Le 11/08/2010 20:16, Heiko Schocher a ?crit :
> 
>> diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
>> index 54519b0..88c6427 100644
>> --- a/arch/arm/lib/board.c
>> +++ b/arch/arm/lib/board.c
> 
>> +init_fnc_t *init_sequence[] = {
> 
> Tested this code tonight, and I noticed that if the image is run from
> another location than the one it was linked for, then access to
> init_sequence is not made at the right location. To get correct access
> regardless of the image location, init_sequence has to be defined const.

Hmm.. at this place code is not relocated! So it should be executed
on the right address. Don;t know, if this would be the only problem,
if you run this code from another address ...

> I suspect that the same applies to all globals used by any function
> called during board_init_f execution.

bye
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-15 21:06 ` Albert ARIBAUD
  2010-09-16  5:09   ` Heiko Schocher
@ 2010-09-16  6:23   ` Alessandro Rubini
  2010-09-16  7:06     ` Wolfgang Denk
  1 sibling, 1 reply; 25+ messages in thread
From: Alessandro Rubini @ 2010-09-16  6:23 UTC (permalink / raw)
  To: u-boot

Hello Heiko.

> Hmm.. at this place code is not relocated! So it should be executed
> on the right address.

May I say this is a huge step back from the non-relocation case?

One of the things I love(d) with u-boot (at least the ARM one) is that
I could place it in flash at any address and it would just work.  So
when I have a new binary I first write it to another flash sector and
"go" to it.  Only if it works I flash at offset 0.  Sure I test in RAM
first, but since writing the ram image to flash is not uncommon, the
final test for me has always been in flash -- also for other reasons.

I also think that simpler is better and I never understood the
contorsions of relocation.... but I wouldn't argue if it wasn't a step
back (I know the advantages, like going to end of ram, but they don't
mean much to me).

Is there any chance we could go on testing on a different flash
address without relinking in-between (with the risk of mismatching the
two images?)

Thanks
/alessandro

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16  6:23   ` Alessandro Rubini
@ 2010-09-16  7:06     ` Wolfgang Denk
  2010-09-16  7:18       ` Graeme Russ
  0 siblings, 1 reply; 25+ messages in thread
From: Wolfgang Denk @ 2010-09-16  7:06 UTC (permalink / raw)
  To: u-boot

Dear Alessandro Rubini,

In message <20100916062347.GA25290@morgana.i.gnudd.com> you wrote:
> 
> One of the things I love(d) with u-boot (at least the ARM one) is that
> I could place it in flash at any address and it would just work.  So
> when I have a new binary I first write it to another flash sector and
> "go" to it.  Only if it works I flash at offset 0.  Sure I test in RAM

This may, or may not work. In general you have to be lucky if it does
work.  Many processors have steps in their initialization sequence
which cannot be repeated easily, at least not without a reset.

> first, but since writing the ram image to flash is not uncommon, the
> final test for me has always been in flash -- also for other reasons.

Even if it works, this is not, and cannot be, any guarantee that the
image would run when started out of reset. On contrary, on many
processors you will have to modify the code so that it can be started
on an already running system.

> Is there any chance we could go on testing on a different flash
> address without relinking in-between (with the risk of mismatching the
> two images?)

I don't understand why you think this could (or should) be working? 

We have a static configuration with CONFIG_SKIP_LOWLEVEL_INIT (and
CONFIG_SKIP_RELOCATE_UBOOT); if CONFIG_SKIP_LOWLEVEL_INIT is not set,
starting another U-Boot instance with "go" would repeat the whole
low-level initialization which _will_ break on many systems.


I agree that it would be nice to have U-Boot completely position-
independent and completelky restartable, but this would be a new
feature, which newer existed before.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"'Tis true, 'tis pity, and pity 'tis 'tis true."
    - Poloniouius, in Willie the Shake's _Hamlet, Prince of Darkness_

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16  7:06     ` Wolfgang Denk
@ 2010-09-16  7:18       ` Graeme Russ
  2010-09-16  8:23         ` Wolfgang Denk
  0 siblings, 1 reply; 25+ messages in thread
From: Graeme Russ @ 2010-09-16  7:18 UTC (permalink / raw)
  To: u-boot

On Thu, Sep 16, 2010 at 5:06 PM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Alessandro Rubini,
>
> I agree that it would be nice to have U-Boot completely position-
> independent and completelky restartable, but this would be a new
> feature, which newer existed before.
>

x86 has a nice feature whereby I can build two images that differ only by
TEXT_BASE. I can build using TEXT_BASE somewhere in low memory, tftp the
image and the 'go' directly to the base address of the image

e.g.

> tftp 6000000 u-boot.bin
> go 6000000

This works because the x86 reset vector is at top of memory (0xfffffff0),
not bottom (0x00000000) so the very first bytes of u-boot.bin are not the
reset vector, but rather where the reset vector jumps to after performing
some very low-level hardware init

Both images, as a very first step, relocate to the highest available
memory location and adjust all the relocation offsets in the image and
jump into the relocated image.

As long as I do not mess with the low-level init code, I can be confident
that an image that 'boots' using the 'go' command will boot from Flash

No, it is not a 'fully relocatable' image, but it is so close as to not
make any real difference to me.

Regards,

Graeme

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16  7:18       ` Graeme Russ
@ 2010-09-16  8:23         ` Wolfgang Denk
  2010-09-16  9:54           ` Graeme Russ
  0 siblings, 1 reply; 25+ messages in thread
From: Wolfgang Denk @ 2010-09-16  8:23 UTC (permalink / raw)
  To: u-boot

Dear Graeme Russ,

In message <AANLkTimDxzWm9-sekLv60-zNDFmBKE3dc=kxiO+ZqZZn@mail.gmail.com> you wrote:
>
> > I agree that it would be nice to have U-Boot completely position-
> > independent and completelky restartable, but this would be a new
> > feature, which newer existed before.
> >
> 
> x86 has a nice feature whereby I can build two images that differ only by
> TEXT_BASE. I can build using TEXT_BASE somewhere in low memory, tftp the
> image and the 'go' directly to the base address of the image

You can build such images for any architecture, but usually they will
not work.

The code assumes to be started at the reset vector, and to find a CPU
with all peripherals and registers in virgine state which is only
present after a reset.

On many processors there are certain steps that are irreversiable by
software - there are write-once registers, there are memory controller
registers which change the behaviour of the memory controller when the
are written for the first time, etc.

> This works because the x86 reset vector is at top of memory (0xfffffff0),
> not bottom (0x00000000) so the very first bytes of u-boot.bin are not the
> reset vector, but rather where the reset vector jumps to after performing
> some very low-level hardware init

The actual position of the reset vector in the address space has
nothing to do with that isse. It's other things like register states
or mode of operation of certain units (memory controller, MMU etc.)
that are different when coming frash out of reset versus when coming
from a running U-Boot systems.

> As long as I do not mess with the low-level init code, I can be confident
> that an image that 'boots' using the 'go' command will boot from Flash

This _may_ work on certain boards and processors, but it does not
(and I think it cannot) work in general.


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
He's dead, Jim
	-- McCoy, "The Devil in the Dark", stardate 3196.1

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16  8:23         ` Wolfgang Denk
@ 2010-09-16  9:54           ` Graeme Russ
  2010-09-16 10:18             ` Wolfgang Wegner
  0 siblings, 1 reply; 25+ messages in thread
From: Graeme Russ @ 2010-09-16  9:54 UTC (permalink / raw)
  To: u-boot

On 16/09/10 18:23, Wolfgang Denk wrote:
> Dear Graeme Russ,
> 
> In message <AANLkTimDxzWm9-sekLv60-zNDFmBKE3dc=kxiO+ZqZZn@mail.gmail.com> you wrote:
>>
>>> I agree that it would be nice to have U-Boot completely position-
>>> independent and completelky restartable, but this would be a new
>>> feature, which newer existed before.
>>>
>>
>> x86 has a nice feature whereby I can build two images that differ only by
>> TEXT_BASE. I can build using TEXT_BASE somewhere in low memory, tftp the
>> image and the 'go' directly to the base address of the image
> 
> You can build such images for any architecture, but usually they will
> not work.
> 
> The code assumes to be started at the reset vector, and to find a CPU
> with all peripherals and registers in virgine state which is only
> present after a reset.
> 
> On many processors there are certain steps that are irreversiable by
> software - there are write-once registers, there are memory controller
> registers which change the behaviour of the memory controller when the
> are written for the first time, etc.

I have the same constraints. For example, I cannot reconfigure the DRAM
controller or perform memory sizing after tftp'ing the new image as they
are likely to destroy it.

> 
>> This works because the x86 reset vector is at top of memory (0xfffffff0),
>> not bottom (0x00000000) so the very first bytes of u-boot.bin are not the
>> reset vector, but rather where the reset vector jumps to after performing
>> some very low-level hardware init
> 
> The actual position of the reset vector in the address space has
> nothing to do with that isse. It's other things like register states

True, but it does make life easier to know the 'go' address is the same as
the load address

> or mode of operation of certain units (memory controller, MMU etc.)
> that are different when coming frash out of reset versus when coming
> from a running U-Boot systems.

I have a 'cold-boot' parameter which is set by the reset vector code. I can
use this to selectively skip 'once-only' initialisation

> 
>> As long as I do not mess with the low-level init code, I can be confident
>> that an image that 'boots' using the 'go' command will boot from Flash
> 
> This _may_ work on certain boards and processors, but it does not
> (and I think it cannot) work in general.

I don't doubt that you are entirely correct. But there are many ways to
skin a cat. My problem was to reduce the build->burn->boot development time
where the burn phase was the longest. The low level boot and device
initialisation all works and hasn't changed in quite a while, so I can rely
on what is on my (nearly a year) old image.

I don't see what I am doing as very far removed from the 'ipl' framework. I
have on my 'TODO' list to split the low-level init which always runs from
flash from the higher level code which runs relocated. From there, I can
create a fully position independent image which could be located anywhere
(on the boot flash, on other on-board flash, NAND device etc)

A common framework (within the bounds of cross-architecture limitations)
would be nice

Regards,

Graeme

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16  9:54           ` Graeme Russ
@ 2010-09-16 10:18             ` Wolfgang Wegner
  2010-09-16 10:49               ` Albert ARIBAUD
  2010-09-16 11:06               ` Wolfgang Denk
  0 siblings, 2 replies; 25+ messages in thread
From: Wolfgang Wegner @ 2010-09-16 10:18 UTC (permalink / raw)
  To: u-boot

On Thu, Sep 16, 2010 at 07:54:03PM +1000, Graeme Russ wrote:
[...]
> I have a 'cold-boot' parameter which is set by the reset vector code. I can
> use this to selectively skip 'once-only' initialisation
[...]
> I don't doubt that you are entirely correct. But there are many ways to
> skin a cat. My problem was to reduce the build->burn->boot development time
> where the burn phase was the longest. The low level boot and device
> initialisation all works and hasn't changed in quite a while, so I can rely
> on what is on my (nearly a year) old image.

I see this feature not only nice to speed up development, sometimes
it also comes in really handy for production, too - if you have to
struggle with debugging tools that are either plain too stupid to
program some flash devices or are much slower than U-Boot, you
can simply run a specially built version from RAM and/or provide it
with an environment in RAM to do all the actual flashing for the board
production.

> A common framework (within the bounds of cross-architecture limitations)
> would be nice

For some targets, there may be fragments present in the code
when searching for CONFIG_MONITOR_IS_IN_RAM, which statically
disables all the low-level initialization to allow U-Boot being 
loaded from a first-stage loader or debugger. But beware, it is
not always functional out-of-the-box.

Regards,
Wolfgang

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16 10:18             ` Wolfgang Wegner
@ 2010-09-16 10:49               ` Albert ARIBAUD
  2010-09-16 11:06               ` Wolfgang Denk
  1 sibling, 0 replies; 25+ messages in thread
From: Albert ARIBAUD @ 2010-09-16 10:49 UTC (permalink / raw)
  To: u-boot

Le 16/09/2010 12:18, Wolfgang Wegner a ?crit :
> On Thu, Sep 16, 2010 at 07:54:03PM +1000, Graeme Russ wrote:
> [...]
>> I have a 'cold-boot' parameter which is set by the reset vector code. I can
>> use this to selectively skip 'once-only' initialisation
> [...]
>> I don't doubt that you are entirely correct. But there are many ways to
>> skin a cat. My problem was to reduce the build->burn->boot development time
>> where the burn phase was the longest. The low level boot and device
>> initialisation all works and hasn't changed in quite a while, so I can rely
>> on what is on my (nearly a year) old image.
>
> I see this feature not only nice to speed up development, sometimes
> it also comes in really handy for production, too - if you have to
> struggle with debugging tools that are either plain too stupid to
> program some flash devices or are much slower than U-Boot, you
> can simply run a specially built version from RAM and/or provide it
> with an environment in RAM to do all the actual flashing for the board
> production.
>
>> A common framework (within the bounds of cross-architecture limitations)
>> would be nice
>
> For some targets, there may be fragments present in the code
> when searching for CONFIG_MONITOR_IS_IN_RAM, which statically
> disables all the low-level initialization to allow U-Boot being
> loaded from a first-stage loader or debugger. But beware, it is
> not always functional out-of-the-box.

For ARM926, you can disable low level init stuff and run from RAM by 
defining CONFIG_SKIP_LOWLEVEL_INIT. This works and is actively used in 
kirkwood where low level init is done by a previous loader.

(independently you can disable relocation from FLASH to RAM with 
CONFIG_SKIP_RELOCATE_UBOOT.)

Maybe we could start by standardizing a single (set of) config option(s) 
for skipping inits and have all boards use that?

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16  5:09   ` Heiko Schocher
@ 2010-09-16 10:50     ` Albert ARIBAUD
  2010-09-16 11:29       ` Wolfgang Denk
  0 siblings, 1 reply; 25+ messages in thread
From: Albert ARIBAUD @ 2010-09-16 10:50 UTC (permalink / raw)
  To: u-boot

Le 16/09/2010 07:09, Heiko Schocher a ?crit :
> Hello Albert,
>
> Albert ARIBAUD wrote:
>> Le 11/08/2010 20:16, Heiko Schocher a ?crit :
>>
>>> diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
>>> index 54519b0..88c6427 100644
>>> --- a/arch/arm/lib/board.c
>>> +++ b/arch/arm/lib/board.c
>>
>>> +init_fnc_t *init_sequence[] = {
>>
>> Tested this code tonight, and I noticed that if the image is run from
>> another location than the one it was linked for, then access to
>> init_sequence is not made at the right location. To get correct access
>> regardless of the image location, init_sequence has to be defined const.
>
> Hmm.. at this place code is not relocated! So it should be executed
> on the right address. Don;t know, if this would be the only problem,
> if you run this code from another address ...

Well, the main goal of -fPIC is that the code should be able to run from 
anywhere, so it should be able to run from anywhere in FLASH. Besides, 
that can be useful for designs where two (possibly differently built) 
images of u-boot are located in FLASH and some mechanism allows booting 
from either.

(I personally have another motive for having at least the _f part of 
u-boot able to run fully PIC, as I want to implement direct-to-u-boot 
resetting on targets that have a reset vector rather far away from the 
end of the addressable space but too near to fit u-boot in, e.g. the 
orion5x which resets as 0xffff0000: 64 KB is too small for u-boot. I 
have submitted a patch for this then withdrawn it because of the 
relocation patches; however for this conversation, we can keep this 
point aside)

As for what would or would not work, ATM it boils down to 'access to 
const variables will be position-independent, access to others will 
not'. Non-initialized as well as initialized-but-not-const globals are 
always accessed at their link location before and after relocation, and 
thus will work only if you're running the image at its linked location.

This means that non-const data obviously can't work when the image is 
linked to FLASH; and they can even wreak havoc if the image linked for 
RAM and relocated near, but not exactly at, its linked location. The 
fact that it did not break so far in u-boot without reloc (and yes, 
several drivers do access globals during in-FLASH board init) is due to 
the fact that DRAM is already initialized when drivers access these 
globals at their linked location; this breaks when the image is linked 
for a location in FLASH.

Of course solving the init data issue (by making them const) will not 
solve the issue of rw data. For this one I see two solutions:

1) forbid using such data in drivers during _f phase if that is 
possible. For instance, in the timer.c driver of orion5x, the timer_init 
code accesses two writable variables because it wants to have a first 
reference for rollover detection; this can obviously be postponed to the 
_r init phase.

2) in case where the _f phase *has* to store data in globals, then this 
data should go to the globals space allocated below the stack, where gd 
also resides, and be later copied to usual globals if reqired.

BTW, the comments in board.c say that the _f init functions receive a 
pointer to gd; actually they dont, they're int (*) (void). Were the 
comments always out-of-sync with the code, or was there a removal of the 
gd argument for some reason?

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16 10:18             ` Wolfgang Wegner
  2010-09-16 10:49               ` Albert ARIBAUD
@ 2010-09-16 11:06               ` Wolfgang Denk
  2010-09-16 11:24                 ` Wolfgang Wegner
  1 sibling, 1 reply; 25+ messages in thread
From: Wolfgang Denk @ 2010-09-16 11:06 UTC (permalink / raw)
  To: u-boot

Dear Wolfgang Wegner,

In message <20100916101810.GH25692@leila.ping.de> you wrote:
>
> I see this feature not only nice to speed up development, sometimes
> it also comes in really handy for production, too - if you have to

I think we all agree that this would be a nice-to-have feature.

> struggle with debugging tools that are either plain too stupid to
> program some flash devices or are much slower than U-Boot, you
> can simply run a specially built version from RAM and/or provide it
> with an environment in RAM to do all the actual flashing for the board
> production.

Note the "specially built version". My understanding is that this
"special building" cannot be avoided in general.

> For some targets, there may be fragments present in the code
> when searching for CONFIG_MONITOR_IS_IN_RAM, which statically
> disables all the low-level initialization to allow U-Boot being 
> loaded from a first-stage loader or debugger. But beware, it is
> not always functional out-of-the-box.

True. And the image configured that way is not the same binary image
that you normally load into flash.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
In the beginning there was nothing.
And the Lord said "Let There Be Light!"
And still there was nothing, but at least now you could see it.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16 11:06               ` Wolfgang Denk
@ 2010-09-16 11:24                 ` Wolfgang Wegner
  0 siblings, 0 replies; 25+ messages in thread
From: Wolfgang Wegner @ 2010-09-16 11:24 UTC (permalink / raw)
  To: u-boot

Dear Wolfgang Denk,

On Thu, Sep 16, 2010 at 01:06:01PM +0200, Wolfgang Denk wrote:
> Dear Wolfgang Wegner,
> 
> In message <20100916101810.GH25692@leila.ping.de> you wrote:
[...]
> > struggle with debugging tools that are either plain too stupid to
> > program some flash devices or are much slower than U-Boot, you
> > can simply run a specially built version from RAM and/or provide it
> > with an environment in RAM to do all the actual flashing for the board
> > production.
> 
> Note the "specially built version". My understanding is that this
> "special building" cannot be avoided in general.

I do not know if it can be avoided in general, but if it is architecture-
dependent, maybe those architectures supporting such a boot procedure
to allow doing this with a single image could be made to support it
out-of-the-box. Then the other architectures could still benefit from
more awareness of something like "CONFIG_MONITOR_IS_IN_RAM" or
"CONFIG_SKIP_LOWLEVEL_INIT".

> > For some targets, there may be fragments present in the code
> > when searching for CONFIG_MONITOR_IS_IN_RAM, which statically
> > disables all the low-level initialization to allow U-Boot being 
> > loaded from a first-stage loader or debugger. But beware, it is
> > not always functional out-of-the-box.
> 
> True. And the image configured that way is not the same binary image
> that you normally load into flash.

Currently it is not, and I do not know if it is possible at all for
every architecture and worth the effort to make a single image for
both cases, but as there seem to be already some architectures out
there with (maybe somewhat limited) support, it looks like an
interesting thought to me.

Best regards,
Wolfgang

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16 10:50     ` Albert ARIBAUD
@ 2010-09-16 11:29       ` Wolfgang Denk
  2010-09-16 20:20         ` Albert ARIBAUD
  0 siblings, 1 reply; 25+ messages in thread
From: Wolfgang Denk @ 2010-09-16 11:29 UTC (permalink / raw)
  To: u-boot

Dear Albert ARIBAUD,

In message <4C91F659.7020607@free.fr> you wrote:
>
> Well, the main goal of -fPIC is that the code should be able to run from
> anywhere, so it should be able to run from anywhere in FLASH. Besides,

You misread that. We actually make no attempts that the code can be
run from any arbitrary address. On contrary - we explicitly link it
for a fixed address map, which is defined by the location of the reset
vector, which is the one and only defined entry point into U-Boot.

[I'm giving the generic, architecture independent view of U-Boot
here. Actual implementations for some processors may behave
differently, but this is nothing you should build on.]

> that can be useful for designs where two (possibly differently built)
> images of u-boot are located in FLASH and some mechanism allows booting
> from either.

The only reasonable use cases for such a szenario that I am aware of
would be best implemented in hardware, by being able to toggle between
two banks of flash memory, selecting one or the other as boot device.
Then you can even use the same U-Boot binary images, which is a good
thing in such setups. [eventualkly you want to store the environment
somewhere else, say in some storage device on the backplane, so all
instances of U-Boot refer to the same data.]

> (I personally have another motive for having at least the _f part of
> u-boot able to run fully PIC, as I want to implement direct-to-u-boot
> resetting on targets that have a reset vector rather far away from the
> end of the addressable space but too near to fit u-boot in, e.g. the
> orion5x which resets as 0xffff0000: 64 KB is too small for u-boot. I
> have submitted a patch for this then withdrawn it because of the
> relocation patches; however for this conversation, we can keep this
> point aside)

I do not understand this what you mean by that, or what the problem
might be. It is trivial to arrange the code such that no significant
gaps remain. This requires just a little tuning of the linker
script.

> As for what would or would not work, ATM it boils down to 'access to
> const variables will be position-independent, access to others will
> not'. Non-initialized as well as initialized-but-not-const globals are
> always accessed at their link location before and after relocation, and
> thus will work only if you're running the image at its linked location.

Again, please keep in mind that (1) this depends on the linker script,
and (2) that before relocation to RAM _all_ access to global variables
is extremely limited as we have only a read-only data segment and no
BSS segment at all.

> This means that non-const data obviously can't work when the image is
> linked to FLASH; and they can even wreak havoc if the image linked for
> RAM and relocated near, but not exactly at, its linked location. The

I don't understand what you mean. Are you aware of the restrictions
of the execution environment before relocation to RAM?

> fact that it did not break so far in u-boot without reloc (and yes,
> several drivers do access globals during in-FLASH board init) is due to
> the fact that DRAM is already initialized when drivers access these
> globals at their linked location; this breaks when the image is linked
> for a location in FLASH.

If any drivers do such things, and if these drivers are used before
relocation to RAM, these are serious bugs that must be fixed.

If you are aware of such bugs please post this information, so people
can start working on fixes.

> Of course solving the init data issue (by making them const) will not
> solve the issue of rw data. For this one I see two solutions:
>
> 1) forbid using such data in drivers during _f phase if that is

This is, and has always been, the case.

> possible. For instance, in the timer.c driver of orion5x, the timer_init
> code accesses two writable variables because it wants to have a first
> reference for rollover detection; this can obviously be postponed to the
> _r init phase.

Hm... I don;t see global variables being used in timer_init() in
"arch/arm/cpu/arm926ejs/orion5x/timer.c" - which exact code are you
referring to?

> 2) in case where the _f phase *has* to store data in globals, then this
> data should go to the globals space allocated below the stack, where gd
> also resides, and be later copied to usual globals if reqired.

It seems you really minunderstand the excution environment before
relocation.  Ther eis also no steck there, and of course no "globals
space allocated below the stack", because we don't even have the RAM
initialized yet.

> BTW, the comments in board.c say that the _f init functions receive a
> pointer to gd; actually they dont, they're int (*) (void). Were the
> comments always out-of-sync with the code, or was there a removal of the
> gd argument for some reason?

Please read the code, and the README. Please pay special attention to
section "Initial Stack, Global Data:".

In short: the pointer to the global data is passed in a register,
which we reserve for this purpose.


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"... freedom ... is a worship word..."
"It is our worship word too."
	-- Cloud William and Kirk, "The Omega Glory", stardate unknown

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16 11:29       ` Wolfgang Denk
@ 2010-09-16 20:20         ` Albert ARIBAUD
  2010-09-16 21:26           ` Wolfgang Denk
  0 siblings, 1 reply; 25+ messages in thread
From: Albert ARIBAUD @ 2010-09-16 20:20 UTC (permalink / raw)
  To: u-boot

Le 16/09/2010 13:29, Wolfgang Denk a ?crit :
> Dear Albert ARIBAUD,
>
> In message<4C91F659.7020607@free.fr>  you wrote:
>>
>> Well, the main goal of -fPIC is that the code should be able to run from
>> anywhere, so it should be able to run from anywhere in FLASH. Besides,
>
> You misread that. We actually make no attempts that the code can be
> run from any arbitrary address. On contrary - we explicitly link it
> for a fixed address map, which is defined by the location of the reset
> vector, which is the one and only defined entry point into U-Boot.

I did not write 'the goal of using fPIC in u-boot', I wrote 'the goal of 
fPIC', and as such, I think I read it right. I do agree though (and I 
think I made it clear further in my post) that u-boot images are linked 
for a fixed location and that their entry point is at the first address 
of this location.

However, I disagree with the fact that u-boot's link address would 
always be the reset vector location. This is not generally true, and 
this is especially not true for the orion5x, which is linked for its RAM 
location, not for its FLASH location, and for which the image is flashed 
so that _start does not end up at the reset address. And in that 
context, u-boot is designed to execute -- once jumped at from the reset 
vector -- to start running at a location (in FLASH) different from the 
one it was linked for (the RAM) until it has relocated itself to its 
intended RAM address, at which point it jumps there.

> [I'm giving the generic, architecture independent view of U-Boot
> here. Actual implementations for some processors may behave
> differently, but this is nothing you should build on.]

[Except when working with these processors. :) ]

>> that can be useful for designs where two (possibly differently built)
>> images of u-boot are located in FLASH and some mechanism allows booting
>> from either.
>
> The only reasonable use cases for such a szenario that I am aware of
> would be best implemented in hardware, by being able to toggle between
> two banks of flash memory, selecting one or the other as boot device.
> Then you can even use the same U-Boot binary images, which is a good
> thing in such setups. [eventualkly you want to store the environment
> somewhere else, say in some storage device on the backplane, so all
> instances of U-Boot refer to the same data.]
>
>> (I personally have another motive for having at least the _f part of
>> u-boot able to run fully PIC, as I want to implement direct-to-u-boot
>> resetting on targets that have a reset vector rather far away from the
>> end of the addressable space but too near to fit u-boot in, e.g. the
>> orion5x which resets as 0xffff0000: 64 KB is too small for u-boot. I
>> have submitted a patch for this then withdrawn it because of the
>> relocation patches; however for this conversation, we can keep this
>> point aside)
>
> I do not understand this what you mean by that, or what the problem
> might be. It is trivial to arrange the code such that no significant
> gaps remain. This requires just a little tuning of the linker
> script.

As for what I am trying to do: ironically, I am trying to find a way 
that the entry point of u-boot be at the reset vector location, just as 
it should.

As for you suggestion of arranging the code so that the entry point ends 
up at 0xffff0000, it requires much more than a little tuning of the 
linker script. This tuning is actually a long and suboptimal process 
akin to the bin packing problem, where you'd have to split sections, 
notably .text, and then shuffle sections in memory areas while hoping 
that no section is going to grow bigger than the memory region it was 
assigned to. And then, change one thing in the config, and you may need 
to solve the problem yet again.

This would be a huge inconvenience and a clumsy way of doing things, 
when another solution allows keeping the current linear, single-region, 
all-initialized-content-in-one-block mapping and requires only flashing 
the image in a clever way (although I'm saying it myself) and adding 
around twenty instructions to the existing start.S.

>> As for what would or would not work, ATM it boils down to 'access to
>> const variables will be position-independent, access to others will
>> not'. Non-initialized as well as initialized-but-not-const globals are
>> always accessed at their link location before and after relocation, and
>> thus will work only if you're running the image at its linked location.
>
> Again, please keep in mind that (1) this depends on the linker script,
> and (2) that before relocation to RAM _all_ access to global variables
> is extremely limited as we have only a read-only data segment and no
> BSS segment at all.

I do have 2 in mind -- I thought that was clear from the rest of my 
post. For 1, well, yes that depends on the linker script, but here I am 
talking about only one linker script, that of the arm926ejs. I see an 
issue there with relocating while init_sequence is not const, but maybe 
it does not occur for other CPUs than ARM, and maybe it does not even 
occur on ARMs for compilers other than the one provided in ELDK42 -- 
that's the one I'm using. But I do think that it does happen with all 
gcc versions, because this is not a compiler bug, this is an overlook in 
board.c -- fundamentally, init_sequence *is* a const and should be 
qualified as such.

>> This means that non-const data obviously can't work when the image is
>> linked to FLASH; and they can even wreak havoc if the image linked for
>> RAM and relocated near, but not exactly at, its linked location. The
>
> I don't understand what you mean. Are you aware of the restrictions
> of the execution environment before relocation to RAM?

I am. More precisely, I am more aware if it than some code in u-boot is. :)

>> fact that it did not break so far in u-boot without reloc (and yes,
>> several drivers do access globals during in-FLASH board init) is due to
>> the fact that DRAM is already initialized when drivers access these
>> globals at their linked location; this breaks when the image is linked
>> for a location in FLASH.
>
> If any drivers do such things, and if these drivers are used before
> relocation to RAM, these are serious bugs that must be fixed.

Uhm... That's what I am implying here, and what I explicitely offer 
solutions for further in my post.

> If you are aware of such bugs please post this information, so people
> can start working on fixes.

I will certainly.

>> Of course solving the init data issue (by making them const) will not
>> solve the issue of rw data. For this one I see two solutions:
>>
>> 1) forbid using such data in drivers during _f phase if that is
>
> This is, and has always been, the case.

Then in at least two cases it was missed by reviews. See below (*).

>> possible. For instance, in the timer.c driver of orion5x, the timer_init
>> code accesses two writable variables because it wants to have a first
>> reference for rollover detection; this can obviously be postponed to the
>> _r init phase.
>
> Hm... I don;t see global variables being used in timer_init() in
> "arch/arm/cpu/arm926ejs/orion5x/timer.c" - which exact code are you
> referring to?

(*)

timer_init() ends up calling reset_timer_masked(), which writes into 
static variables timestamp and lastdec.

The second case where it was missed is in the kirkwood timer, which is 
quite logical as the orion5x code is based on the kirkwood one.

>> 2) in case where the _f phase *has* to store data in globals, then this
>> data should go to the globals space allocated below the stack, where gd
>> also resides, and be later copied to usual globals if reqired.
>
> It seems you really minunderstand the excution environment before
> relocation.  Ther eis also no steck there, and of course no "globals
> space allocated below the stack", because we don't even have the RAM
> initialized yet.

I stand corrected--Indeed, we don't have RAM inittialized at this point. 
This makes my second suggestion inapplicable... And the first one, as 
you noted, is already a requirement.

>> BTW, the comments in board.c say that the _f init functions receive a
>> pointer to gd; actually they dont, they're int (*) (void). Were the
>> comments always out-of-sync with the code, or was there a removal of the
>> gd argument for some reason?
>
> Please read the code, and the README. Please pay special attention to
> section "Initial Stack, Global Data:".
>
> In short: the pointer to the global data is passed in a register,
> which we reserve for this purpose.

This is true, and reinforces my point that the comment in board.c is out 
of sync with what is really going on, as it explicitely says the pointer 
is passed as an argument to the init functions (lines 241 and 242 in 
'next') whereas it is not.

> Best regards,
>
> Wolfgang Denk

I still think that with -fPIC u-boot should be able to run until at 
least the end of board_init_f from anywhere in FLASH. And if all it 
takes to get there is making sure that board_init_f-called code uses 
only consts, then I think it would be worth asking board maintainers to 
go check this while they're testing Heiko's relocation patches.

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16 20:20         ` Albert ARIBAUD
@ 2010-09-16 21:26           ` Wolfgang Denk
  2010-09-17  6:16             ` Albert ARIBAUD
  0 siblings, 1 reply; 25+ messages in thread
From: Wolfgang Denk @ 2010-09-16 21:26 UTC (permalink / raw)
  To: u-boot

Dear Albert ARIBAUD,

In message <4C927C0C.1080007@free.fr> you wrote:
>
> I did not write 'the goal of using fPIC in u-boot', I wrote 'the goal of 
> fPIC', and as such, I think I read it right. I do agree though (and I 
> think I made it clear further in my post) that u-boot images are linked 
> for a fixed location and that their entry point is at the first address 
> of this location.

Wrong. Their entry point is whereever the reset vector happens to be,
and this is usually NOT at offset 0 into the text segment.

> However, I disagree with the fact that u-boot's link address would 
> always be the reset vector location. This is not generally true, and 
> this is especially not true for the orion5x, which is linked for its RAM 
> location, not for its FLASH location, and for which the image is flashed 

You are probably looking at old, obsolete code.  Please check out the
"next" branch, which has Heiko's ARM rework patches applied.

> > [I'm giving the generic, architecture independent view of U-Boot
> > here. Actual implementations for some processors may behave
> > differently, but this is nothing you should build on.]
> 
> [Except when working with these processors. :) ]

Not even then, because things might change under your feet - as just
happened.

> As for what I am trying to do: ironically, I am trying to find a way 
> that the entry point of u-boot be at the reset vector location, just as 
> it should.

There it is.

> As for you suggestion of arranging the code so that the entry point ends 
> up at 0xffff0000, it requires much more than a little tuning of the 
> linker script. This tuning is actually a long and suboptimal process 
> akin to the bin packing problem, where you'd have to split sections, 
> notably .text, and then shuffle sections in memory areas while hoping 
> that no section is going to grow bigger than the memory region it was 
> assigned to. And then, change one thing in the config, and you may need 
> to solve the problem yet again.

If you can live with the wasted 64 kB of empty space "behind" the
reset vector, then it is not worse than counting the number of flash
sectors needed for the image (which you have to do anyway to
determine the TEXT_BASE). And moving a number of static,
never-changing objects into that free area is no real rocket science
either.  Say, half an hour of efforts including basic testing.

> > Hm... I don;t see global variables being used in timer_init() in
> > "arch/arm/cpu/arm926ejs/orion5x/timer.c" - which exact code are you
> > referring to?
> 
> (*)
> 
> timer_init() ends up calling reset_timer_masked(), which writes into 
> static variables timestamp and lastdec.

This is indeed broken and needs to be fixed.

> This is true, and reinforces my point that the comment in board.c is out 
> of sync with what is really going on, as it explicitely says the pointer 
> is passed as an argument to the init functions (lines 241 and 242 in 
> 'next') whereas it is not.

Patch welcome...

> I still think that with -fPIC u-boot should be able to run until at 
> least the end of board_init_f from anywhere in FLASH. And if all it 
> takes to get there is making sure that board_init_f-called code uses 
> only consts, then I think it would be worth asking board maintainers to 
> go check this while they're testing Heiko's relocation patches.

We use PIC to make U-Boot relocatable to any RAM address, so we can
auto-adjust to actual RAM sizes and always copy U-Boot to the
(dynamically determined) end of RAM location.  When running from
flash, U-Boot is linked to a fixed address map, which includes the
(fix) reset vector as single entry point.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Our management frequently gets lost in thought.   That's because it's
unfamiliar territory.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-16 21:26           ` Wolfgang Denk
@ 2010-09-17  6:16             ` Albert ARIBAUD
  2010-09-17 11:05               ` Wolfgang Denk
  0 siblings, 1 reply; 25+ messages in thread
From: Albert ARIBAUD @ 2010-09-17  6:16 UTC (permalink / raw)
  To: u-boot

Le 16/09/2010 23:26, Wolfgang Denk a ?crit :
> Dear Albert ARIBAUD,
>
> In message<4C927C0C.1080007@free.fr>  you wrote:
>>
>> I did not write 'the goal of using fPIC in u-boot', I wrote 'the goal of
>> fPIC', and as such, I think I read it right. I do agree though (and I
>> think I made it clear further in my post) that u-boot images are linked
>> for a fixed location and that their entry point is at the first address
>> of this location.
>
> Wrong. Their entry point is whereever the reset vector happens to be,
> and this is usually NOT at offset 0 into the text segment.

They key here is 'usually'; see the orion5x case for instance.

>> However, I disagree with the fact that u-boot's link address would
>> always be the reset vector location. This is not generally true, and
>> this is especially not true for the orion5x, which is linked for its RAM
>> location, not for its FLASH location, and for which the image is flashed
>
> You are probably looking at old, obsolete code.  Please check out the
> "next" branch, which has Heiko's ARM rework patches applied.

I am looking at code which was in effect until Heiko's patches; this is 
barely 'old, obsolete code', and I am precisely discussing the fact that 
Heiko's patches break building this code for orion5x, and require 
replacing a simple process with quite a complicated one.

>>> [I'm giving the generic, architecture independent view of U-Boot
>>> here. Actual implementations for some processors may behave
>>> differently, but this is nothing you should build on.]
>>
>> [Except when working with these processors. :) ]
>
> Not even then, because things might change under your feet - as just
> happened.

Things do change indeed, hence my attempt ? 1) making sure I detect the 
change, 2) design things so that they are as resilient to change as 
possible. One example of such a resilience is making sure the u-boot 
code designed to run in FLASH can run *anywhere* in FLASH.

>> As for what I am trying to do: ironically, I am trying to find a way
>> that the entry point of u-boot be at the reset vector location, just as
>> it should.
>
> There it is.

Yes. And you are opposing this, which I do not understand since I'm 
trying to make this SoC/board perform exactly as you specify while 
maintaining balance with the hardware's constraints.

>> As for you suggestion of arranging the code so that the entry point ends
>> up at 0xffff0000, it requires much more than a little tuning of the
>> linker script. This tuning is actually a long and suboptimal process
>> akin to the bin packing problem, where you'd have to split sections,
>> notably .text, and then shuffle sections in memory areas while hoping
>> that no section is going to grow bigger than the memory region it was
>> assigned to. And then, change one thing in the config, and you may need
>> to solve the problem yet again.
>
> If you can live with the wasted 64 kB of empty space "behind" the
> reset vector, then it is not worse than counting the number of flash
> sectors needed for the image (which you have to do anyway to
> determine the TEXT_BASE). And moving a number of static,
> never-changing objects into that free area is no real rocket science
> either.  Say, half an hour of efforts including basic testing.

Precisely, I do not want to live with wasting 64 out of 512 KB of FLASH.

Regarding counting the flash sectors for mapping u-boot to flash to 
determine TEXT_BASE, I never had to, thanks to u-boot being (albeit 
accidentally) able to run from anywhere in FLASH (I can't help seeing 
irony in the fact that this ability was broken by adding a flag which is 
supposed to allow running from anywhere).

As for the half-hour of effort, the half-hour part is an assumption 
which would need supporting, and even if it is only half an hour, it is 
half an hours for each person configuring u-boot for arm; a burden that 
I am not willing to inflict on people who want to use u-boot on 
arm926ejs if I know a way to avoid it, and I know one which indeed 
requires a bit more effort but for me only, and will be just as 
(in)sensitive to things moving under feet.

>>> Hm... I don;t see global variables being used in timer_init() in
>>> "arch/arm/cpu/arm926ejs/orion5x/timer.c" - which exact code are you
>>> referring to?
>>
>> (*)
>>
>> timer_init() ends up calling reset_timer_masked(), which writes into
>> static variables timestamp and lastdec.
>
> This is indeed broken and needs to be fixed.
>
>> This is true, and reinforces my point that the comment in board.c is out
>> of sync with what is really going on, as it explicitely says the pointer
>> is passed as an argument to the init functions (lines 241 and 242 in
>> 'next') whereas it is not.
>
> Patch welcome...

Patches for both timer and board.c coming in soon. :)

>> I still think that with -fPIC u-boot should be able to run until at
>> least the end of board_init_f from anywhere in FLASH. And if all it
>> takes to get there is making sure that board_init_f-called code uses
>> only consts, then I think it would be worth asking board maintainers to
>> go check this while they're testing Heiko's relocation patches.
>
> We use PIC to make U-Boot relocatable to any RAM address, so we can
> auto-adjust to actual RAM sizes and always copy U-Boot to the
> (dynamically determined) end of RAM location.  When running from
> flash, U-Boot is linked to a fixed address map, which includes the
> (fix) reset vector as single entry point.

This statement does not contradict the proposal that U-boot, despite 
being linked for some address in FLASH, should be able to run, from 
_start to relocation, at any FLASH location at least for architectures, 
CPUs, SoCs or boards which trivially allow this. I do believe this 
requirement is both reasonable and useful.

Anyway: there is a bottom line on which I think we agree now:

1) init_sequence is a constant array and should thus be qualified 'const';

2) any data accessed between _start and relocation should be const as well.

Since enforcing these two constaints will fix the problem I have with 
(wrongly) running u-boot from any FLASH location, I'll happily cease 
arguing for it if so ordered; but as long as I can, I'll continue making 
sure changes made to u-boot avoid breaking this if they can.

(and I'll be sure to address the requirement that u-boot be linked for 
an address in flash which contains its entry point in my upcoming patch 
for using the last 64 KB of flash on orion5x)

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-17  6:16             ` Albert ARIBAUD
@ 2010-09-17 11:05               ` Wolfgang Denk
  2010-09-17 12:58                 ` Albert ARIBAUD
  0 siblings, 1 reply; 25+ messages in thread
From: Wolfgang Denk @ 2010-09-17 11:05 UTC (permalink / raw)
  To: u-boot

Dear Albert ARIBAUD,

In message <4C9307C4.40208@free.fr> you wrote:
>
> Things do change indeed, hence my attempt ? 1) making sure I detect the 
> change, 2) design things so that they are as resilient to change as 
> possible. One example of such a resilience is making sure the u-boot 
> code designed to run in FLASH can run *anywhere* in FLASH.

As for 1), just follow the postings on this mailing list.

As for 2), you need to implement the following features (none of which
are supported yet, AFAICT):

[This is based on the assumption that you want to use the very same
binary image fom different addresses]

- The code must be completely position-independent.
- You need a way to detect if you are running on a virgin CPU fresh
  out of reset or on a pre-initialized system.
- You need to isolate parts in the initialization sequence that must
  not be repeated.
- You must make sure such steps are not re-run on a pre-initialized
  system.
- You need to implement a way with the different behaviour in terms of
  resources.

> >> As for what I am trying to do: ironically, I am trying to find a way
> >> that the entry point of u-boot be at the reset vector location, just as
> >> it should.
> >
> > There it is.
> 
> Yes. And you are opposing this, which I do not understand since I'm 
> trying to make this SoC/board perform exactly as you specify while 
> maintaining balance with the hardware's constraints.

I do not understand what you mean. Unless loaded by some other
mechanism (like when booting from NAND flash etc.), the entry point
to U-Boot *is* of course at the reset vector location - or how would
the CPU be able to execute the code?

> > If you can live with the wasted 64 kB of empty space "behind" the
> > reset vector, then it is not worse than counting the number of flash
> > sectors needed for the image (which you have to do anyway to
> > determine the TEXT_BASE). And moving a number of static,
> > never-changing objects into that free area is no real rocket science
> > either.  Say, half an hour of efforts including basic testing.
> 
> Precisely, I do not want to live with wasting 64 out of 512 KB of FLASH.

OK, se put a few objects in that "hole" to fill it.

> Regarding counting the flash sectors for mapping u-boot to flash to 
> determine TEXT_BASE, I never had to, thanks to u-boot being (albeit 
> accidentally) able to run from anywhere in FLASH (I can't help seeing 
> irony in the fact that this ability was broken by adding a flag which is 
> supposed to allow running from anywhere).

I lost you.  If you put the U-Boot image at an arbitrary location in
flash, the CPU will not start it because the CPU begins execution at
the reset vector.

> As for the half-hour of effort, the half-hour part is an assumption 
> which would need supporting, and even if it is only half an hour, it is 
> half an hours for each person configuring u-boot for arm; a burden that 

No. Only for those who have a system with such a reset vector
location, and I seriously doubt that any of these changes to the
linker script have to be board specific. That means you just need to
perform this task once to improve the platform-specific linker script,
and it will automatically work for all other users of that
architecture as well.

> This statement does not contradict the proposal that U-boot, despite 
> being linked for some address in FLASH, should be able to run, from 
> _start to relocation, at any FLASH location at least for architectures, 
> CPUs, SoCs or boards which trivially allow this. I do believe this 
> requirement is both reasonable and useful.

If you know how to implement this in a clean way, then please go
forward and do it. Patches are welcome.  All I can say is that I don't
know how to do that, but then, I'm not an ARM expert. Eventually it
might be easier on ARM than on PowerPC, where we don't have this
feature yet either.

> Anyway: there is a bottom line on which I think we agree now:
> 
> 1) init_sequence is a constant array and should thus be qualified 'const';
> 
> 2) any data accessed between _start and relocation should be const as well.

I think you mean the right thing, but the wording is wrong again.

You can fully access (read and write) data in the special "global
data" or "initial data" structure. You can perform read-accesses to
any data in the text and/or data segments. You cannot write to data in
the  the text and/or data segments. You must not attempt to access any
data in the bss segment because this does not even exist, so you're
accessing random addresses.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Common sense and a sense of humor  are  the  same  thing,  moving  at
different speeds.  A sense of humor is just common sense, dancing.
                                                        - Clive James

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-17 11:05               ` Wolfgang Denk
@ 2010-09-17 12:58                 ` Albert ARIBAUD
  2010-09-17 14:52                   ` Wolfgang Denk
  0 siblings, 1 reply; 25+ messages in thread
From: Albert ARIBAUD @ 2010-09-17 12:58 UTC (permalink / raw)
  To: u-boot

Le 17/09/2010 13:05, Wolfgang Denk a ?crit :
> Dear Albert ARIBAUD,
>
> In message<4C9307C4.40208@free.fr>  you wrote:
>>
>> Things do change indeed, hence my attempt ? 1) making sure I detect the
>> change, 2) design things so that they are as resilient to change as
>> possible. One example of such a resilience is making sure the u-boot
>> code designed to run in FLASH can run *anywhere* in FLASH.
>
> As for 1), just follow the postings on this mailing list.

Check. :)

> As for 2), you need to implement the following features (none of which
> are supported yet, AFAICT):
>
> [This is based on the assumption that you want to use the very same
> binary image fom different addresses]
>
> - The code must be completely position-independent.

This is indeed what I am trying to achieve by suggesting qualifying 
const init_sequence and any other constant data used by u-boot while 
executing from FLASH.

> - You need a way to detect if you are running on a virgin CPU fresh
>    out of reset or on a pre-initialized system.
> - You need to isolate parts in the initialization sequence that must
>    not be repeated.
> - You must make sure such steps are not re-run on a pre-initialized
>    system.

This is not required per se to 'start from any location'. It is required 
to 'start in any state', which is another requirement -- also 
commandable since it increases resilience to varying conditions. I think 
the 'start from anywhere' requirement can be fulfilled without 
fulfilling (yet) the 'start in any state' one.

> - You need to implement a way with the different behaviour in terms of
>    resources.

This requirement sounds very general; can you be more precise on it?

>>>> As for what I am trying to do: ironically, I am trying to find a way
>>>> that the entry point of u-boot be at the reset vector location, just as
>>>> it should.
>>>
>>> There it is.
>>
>> Yes. And you are opposing this, which I do not understand since I'm
>> trying to make this SoC/board perform exactly as you specify while
>> maintaining balance with the hardware's constraints.
>
> I do not understand what you mean. Unless loaded by some other
> mechanism (like when booting from NAND flash etc.), the entry point
> to U-Boot *is* of course at the reset vector location - or how would
> the CPU be able to execute the code?

Yes, u-boot needs to be stored in FLASH so that at execution time the 
_start symbol is mapped at the physical location of the reset vector.

But no, u-boot does not necessarily need to be linked so that the _start 
symbol maps at the vector reset location; not, at least, if the startup 
code is position-independent.

Now, for arm926ejs, it so happens that prior to Heiko's relocation 
patches, u-boot's startup code *was* position-independent, and is not 
any more, but that making init_sequence (and other data read during 
startup) onst makes it p-i again.

>>> If you can live with the wasted 64 kB of empty space "behind" the
>>> reset vector, then it is not worse than counting the number of flash
>>> sectors needed for the image (which you have to do anyway to
>>> determine the TEXT_BASE). And moving a number of static,
>>> never-changing objects into that free area is no real rocket science
>>> either.  Say, half an hour of efforts including basic testing.
>>
>> Precisely, I do not want to live with wasting 64 out of 512 KB of FLASH.
>
> OK, se put a few objects in that "hole" to fill it.

This is a bad approach, as I explain below.

>> Regarding counting the flash sectors for mapping u-boot to flash to
>> determine TEXT_BASE, I never had to, thanks to u-boot being (albeit
>> accidentally) able to run from anywhere in FLASH (I can't help seeing
>> irony in the fact that this ability was broken by adding a flag which is
>> supposed to allow running from anywhere).
>
> I lost you.  If you put the U-Boot image at an arbitrary location in
> flash, the CPU will not start it because the CPU begins execution at
> the reset vector.

You're mistaking "putting the image anywhere in FLASH" and "putting 
_start anywhere in FLASH".

>> As for the half-hour of effort, the half-hour part is an assumption
>> which would need supporting, and even if it is only half an hour, it is
>> half an hours for each person configuring u-boot for arm; a burden that
>
> No. Only for those who have a system with such a reset vector
> location,

That is, all people using orion5x for instance.

> and I seriously doubt that any of these changes to the
> linker script have to be board specific.

I did not say board-specific, I said config-specific.

> That means you just need to
> perform this task once to improve the platform-specific linker script,
> and it will automatically work for all other users of that
> architecture as well.

Only for a given u-boot configuration. Change it, and that changes the 
image content, thus the mapping, and you've got to fix _start again.

>> This statement does not contradict the proposal that U-boot, despite
>> being linked for some address in FLASH, should be able to run, from
>> _start to relocation, at any FLASH location at least for architectures,
>> CPUs, SoCs or boards which trivially allow this. I do believe this
>> requirement is both reasonable and useful.
>
> If you know how to implement this in a clean way, then please go
> forward and do it. Patches are welcome.  All I can say is that I don't
> know how to do that, but then, I'm not an ARM expert. Eventually it
> might be easier on ARM than on PowerPC, where we don't have this
> feature yet either.

I do know how to implement this indeed -- I actually have a working (and 
thoroughly tested) implementation, but valid for the master branch, 
without Heiko's patches; I am working on making it work with Heiko's 
patches right now. I can send a patch set based on master to the list as 
an RFC.

>> Anyway: there is a bottom line on which I think we agree now:
>>
>> 1) init_sequence is a constant array and should thus be qualified 'const';
>>
>> 2) any data accessed between _start and relocation should be const as well.
>
> I think you mean the right thing, but the wording is wrong again.
>
> You can fully access (read and write) data in the special "global
> data" or "initial data" structure.

In that respect I may indeed have expressed myself inadequately. When I 
said that a driver's _f init function could pass data via 'globals space 
allocated below the stack, I should have said 'above' -- but I had 
clearly expressed that I was talking about the memory area where gd lives.

> You can perform read-accesses to
> any data in the text and/or data segments. You cannot write to data in
> the  the text and/or data segments. You must not attempt to access any
> data in the bss segment because this does not even exist, so you're
> accessing random addresses.

I think none of this contradicts either of points 1) and 2) above. Or 
does it?

> Best regards,
>
> Wolfgang Denk

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-17 12:58                 ` Albert ARIBAUD
@ 2010-09-17 14:52                   ` Wolfgang Denk
  2010-09-17 16:39                     ` Albert ARIBAUD
  0 siblings, 1 reply; 25+ messages in thread
From: Wolfgang Denk @ 2010-09-17 14:52 UTC (permalink / raw)
  To: u-boot

Dear Albert ARIBAUD,

In message <4C9365E7.50505@free.fr> you wrote:
>
> > - You need a way to detect if you are running on a virgin CPU fresh
> >    out of reset or on a pre-initialized system.
> > - You need to isolate parts in the initialization sequence that must
> >    not be repeated.
> > - You must make sure such steps are not re-run on a pre-initialized
> >    system.
> 
> This is not required per se to 'start from any location'. It is required 
> to 'start in any state', which is another requirement -- also 

"start in any state" is only possible by going through the hardware
reset. There are messed up situations where you cannot recover the
processor any more by software.

You probably mean "virgin state after reset" versus "some other, but
sane state, for example while running U-Boot". You cannot separate
these. If you want to start from another location, you must run some
other code before that (as the CPU will always start from the boot
vector only), so your system state has been changed.

> commandable since it increases resilience to varying conditions. I think 
> the 'start from anywhere' requirement can be fulfilled without 
> fulfilling (yet) the 'start in any state' one.

But not without being able to "start in another, non-virgin state".


> > - You need to implement a way with the different behaviour in terms of
> >    resources.
> 
> This requirement sounds very general; can you be more precise on it?

After reset you have no RAM, no stack, no BSS, no writable data
segment, etc. etc. When starting from some other code, conditions may
be different.

> Now, for arm926ejs, it so happens that prior to Heiko's relocation 
> patches, u-boot's startup code *was* position-independent, and is not 
> any more, but that making init_sequence (and other data read during 
> startup) onst makes it p-i again.

OK.

> > I lost you.  If you put the U-Boot image at an arbitrary location in
> > flash, the CPU will not start it because the CPU begins execution at
> > the reset vector.
> 
> You're mistaking "putting the image anywhere in FLASH" and "putting 
> _start anywhere in FLASH".

_start is integral part of the U-Boot image...

> >> As for the half-hour of effort, the half-hour part is an assumption
> >> which would need supporting, and even if it is only half an hour, it is
> >> half an hours for each person configuring u-boot for arm; a burden that
> >
> > No. Only for those who have a system with such a reset vector
> > location,
> 
> That is, all people using orion5x for instance.
> 
> > and I seriously doubt that any of these changes to the
> > linker script have to be board specific.
> 
> I did not say board-specific, I said config-specific.

It does not depend on board configuration or such. It depends only on
your system's memory map (location of the reset vector), and this is
constant - for example - for all orion5x boards.

> Only for a given u-boot configuration. Change it, and that changes the 
> image content, thus the mapping, and you've got to fix _start again.

Why should I?  Did you not state that the reset vector is at a fixed
location? Then we can use constant data (comon to all board
configurations) to fill the gap between there and end of physical
memory space.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
If a train station is a place where a train stops,
                                           then what's a workstation?

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-17 14:52                   ` Wolfgang Denk
@ 2010-09-17 16:39                     ` Albert ARIBAUD
  2010-09-17 19:04                       ` Wolfgang Denk
  0 siblings, 1 reply; 25+ messages in thread
From: Albert ARIBAUD @ 2010-09-17 16:39 UTC (permalink / raw)
  To: u-boot

Le 17/09/2010 16:52, Wolfgang Denk a ?crit :
> Dear Albert ARIBAUD,
>
> In message<4C9365E7.50505@free.fr>  you wrote:
>>
>>> - You need a way to detect if you are running on a virgin CPU fresh
>>>     out of reset or on a pre-initialized system.
>>> - You need to isolate parts in the initialization sequence that must
>>>     not be repeated.
>>> - You must make sure such steps are not re-run on a pre-initialized
>>>     system.
>>
>> This is not required per se to 'start from any location'. It is required
>> to 'start in any state', which is another requirement -- also
>
> "start in any state" is only possible by going through the hardware
> reset.

Depends on the processor I guess; but still, my point is that "start at 
any location" does not require that you detect whether you are fresh out 
of reset or not.

> There are messed up situations where you cannot recover the
> processor any more by software.

Possibly. So what?

> You probably mean "virgin state after reset" versus "some other, but
> sane state, for example while running U-Boot". You cannot separate
> these.

Yes, I mean start in any sane state, and I think this is a different 
problem that "start from any location".

> If you want to start from another location, you must run some
> other code before that (as the CPU will always start from the boot
> vector only), so your system state has been changed.

On ARM, the other code could be a single branch instruction, in which 
case for all practical purposes the only part of the state that would 
changed is the pc, which is already prone to changing a lot.

>> commandable since it increases resilience to varying conditions. I think
>> the 'start from anywhere' requirement can be fulfilled without
>> fulfilling (yet) the 'start in any state' one.
>
> But not without being able to "start in another, non-virgin state".

Maybe on some architectures this other state is considerably different 
to the point that u-boot could not start properly; on arm926ejs (and, I 
suspect, on other ARMs as well) the 'non-virginity' can be limited to 
"having done some reads, writes and branches" without preventing u-boot 
from starting using exactly the same code as it would if executed 
directly on reset. That's tested, and actually used in production on 
several arm926ejs based boards.

>>> - You need to implement a way with the different behaviour in terms of
>>>     resources.
>>
>> This requirement sounds very general; can you be more precise on it?
>
> After reset you have no RAM, no stack, no BSS, no writable data
> segment, etc. etc. When starting from some other code, conditions may
> be different.

On orion5x the DRAM controller can be fully reinitialized, and I suspect 
it is not the only one which can do this.

>> Now, for arm926ejs, it so happens that prior to Heiko's relocation
>> patches, u-boot's startup code *was* position-independent, and is not
>> any more, but that making init_sequence (and other data read during
>> startup) onst makes it p-i again.
>
> OK.
>
>>> I lost you.  If you put the U-Boot image at an arbitrary location in
>>> flash, the CPU will not start it because the CPU begins execution at
>>> the reset vector.
>>
>> You're mistaking "putting the image anywhere in FLASH" and "putting
>> _start anywhere in FLASH".
>
> _start is integral part of the U-Boot image...

I did not sayt it wasn't -- but this point shall be better understood 
when I publish my patch above Heiko's code, with consts added where due.

>>>> As for the half-hour of effort, the half-hour part is an assumption
>>>> which would need supporting, and even if it is only half an hour, it is
>>>> half an hours for each person configuring u-boot for arm; a burden that
>>>
>>> No. Only for those who have a system with such a reset vector
>>> location,
>>
>> That is, all people using orion5x for instance.
>>
>>> and I seriously doubt that any of these changes to the
>>> linker script have to be board specific.
>>
>> I did not say board-specific, I said config-specific.
>
> It does not depend on board configuration or such. It depends only on
> your system's memory map (location of the reset vector), and this is
> constant - for example - for all orion5x boards.

Reminder: here we're talking about fitting a >64 KB u-boot in flash, 
with _start at the reset vector (0xffff0000 on orion5x), without wasting 
the space above the reset vector (64 KB on orion5x) and with minimal 
waste in the rest of the mapping.

You suggested tweaking the linker file to manually place the _start 
symbol at the reset location, and then bin-pack the rest of the code -- 
some of which will have to go above _start, some below. This can only be 
achieved by defining 'MEMORY' regions in the linker file, and then you 
have to decide what sections go in the top region with the start.o .text 
section, and define another region big enough for what's left. And then, 
if you add or remove a configuration option, you section sizes will 
either grow or shrink; you risk a 'region full' link failure or a hole 
growing in the mapping, so you have to do it all over again.

This is why I say that the proposed solution of manually tweaking the 
linker file is sensitive to configuration changes.

>> Only for a given u-boot configuration. Change it, and that changes the
>> image content, thus the mapping, and you've got to fix _start again.
>
> Why should I?

Your change may overfill one of the 'MEMORY' regions that would have to 
be defined to get _start mapped to the reset vector location. 
Personally, I hate it when I enable some configuration option and it 
results in a link-time mapping error.

>  Did you not state that the reset vector is at a fixed
> location? Then we can use constant data (comon to all board
> configurations) to fill the gap between there and end of physical
> memory space.

That will not fill it properly and consistently unless that constant 
data is 1) really constant across all configuration option choices for 
all boards and 2) nicely filling the gap up to 64 KB.

> Best regards,
>
> Wolfgang Denk

As I said, I have a solution for my problem which puts _start at the 
reset vector location without changing the linker file at all, and with 
little, contained and controlled changes to the start.S file. I will 
post this as a [PATCH][NEXT] ([RFC] also if you will), clearly exposing 
the issue it addresses and the solution it uses, and we can discuss its 
merit then.

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-17 16:39                     ` Albert ARIBAUD
@ 2010-09-17 19:04                       ` Wolfgang Denk
  2010-09-17 22:19                         ` Albert ARIBAUD
  0 siblings, 1 reply; 25+ messages in thread
From: Wolfgang Denk @ 2010-09-17 19:04 UTC (permalink / raw)
  To: u-boot

Dear Albert ARIBAUD,

In message <4C9399A7.5020006@free.fr> you wrote:
>
> Depends on the processor I guess; but still, my point is that "start at 
> any location" does not require that you detect whether you are fresh out 
> of reset or not.

OK. I've repeated that often enough now, I will not iterate over this
any longer.

> Reminder: here we're talking about fitting a >64 KB u-boot in flash, 
> with _start at the reset vector (0xffff0000 on orion5x), without wasting 
> the space above the reset vector (64 KB on orion5x) and with minimal 
> waste in the rest of the mapping.

We do similar things on several boards to align the environment with
special, small flash sectors that happen to lie in the middle of the
image.

Your case is the same  - you would align the _start such that it is
located right in the middle of the image: not on a specific flash
sector, but at the reset vector.

> You suggested tweaking the linker file to manually place the _start 
> symbol at the reset location, and then bin-pack the rest of the code -- 
> some of which will have to go above _start, some below. This can only be 
> achieved by defining 'MEMORY' regions in the linker file, and then you 

This is not needed.

> This is why I say that the proposed solution of manually tweaking the 
> linker file is sensitive to configuration changes.

Yes, it is. I do not deny that. But this is not a real problem. If
the configuration grows such that you need an additional flash
sector, you will have to adjust TEXT_BASE.  This does not happen
frequently.

> >> Only for a given u-boot configuration. Change it, and that changes the
> >> image content, thus the mapping, and you've got to fix _start again.
> >
> > Why should I?
> 
> Your change may overfill one of the 'MEMORY' regions that would have to 
> be defined to get _start mapped to the reset vector location. 
> Personally, I hate it when I enable some configuration option and it 
> results in a link-time mapping error.

The "upper part", for reset vector to end of address space, would
never change.

> > location? Then we can use constant data (comon to all board
> > configurations) to fill the gap between there and end of physical
> > memory space.
> 
> That will not fill it properly and consistently unless that constant 
> data is 1) really constant across all configuration option choices for 
> all boards and 2) nicely filling the gap up to 64 KB.

See for example the TQM860L board configuration - it uses an embedded
flash sector, with manual tweaking in the linker script.

u-boot.map for this board shows:

...
 arch/powerpc/lib/cache.o(.text)
 .text          0x40007c20       0x64 arch/powerpc/lib/cache.o
                0x40007c20                flush_cache
                0x00008000                . = DEFINED (env_offset)?env_offset:.
 *fill*         0x40007c84      0x37c 00
 common/env_embedded.o(.ppcenv)
 .ppcenv        0x40008000     0x8000 common/env_embedded.o
                0x40008000                environment
                0x4000c000                redundand_environment
 *(.text)
 .text          0x40010000        0x4 common/env_embedded.o
                0x40010000                env_size
 .text          0x40010004        0x0 lib/libgeneric.a(ctype.o)
...

So we are "wasting" 0x37c = 892 bytes of memory for an unused gap.
The last changes where the object placing had to be changed due to
code size etc. were commit 32482be6 (Feb 19, 2009), and before that
fe57bb19 (Sep 18, 2002). Having to tweak this file every 7 years or
so is something I'm considering to be acceptable.  YMMV...


> As I said, I have a solution for my problem which puts _start at the 
> reset vector location without changing the linker file at all, and with 
> little, contained and controlled changes to the start.S file. I will 
> post this as a [PATCH][NEXT] ([RFC] also if you will), clearly exposing 
> the issue it addresses and the solution it uses, and we can discuss its 
> merit then.

I'm looking forward to seeing your patches.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Calm down, it's *__only* ones and zeroes.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-17 19:04                       ` Wolfgang Denk
@ 2010-09-17 22:19                         ` Albert ARIBAUD
  2010-09-17 22:42                           ` Wolfgang Denk
  0 siblings, 1 reply; 25+ messages in thread
From: Albert ARIBAUD @ 2010-09-17 22:19 UTC (permalink / raw)
  To: u-boot

Le 17/09/2010 21:04, Wolfgang Denk a ?crit :
> Dear Albert ARIBAUD,

>> Reminder: here we're talking about fitting a>64 KB u-boot in flash,
>> with _start at the reset vector (0xffff0000 on orion5x), without wasting
>> the space above the reset vector (64 KB on orion5x) and with minimal
>> waste in the rest of the mapping.
>
> We do similar things on several boards to align the environment with
> special, small flash sectors that happen to lie in the middle of the
> image.
>
> Your case is the same  - you would align the _start such that it is
> located right in the middle of the image: not on a specific flash
> sector, but at the reset vector.
>
>> You suggested tweaking the linker file to manually place the _start
>> symbol at the reset location, and then bin-pack the rest of the code --
>> some of which will have to go above _start, some below. This can only be
>> achieved by defining 'MEMORY' regions in the linker file, and then you
>
> This is not needed.

This is the only way to *ensure* a symbol ends up linked at a given 
address. Methods based on  -- at least the only one that isn't utterly 
sensitive to any change in the configuration.

>> This is why I say that the proposed solution of manually tweaking the
>> linker file is sensitive to configuration changes.
>
> Yes, it is. I do not deny that. But this is not a real problem. If
> the configuration grows such that you need an additional flash
> sector, you will have to adjust TEXT_BASE.  This does not happen
> frequently.
>
>>>> Only for a given u-boot configuration. Change it, and that changes the
>>>> image content, thus the mapping, and you've got to fix _start again.
>>>
>>> Why should I?
>>
>> Your change may overfill one of the 'MEMORY' regions that would have to
>> be defined to get _start mapped to the reset vector location.
>> Personally, I hate it when I enable some configuration option and it
>> results in a link-time mapping error.
>
> The "upper part", for reset vector to end of address space, would
> never change.

This is a bold assumption to make, and hard to prove, I think.

>>> location? Then we can use constant data (comon to all board
>>> configurations) to fill the gap between there and end of physical
>>> memory space.
>>
>> That will not fill it properly and consistently unless that constant
>> data is 1) really constant across all configuration option choices for
>> all boards and 2) nicely filling the gap up to 64 KB.
>
> See for example the TQM860L board configuration - it uses an embedded
> flash sector, with manual tweaking in the linker script.

You mean the one in which the comment about hand-optimizing ends with 
"XXX FIXME XXX" ? :)

I fail to see that it is an example of setting _start at a specific 
location within the image: it sets it at the first location of .text 
always. My problem is being able flash an image bigger than 64 KB while 
getting _start to end up flashed at 0xffff0000, which means putting 
_start somewhere in the middle of the .text section (which this ld trick 
does not help do)... or use the solution I posted (see below).

> u-boot.map for this board shows:
>
> ...
>   arch/powerpc/lib/cache.o(.text)
>   .text          0x40007c20       0x64 arch/powerpc/lib/cache.o
>                  0x40007c20                flush_cache
>                  0x00008000                . = DEFINED (env_offset)?env_offset:.
>   *fill*         0x40007c84      0x37c 00
>   common/env_embedded.o(.ppcenv)
>   .ppcenv        0x40008000     0x8000 common/env_embedded.o
>                  0x40008000                environment
>                  0x4000c000                redundand_environment
>   *(.text)
>   .text          0x40010000        0x4 common/env_embedded.o
>                  0x40010000                env_size
>   .text          0x40010004        0x0 lib/libgeneric.a(ctype.o)
> ...
>
> So we are "wasting" 0x37c = 892 bytes of memory for an unused gap.
> The last changes where the object placing had to be changed due to
> code size etc. were commit 32482be6 (Feb 19, 2009), and before that
> fe57bb19 (Sep 18, 2002). Having to tweak this file every 7 years or
> so is something I'm considering to be acceptable.  YMMV...

This is a simple alignment. I do not need to align code, I need to map 
*one* symbol, namely _start, at a given location, here 0xffff0000, so 
that the 64 KB sector which contains start is not wasted and the image 
resides in as few sectors as possible.

>> As I said, I have a solution for my problem which puts _start at the
>> reset vector location without changing the linker file at all, and with
>> little, contained and controlled changes to the start.S file. I will
>> post this as a [PATCH][NEXT] ([RFC] also if you will), clearly exposing
>> the issue it addresses and the solution it uses, and we can discuss its
>> merit then.
>
> I'm looking forward to seeing your patches.

I am finishing it for next, but you can already see the version for 
master I'd posted, and then withdrawn only because I wanted to rewrite 
it above Heiko's patches. It is at 
http://www.mail-archive.com/u-boot at lists.denx.de/msg37952.html, and 
there is a large comment to explain how it works. As indicated, it has 
been tested for all functional cases.

Note that the new version will slightly differ in the order of the 
copies, so as to minimize register usage.

> Best regards,
>
> Wolfgang Denk

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-17 22:19                         ` Albert ARIBAUD
@ 2010-09-17 22:42                           ` Wolfgang Denk
  2010-09-17 23:25                             ` Albert ARIBAUD
  0 siblings, 1 reply; 25+ messages in thread
From: Wolfgang Denk @ 2010-09-17 22:42 UTC (permalink / raw)
  To: u-boot

Dear Albert ARIBAUD,

In message <4C93E978.9010508@free.fr> you wrote:
>
> > u-boot.map for this board shows:
> >
> > ...
> >   arch/powerpc/lib/cache.o(.text)
> >   .text          0x40007c20       0x64 arch/powerpc/lib/cache.o
> >                  0x40007c20                flush_cache
> >                  0x00008000                . = DEFINED (env_offset)?env_offset:.
> >   *fill*         0x40007c84      0x37c 00
> >   common/env_embedded.o(.ppcenv)
> >   .ppcenv        0x40008000     0x8000 common/env_embedded.o
> >                  0x40008000                environment
> >                  0x4000c000                redundand_environment
> >   *(.text)
> >   .text          0x40010000        0x4 common/env_embedded.o
> >                  0x40010000                env_size
> >   .text          0x40010004        0x0 lib/libgeneric.a(ctype.o)
> > ...
> >
> > So we are "wasting" 0x37c = 892 bytes of memory for an unused gap.
> > The last changes where the object placing had to be changed due to
> > code size etc. were commit 32482be6 (Feb 19, 2009), and before that
> > fe57bb19 (Sep 18, 2002). Having to tweak this file every 7 years or
> > so is something I'm considering to be acceptable.  YMMV...
> 
> This is a simple alignment. I do not need to align code, I need to map 
> *one* symbol, namely _start, at a given location, here 0xffff0000, so 
> that the 64 KB sector which contains start is not wasted and the image 
> resides in as few sectors as possible.

And I map *one* symbol, namely environment, at a given location, here
0x40008000.

It seems you are not willing or trying or able to understand. I give
up here.


Viele Gr??e,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
When in doubt, mumble;   when in trouble, delegate;  when in  charge,
ponder.                                             -- James H. Boren

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [U-Boot] [PATCH 12/26] ARM: add relocation support
  2010-09-17 22:42                           ` Wolfgang Denk
@ 2010-09-17 23:25                             ` Albert ARIBAUD
  0 siblings, 0 replies; 25+ messages in thread
From: Albert ARIBAUD @ 2010-09-17 23:25 UTC (permalink / raw)
  To: u-boot

Le 18/09/2010 00:42, Wolfgang Denk a ?crit :
> Dear Albert ARIBAUD,
>
> In message<4C93E978.9010508@free.fr>  you wrote:
>>
>>> u-boot.map for this board shows:
>>>
>>> ...
>>>    arch/powerpc/lib/cache.o(.text)
>>>    .text          0x40007c20       0x64 arch/powerpc/lib/cache.o
>>>                   0x40007c20                flush_cache
>>>                   0x00008000                . = DEFINED (env_offset)?env_offset:.
>>>    *fill*         0x40007c84      0x37c 00
>>>    common/env_embedded.o(.ppcenv)
>>>    .ppcenv        0x40008000     0x8000 common/env_embedded.o
>>>                   0x40008000                environment
>>>                   0x4000c000                redundand_environment
>>>    *(.text)
>>>    .text          0x40010000        0x4 common/env_embedded.o
>>>                   0x40010000                env_size
>>>    .text          0x40010004        0x0 lib/libgeneric.a(ctype.o)
>>> ...
>>>
>>> So we are "wasting" 0x37c = 892 bytes of memory for an unused gap.
>>> The last changes where the object placing had to be changed due to
>>> code size etc. were commit 32482be6 (Feb 19, 2009), and before that
>>> fe57bb19 (Sep 18, 2002). Having to tweak this file every 7 years or
>>> so is something I'm considering to be acceptable.  YMMV...
>>
>> This is a simple alignment. I do not need to align code, I need to map
>> *one* symbol, namely _start, at a given location, here 0xffff0000, so
>> that the 64 KB sector which contains start is not wasted and the image
>> resides in as few sectors as possible.
>
> And I map *one* symbol, namely environment, at a given location, here
> 0x40008000.
>
> It seems you are not willing or trying or able to understand. I give
> up here.

I *am* willing to understand, and *able* I think too; I believe I never 
expressed any doubt on your own will or ability to understand, and I 
would appreciate if you kept your doubts about me to yourself.

I still fail to see a mapping of _start at a given here, at least I fail 
to see a manual action to get there. Are we both talking about the 
boards/tqc/tqm8xx/u-boot.lds linker file? If so, then it places _start 
right at the beginning of the .text section (line 58 of the linker file) 
-- just like all linker files I saw so far -- and does the alignment 
trick on the location pointer later, at line 67, which aligns the 
location of env_embedded, not of _start.

Maybe the intent was to move env_embedded out of the sector where 
start.o et al. are put; but then, that is not what I am look for. I do 
not want to isolate _start within a given sector; I want to make sure it 
gets flashed at a given location, where it cannot end up if it was 
mapped at the beginning of the iagem, because the image is bigger than 
the space from the reset vector location to the end of the addressable 
space.

> Viele Gr??e,
>
> Wolfgang Denk

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2010-09-17 23:25 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-11 18:16 [U-Boot] [PATCH 12/26] ARM: add relocation support Heiko Schocher
2010-09-15 21:06 ` Albert ARIBAUD
2010-09-16  5:09   ` Heiko Schocher
2010-09-16 10:50     ` Albert ARIBAUD
2010-09-16 11:29       ` Wolfgang Denk
2010-09-16 20:20         ` Albert ARIBAUD
2010-09-16 21:26           ` Wolfgang Denk
2010-09-17  6:16             ` Albert ARIBAUD
2010-09-17 11:05               ` Wolfgang Denk
2010-09-17 12:58                 ` Albert ARIBAUD
2010-09-17 14:52                   ` Wolfgang Denk
2010-09-17 16:39                     ` Albert ARIBAUD
2010-09-17 19:04                       ` Wolfgang Denk
2010-09-17 22:19                         ` Albert ARIBAUD
2010-09-17 22:42                           ` Wolfgang Denk
2010-09-17 23:25                             ` Albert ARIBAUD
2010-09-16  6:23   ` Alessandro Rubini
2010-09-16  7:06     ` Wolfgang Denk
2010-09-16  7:18       ` Graeme Russ
2010-09-16  8:23         ` Wolfgang Denk
2010-09-16  9:54           ` Graeme Russ
2010-09-16 10:18             ` Wolfgang Wegner
2010-09-16 10:49               ` Albert ARIBAUD
2010-09-16 11:06               ` Wolfgang Denk
2010-09-16 11:24                 ` Wolfgang Wegner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.