
I ran the code you (Andreas) sent, with the one correction for the printf(). The code you sent did not set the test array pointer to 0x40000. When I use the code you _ment_ rather than what you _sent_ (see below - sorry for top-quoting), I get the same effect you get:
vanbaren@sherwood:~/x> ./arrtest *test: 0x08048558 test[]: 0x08048558
vanbaren@sherwood:~/x> ./arrtest-ptr *test: 0x00040000 test[]: 0x08048558
I think I now understand the root of your problem. You want to place an initialized array at a specific location. C has a way of initializing arrays: const unsigned char test[] = { value... }; and a way of making a pointer to an array: const unsigned char *test = (unsigned char*)0x40000; but it doesn't have a way to do _both_ at the same time. You are trying to avoid the need for two initializations in one declaration limitation by doing it _differently_ in _two_ different places. This is confusing the compiler and/or the linker.
I would guess this is a compiler/linker interaction that could be labeled unfortunate lack of communications or a bug, depending on your frustration level for the day.
I would contend that the "proper" solution is to declare the array consistantly and with data initialization in common.h: #ifdef EXTERN EXTERN const unsigned char test[]; #else const unsigned char test[] = { 0, 1, 2 }; #endif (with EXTERN #defined to be extern in exactly one file, in your example it would be #defined in array.c -- see attached) and then use the linker control file to place the resulting array in the proper location (you may need a new section and place "test" in the new section).
I cannot claim expertise in the area, but it looks to me that the problem has nothing to do with u-boot relocation per se. It is a language/compiler/linker issue.
You still may have to resolve relocation issues, depending on where you locate the resulting array data and whether it gets copied and whether it is available in the ROM location, but that is a red herring at this point.
gvb
Andreas Block wrote:
I'm not quite sure, what happened on your side. Here's the result on my side (together with the source as it ought look):
--- BEGIN OF CONSOLE OUTPUT andreas@pc-linux-dev:~/arrtest> cat common.h int showwrong(void);
andreas@pc-linux-dev:~/arrtest> cat common.c #include <stdio.h>
extern const unsigned char test[];
int showwrong(void) { printf("test[]: 0x%08X\n", (int)test); return 0; }
andreas@pc-linux-dev:~/arrtest> cat array.c #include "common.h"
const unsigned char *test = (unsigned char*)0x40000;
int main(void) { printf("*test: 0x%08X\n", (int)test); showwrong(); return 0; } andreas@pc-linux-dev:~/arrtest> gcc -o arrtest -I ./ ./common.c ./array.c andreas@pc-linux-dev:~/arrtest> ./arrtest *test: 0x00040000 test[]: 0x080494E4 --- END OF CONSOLE OUTPUT
What buffles me is, that on your side, the *test-output isn't 0x40000, because the pointer is initialized directly in that object and used as pointer. And on the other hand, the output can't be the same: extern char test[]; ==> results in a symbol at the start address of the array. char *test; ==> is a pointer containing the start-address of the array. This means one more level of reference.
Could you please show your source files as they were used for your test to us. I'm still sure, both notations are not the same, although they work the same in most cases.
Regards, Andreas
30.06.2005 19:28:32, Jerry Van Baren gerald.vanbaren@smiths-aerospace.com wrote:
Rune Torgersen wrote:
Wow.... This surprises me... I have alwayts thought that *test and test[] would be the same thing.
Only solutionI can see is to change the definition in common.c to be *test, this will still get the address of test[] defined elsewhere. (See attached files)
Sure, I've tried this. This is the point, where my problem arose. Attached you find two small files, you can easily compile under linux (gcc -o arrtest -I ./ ./common.c ./array.c). The file "common.c" represents the code I can't (don't want to) touch. "array.c" represents my project dependent code. If you run arrtest it will show to you,
With the patch in place (previously sent to the list), it works for linux:
vanbaren@sherwood:~/x> ll total 32 -rwxr----- 1 vanbaren users 200 Jun 30 13:24 array.c -rwxr-xr-x 1 vanbaren users 8963 Jun 30 13:26 arrtest -rwxr----- 1 vanbaren users 132 Jun 30 08:03 common.c -rwxr----- 1 vanbaren users 121 Jun 30 08:03 common.c-original -rw-r--r-- 1 vanbaren users 237 Jun 30 08:04 common.c.diff -rwxr----- 1 vanbaren users 24 Jun 30 13:23 common.h vanbaren@sherwood:~/x> gcc -o arrtest -I ./ ./common.c ./array.c vanbaren@sherwood:~/x> ./arrtest *test: 0x08048558 test[]: 0x08048558
gvb
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users
#ifdef BROKEN #ifdef BROKEN1 #ifdef EXTERN EXTERN const unsigned char test[]; #else const unsigned char *test = (unsigned char*)0x40000; #endif #endif /* BROKEN1 */
#ifdef BROKEN2 #ifdef EXTERN EXTERN const unsigned char *test; #else const unsigned char test[] = (unsigned char*)0x40000; #endif #endif /* BROKEN2 */
#else /* not BROKEN */
#ifdef EXTERN EXTERN const unsigned char test[]; #else const unsigned char test[] = { 0, 1, 2 }; #endif
#endif
int showwrong(void);
#include "stdio.h"
#define EXTERN extern #include "common.h"
int main(void) { printf("test: 0x%08X\n", (int)test); showwrong(); return 0; }
#include <stdio.h> #include "common.h"
int showwrong(void) { printf("test[]: 0x%08X\n", (int)test); return 0; }