From mboxrd@z Thu Jan 1 00:00:00 1970 From: Albert ARIBAUD Date: Sat, 02 Oct 2010 10:26:01 +0200 Subject: [U-Boot] ARM relocation, question to Heiko In-Reply-To: <4CA6E8E5.2090605@emk-elektronik.de> References: <4CA49746.2050301@emk-elektronik.de> <4CA4AEFF.3050101@denx.de> <20100930174308.070ECD2B48C@gemini.denx.de> <4CA570D3.9040406@denx.de> <4CA57468.6090702@free.fr> <4CA57762.3000201@denx.de> <4CA5821E.3070108@emk-elektronik.de> <4CA5873B.6040907@free.fr> <4CA590E6.6070701@emk-elektronik.de> <4CA59B89.6090207@denx.de> <4CA5BB7A.8050304@emk-elektronik.de> <20101001105506.A64D41539A0@gemini.denx.de> <4CA5BFEF.3090208@emk-elektronik.de> <20101001112125.4076E153A7E@gemini.denx.de> <4CA5C7DE.6010300@emk-elektronik.de> <20101001115908.A34411539A0@gemini.denx.de> <4CA5D26D.2090505@emk-elektronik.de> <4CA5D857.5010009@emk-elektronik.de> <20101001125502.D0B4E1539A0@gemini.denx.de> <4CA6DC16.5040409@emk-elektronik.de> <4CA6E517.9040701@free.fr> <4CA6E8E5.2090605@emk-elektronik.de> Message-ID: <4CA6EC99.5080204@free.fr> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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.