Le 02/10/2010 10:10, Reinhard Meyer a écrit : > Dear Albert ARIBAUD, >>> I try to understand how the relocation process could handle pointers (to >>> functions or other data) in const or data sections. >>> Your code cannot know what is data and what is a pointer that needs >>> adjustment? >>> >>> Best Regards, >>> Reinhard >> >> Hi Reinhart, >> >> Short answer - the relocation process does not handle pointers inside >> data structures. >> >> And yes, this means the content arrays of pointers such as init_sequence >> is not relocated. Been there, done that, can give you one of the >> tee-shirts I got :) >> >> ATM I have not found a way to fix this, except making the code which >> uses the pointers aware that the are location-sensitive and fix them >> when using them. > > That means that things like this cannot work (with relocation), > unless adding the relocation offset before using the pointer: > > const struct { > const u8 shift; > const u8 idcode; > struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode); > } flashes[] = { > #ifdef CONFIG_SPI_FLASH_SPANSION > { 0, 0x01, spi_flash_probe_spansion, }, > #endif > #ifdef CONFIG_SPI_FLASH_ATMEL > { 0, 0x1F, spi_flash_probe_atmel, }, > #endif > #ifdef CONFIG_SPI_FLASH_MACRONIX > { 0, 0xc2, spi_flash_probe_macronix, }, > #endif > #ifdef CONFIG_SPI_FLASH_WINBOND > { 0, 0xef, spi_flash_probe_winbond, }, > #endif > #ifdef CONFIG_SPI_FLASH_STMICRO > { 0, 0x20, spi_flash_probe_stmicro, }, > { 0, 0xff, spi_flash_probe_stmicro, }, > #endif > #ifdef CONFIG_SPI_FLASH_SST > { 0, 0xBF, spi_flash_probe_sst, }, > #endif > #ifdef CONFIG_SPI_FRAM_RAMTRON > { 6, 0xc2, spi_fram_probe_ramtron, }, > # ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC > { 0, 0xff, spi_fram_probe_ramtron, }, > # endif > # undef IDBUF_LEN > # define IDBUF_LEN 9 /* we need to read 6+3 bytes */ > #endif > }; > > And I think there are more places of this type in u-boot... > > Best Regards, > Reinhard
If this code is intended to execute after relocation [1] then no, it will not work. There are two ways to fix that: The first one is to make the variable non-const and, after relocation but before use, run a fixup loop specifically for this variable. Then you can call the (now fixed) functions. The second one is to fix on-the-fly: provide a field in gd which contains the relocation offset in gd (if not done already); in the code which calls function pointers, DECLARE_GLOBAL_DATA_PTR and call the function through a global macro (defined in some general u-boot header), e.g. FIX_RELOCATED_FUNCTION_POINTER(fp), which would offset fp to its correct location. Thus in the code, instead of x = fp(args) you'd have x = FIX_RELOCATED_FUNCTION_POINTER(fp)(args). [1] or, in my case, before relocation but not from the location specified at link time. This is a slightly different issue, which the first solution fails to address but the second does. Amicalement, -- Albert. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot