Skip to contentSkip to conversation

ARM: add relocation support

PATCH New Heiko Schocher 6 participants 25 messages Aug 11, 2010 – Sep 17, 2010 Arm (32-bit)

lore
Share & tools
lore
#0 lore raw

PATCH 12/26 ARM: add relocation support

!! 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

---
- 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
arch/arm/config.mk +8 -0
index e10dafc..6923f6d 100644
@@ -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:
arch/arm/include/asm/config.h +2 -1
index b76fd8e..4e8dfd7 100644
@@ -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
arch/arm/include/asm/global_data.h +11 -0
index 02cfe45..488bae7 100644
@@ -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;
 
arch/arm/include/asm/u-boot-arm.h +13 -1
index 6d2f8bc..faf800a 100644
@@ -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);
 
arch/arm/lib/board.c +467 -1

505 lines not on this page · raw message

arch/arm/lib/cache-cp15.c +34 -3
index b2811f3..fe6d459 100644
@@ -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);
arch/arm/lib/interrupts.c +18 -1
index 1f2b815..9a21e7b 100644
@@ -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;
common/cmd_bdinfo.c +10 -1
index cc81543..4c3040a 100644
@@ -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;
 }
 
common/cmd_bmp.c +6 -0
index d51cc55..6fa8a15 100644
@@ -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
  *
common/cmd_i2c.c +6 -0
index 5e9135e..48de54b 100644
@@ -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;
doc/README.arm-relocation new file +321 -0

321 lines not on this page · raw message

nand_spl/nand_boot.c +7 -0
index b9fd6f5..18ecbe1 100644
@@ -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
nand_spl/nand_boot_fsl_nfc.c +7 -0
index ea3566b..3105657 100644
@@ -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
Signature · 5 lines
1.6.2.5

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

PATCH 12/26 ARM: add relocation support

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

arch/arm/lib/board.c extern void davinci_eth_set_mac_addr (const u_int8_t *addr); · line 469

Quoted 6 lines
arch/arm/lib/board.c +1 -0
index 54519b0..88c6427 100644
 
+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,

Signature · 1 line
Albert.
#2 lore raw

PATCH 12/26 ARM: add relocation support

Hello Albert,

Quoted 7 lines · Albert ARIBAUD

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

Quoted 4 lines
arch/arm/lib/board.c +0 -0
index 54519b0..88c6427 100644
Quoted 6 lines
Quoted 1 line

+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 ...

Quoted 2 lines

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

bye
Heiko

Signature · 2 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#3 lore raw

PATCH 12/26 ARM: add relocation support

Hello Heiko.

Quoted 2 lines

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

#4 lore raw

PATCH 12/26 ARM: add relocation support

Dear Alessandro Rubini,

Quoted 5 lines · In message <[email protected]> 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.

Quoted 2 lines

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.

Quoted 3 lines

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

Signature · 5 lines
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_
#5 lore raw

PATCH 12/26 ARM: add relocation support

Quoted 6 lines · Wolfgang Denk

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.

Quoted 2 lines

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

#6 lore raw

PATCH 12/26 ARM: add relocation support

Dear Graeme Russ,

Quoted 9 lines · In message <[email protected]> you…
Quoted 5 lines

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.

Quoted 4 lines

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.

Quoted 2 lines

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

Signature · 5 lines
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
#7 lore raw

PATCH 12/26 ARM: add relocation support

Quoted 16 lines · Wolfgang Denk

Dear Graeme Russ,

Quoted 9 lines · In message <[email protected]> you…
Quoted 5 lines

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.

Quoted 8 lines

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.

Quoted 8 lines
Quoted 5 lines

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

Quoted 3 lines

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

Quoted 6 lines
Quoted 3 lines

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

#8 lore raw

PATCH 12/26 ARM: add relocation support

On Thu, Sep 16, 2010 at 07:54:03PM +1000, Graeme Russ wrote:
[...]

Quoted 2 lines

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

[...]

Quoted 5 lines

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.

Quoted 2 lines

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

#9 lore raw

PATCH 12/26 ARM: add relocation support

Le 16/09/2010 12:18, Wolfgang Wegner a ?crit :

Quoted 19 lines · Graeme Russ

[...]

Quoted 2 lines

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

[...]

Quoted 5 lines

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.

Quoted 8 lines
Quoted 2 lines

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,

Signature · 1 line
Albert.
#10 lore raw

PATCH 12/26 ARM: add relocation support

In reply to Wolfgang Wegner

Dear Wolfgang Wegner,

Quoted 3 lines · In message <[email protected]> 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.

Quoted 5 lines

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.

Quoted 5 lines

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

Signature · 6 lines
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.
#11 lore raw

PATCH 12/26 ARM: add relocation support

Dear Wolfgang Denk,

Quoted 3 lines · Wolfgang Denk

Dear Wolfgang Wegner,

In message <[email protected]> you wrote:

[...]

Quoted 8 lines
Quoted 5 lines

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".

Quoted 8 lines
Quoted 5 lines

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

#12 lore raw

PATCH 12/26 ARM: add relocation support

In reply to Heiko Schocher

Le 16/09/2010 07:09, Heiko Schocher a ?crit :

Quoted 12 lines

Hello Albert,

Quoted 9 lines · Albert ARIBAUD

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

Quoted 6 lines
arch/arm/lib/board.c +1 -0
index 54519b0..88c6427 100644
 
+init_fnc_t *init_sequence[] = {
Quoted 8 lines
Quoted 4 lines

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,

Signature · 1 line
Albert.
#13 lore raw

PATCH 12/26 ARM: add relocation support

Dear Albert ARIBAUD,

Quoted 3 lines · In message <[email protected]> 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.]

Quoted 3 lines

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.]

Quoted 8 lines

(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.

Quoted 5 lines

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.

Quoted 3 lines

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?

Quoted 5 lines

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.

Quoted 4 lines

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.

Quoted 4 lines

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?

Quoted 3 lines

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.

Quoted 4 lines

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

Signature · 6 lines
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
#14 lore raw

PATCH 12/26 ARM: add relocation support

Le 16/09/2010 13:29, Wolfgang Denk a ?crit :

Quoted 11 lines

Dear Albert ARIBAUD,

Quoted 3 lines · In message<[email protected]> 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.

Quoted 3 lines

[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. :) ]

Quoted 21 lines
Quoted 3 lines

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.]

Quoted 8 lines

(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)

Quoted 4 lines

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.

Quoted 10 lines
Quoted 5 lines

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.

Quoted 6 lines
Quoted 3 lines

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. :)

Quoted 8 lines
Quoted 5 lines

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.

Quoted 2 lines

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

I will certainly.

Quoted 6 lines
Quoted 4 lines

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 (*).

Quoted 8 lines
Quoted 4 lines

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.

Quoted 8 lines
Quoted 3 lines

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.

Quoted 10 lines
Quoted 4 lines

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.

Quoted 3 lines

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,

Signature · 1 line
Albert.
#15 lore raw

PATCH 12/26 ARM: add relocation support

Dear Albert ARIBAUD,

Quoted 6 lines · In message <[email protected]> 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.

Quoted 4 lines

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.

Quoted 5 lines
Quoted 3 lines

[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.

Quoted 3 lines

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.

Quoted 8 lines

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.

Quoted 8 lines
Quoted 3 lines

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.

Quoted 4 lines

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...

Quoted 5 lines

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

Signature · 5 lines
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.
#16 lore raw

PATCH 12/26 ARM: add relocation support

Le 16/09/2010 23:26, Wolfgang Denk a ?crit :

Quoted 4 lines

Dear Albert ARIBAUD,

Quoted 1 line · In message<[email protected]> you wrote:
Quoted 8 lines
Quoted 5 lines

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.

Quoted 7 lines
Quoted 4 lines

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.

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

[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.

Quoted 5 lines
Quoted 3 lines

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.

Quoted 9 lines
Quoted 8 lines

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.

Quoted 6 lines

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.

Quoted 9 lines
Quoted 8 lines
Quoted 3 lines

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.

Quoted 8 lines

This is indeed broken and needs to be fixed.

Quoted 4 lines

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. :)

Quoted 11 lines
Quoted 5 lines

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,

Signature · 1 line
Albert.
#17 lore raw

PATCH 12/26 ARM: add relocation support

Dear Albert ARIBAUD,

Quoted 5 lines · In message <[email protected]> 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.

Quoted 9 lines
Quoted 5 lines
Quoted 3 lines

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?

Quoted 8 lines
Quoted 6 lines

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.

Quoted 5 lines

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.

Quoted 3 lines

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.

Quoted 5 lines

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.

Quoted 5 lines

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

Signature · 6 lines
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
#18 lore raw

PATCH 12/26 ARM: add relocation support

Le 17/09/2010 13:05, Wolfgang Denk a ?crit :

Quoted 10 lines

Dear Albert ARIBAUD,

Quoted 5 lines · In message<[email protected]> 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. :)

Quoted 7 lines

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.

Quoted 6 lines

- 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.

Quoted 2 lines

- 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?

Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 3 lines

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.

Quoted 8 lines
Quoted 3 lines

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.

Quoted 10 lines
Quoted 8 lines
Quoted 6 lines

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.

Quoted 9 lines
Quoted 5 lines

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".

Quoted 6 lines
Quoted 3 lines

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.

Quoted 2 lines

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.

Quoted 4 lines

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.

Quoted 11 lines
Quoted 5 lines

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.

Quoted 10 lines
Quoted 5 lines

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.

Quoted 5 lines

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?

Quoted 3 lines

Best regards,

Wolfgang Denk

Amicalement,

Signature · 1 line
Albert.
#19 lore raw

PATCH 12/26 ARM: add relocation support

Dear Albert ARIBAUD,

Quoted 10 lines · In message <[email protected]> you wrote:
Quoted 7 lines

- 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.

Quoted 3 lines

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".

Quoted 4 lines
Quoted 2 lines

- 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.

Quoted 4 lines

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.

Quoted 6 lines
Quoted 3 lines

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...

Quoted 7 lines
Quoted 6 lines
Quoted 3 lines

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,

Quoted 6 lines

That is, all people using orion5x for instance.

Quoted 2 lines

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.

Quoted 2 lines

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

Signature · 5 lines
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?
#20 lore raw

PATCH 12/26 ARM: add relocation support

Le 17/09/2010 16:52, Wolfgang Denk a ?crit :

Quoted 11 lines

Dear Albert ARIBAUD,

Quoted 8 lines · In message<[email protected]> you wrote:
Quoted 7 lines

- 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.

Quoted 5 lines
Quoted 2 lines

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.

Quoted 2 lines

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

Possibly. So what?

Quoted 3 lines

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".

Quoted 3 lines

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.

Quoted 5 lines
Quoted 3 lines

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.

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

- 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.

Quoted 7 lines
Quoted 4 lines

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.

Quoted 8 lines
Quoted 6 lines
Quoted 3 lines

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.

Quoted 9 lines
Quoted 9 lines
Quoted 6 lines
Quoted 3 lines

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.

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

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.

Quoted 4 lines
Quoted 2 lines

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.

Quoted 4 lines

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.

Quoted 3 lines

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,

Signature · 1 line
Albert.
#21 lore raw

PATCH 12/26 ARM: add relocation support

Dear Albert ARIBAUD,

Quoted 4 lines · In message <[email protected]> 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.

Quoted 4 lines

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.

Quoted 4 lines

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.

Quoted 2 lines

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.

Quoted 9 lines
Quoted 4 lines
Quoted 2 lines

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.

Quoted 7 lines
Quoted 3 lines

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...

Quoted 6 lines

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

Signature · 4 lines
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.
#22 lore raw

PATCH 12/26 ARM: add relocation support

Le 17/09/2010 21:04, Wolfgang Denk a ?crit :

Quoted 15 lines

Dear Albert ARIBAUD,

Quoted 4 lines

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.

Quoted 6 lines
Quoted 4 lines

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.

Quoted 13 lines
Quoted 2 lines

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.

Quoted 5 lines
Quoted 4 lines
Quoted 2 lines

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?

Quoted 7 lines
Quoted 4 lines

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.

Quoted 10 lines
Quoted 7 lines
Quoted 3 lines

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).

Quoted 15 lines

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
Quoted 8 lines

.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.

Quoted 8 lines
Quoted 6 lines

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.

Quoted 3 lines

Best regards,

Wolfgang Denk

Amicalement,

Signature · 1 line
Albert.
#23 lore raw

PATCH 12/26 ARM: add relocation support

Dear Albert ARIBAUD,

Quoted 25 lines · In message <[email protected]> you wrote:
Quoted 16 lines

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
Quoted 8 lines

.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...

Quoted 4 lines

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

Signature · 5 lines
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
#24 lore raw

PATCH 12/26 ARM: add relocation support

Le 18/09/2010 00:42, Wolfgang Denk a ?crit :

Quoted 33 lines

Dear Albert ARIBAUD,

Quoted 25 lines · In message<[email protected]> you wrote:
Quoted 16 lines

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
Quoted 8 lines

.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...

Quoted 4 lines

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.

Quoted 5 lines

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.

Quoted 3 lines

Viele Gr??e,

Wolfgang Denk

Amicalement,

Signature · 1 line
Albert.