[U-Boot-Users] simple_strtoul overwrites bd_info field

I'm experiencing the following problem when building U-Boot with GCC 4.0.0 provided by ELDK 4.0 ARM. My struct bd_info looks like this:
typedef struct bd_info { int bi_baudrate; /* serial console baudrate */ unsigned long bi_ip_addr; /* IP Address */ unsigned char bi_enetaddr[6]; /* Ethernet adress */ struct environment_s *bi_env; ulong bi_arch_number; /* unique id for this board */ ulong bi_boot_params; /* where this board expects params */ #if defined(CONFIG_ZEFEER_DZA) || defined(CONFIG_ZEFEER_DZB) || \ defined(CONFIG_ZEFEER_DZG) || defined(CONFIG_ZEFEER_DZN) || defined(CONFIG_ZEFEER_DZQ) struct /* RAM configuration */ { ulong start; ulong size; } bi_dram[CONFIG_MAX_NR_DRAM_BANKS]; unsigned char nr_dram_bank; #else struct /* RAM configuration */ { ulong start; ulong size; } bi_dram[CONFIG_NR_DRAM_BANKS]; #endif #ifdef CONFIG_HAS_ETH1 /* second onboard ethernet port */ unsigned char bi_enet1addr[6]; #endif } bd_t;
The SDRAM detection algorithm finds how many SDRAM blocks are and how big they are. It fills the following fields accordingly.
struct /* RAM configuration */ { ulong start; ulong size; } bi_dram[CONFIG_MAX_NR_DRAM_BANKS]; unsigned char nr_dram_bank;
When start_armboot invokes simple_strtoul to fill the bi_enetaddr field, the bi_dram[1].start field gets overwritten with a spurious value. Is it actually a GCC-related problem? Any suggestions?
TIA, llandre
DAVE Electronics System House - R&D Department web: http://www.dave-tech.it email: r&d2@dave-tech.it

In message 44F460ED.2070006@dave-tech.it you wrote:
I'm experiencing the following problem when building U-Boot with GCC 4.0.0 provided by ELDK 4.0 ARM.
Which board is this?
When start_armboot invokes simple_strtoul to fill the bi_enetaddr field, the bi_dram[1].start field gets overwritten with a spurious value. Is it actually a GCC-related problem? Any suggestions?
Check the assembler code (single step it under a debugger).
Best regards,
Wolfgang Denk

I'm experiencing the following problem when building U-Boot with GCC 4.0.0 provided by ELDK 4.0 ARM.
Which board is this?
Zefeer
Check the assembler code (single step it under a debugger).
This is the offending instruction in simple_strtoul: *endp = (char *)cp;
As endp points to one field of the struct bd_info, it gets corrupted. So the problem is about the pointer "e" in function start_armboot that is passed to simple_strtoul. Any idea?

In message 44F54522.4010608@dave-tech.it you wrote:
Check the assembler code (single step it under a debugger).
This is the offending instruction in simple_strtoul: *endp = (char *)cp;
As endp points to one field of the struct bd_info, it gets corrupted. So
Umm.. it should not. endp is the second art when calling simple_strtoul(), and "lib_arm/board.c" passes the address of a local variable here.
the problem is about the pointer "e" in function start_armboot that is passed to simple_strtoul. Any idea?
Did you check which address gets passed to simple_strtoul()? Did you check the generated assembler code as I suggested? [Try "display/i $pc" followed by single-stepping using "si".]
Best regards,
Wolfgang Denk

As endp points to one field of the struct bd_info, it gets corrupted. So
Umm.. it should not. endp is the second art when calling simple_strtoul(), and "lib_arm/board.c" passes the address of a local variable here.
the problem is about the pointer "e" in function start_armboot that is passed to simple_strtoul. Any idea?
Did you check which address gets passed to simple_strtoul()?
Yes and ...
Did you check the generated assembler code as I suggested?
... yes. This is how I found out what happens. See the two dumps here http://www.dave-tech.it/download/misc/zefeer. Stuct bd_info starts at 0xD1EBFF3C.

Did you check which address gets passed to simple_strtoul()?
Yes and ...
Did you check the generated assembler code as I suggested?
... yes. This is how I found out what happens. See the two dumps here http://www.dave-tech.it/download/misc/zefeer. Stuct bd_info starts at 0xD1EBFF3C.
I tried to move the e pointer from start_armboot to the top of the file (static char *e;) and everything works fine.

In message 44F54E7A.7050105@dave-tech.it you wrote:
Did you check which address gets passed to simple_strtoul()?
Yes and ...
If I understand your screen shots correctly, then D1EBFF60 gets passed (in r1) as second argument to simple_strtoul(). Is this understanding correct? Did you verify that is this indeed the address of the local valiable "e"?
Did you check the generated assembler code as I suggested?
... yes. This is how I found out what happens. See the two dumps here http://www.dave-tech.it/download/misc/zefeer. Stuct bd_info starts at 0xD1EBFF3C.
In the second screen shot, the address D1EBFF22 gets used (in r14). Unfortunately your section does not allow to follow the code, i. e. how does the correct (?) content of r1 gets lost and/or changed into the wrong content of r14.
I can only repeat: check the code on assembler instuction level.
In message 44F551D6.7070904@dave-tech.it you wrote:
I tried to move the e pointer from start_armboot to the top of the file (static char *e;) and everything works fine.
This cannot be accepted as solution for the problem. I see absolutely no reason why the current code [cs]ould cause problems here.
Best regards,
Wolfgang Denk

In message 44F551D6.7070904@dave-tech.it you wrote:
I tried to move the e pointer from start_armboot to the top of the file (static char *e;) and everything works fine.
This cannot be accepted as solution for the problem.
Yes, I absolutely agree. I have just performed this attempt to verify that that problem referred to the allocation of variable e.
Anyway I found the bug. Since we had to add more fields for DRAM configuration in the struct bd_info (Ep93xx has complex DRAM mapping), its size increased up to 160 bytes and I just forgot to change CFG_GBL_DATA_SIZE accordingly.
Thanks and best regards, llandre
DAVE Electronics System House - R&D Department web: http://www.dave-tech.it email: r&d2@dave-tech.it

In message 44F6C4EE.1010605@dave-tech.it you wrote:
Anyway I found the bug. Since we had to add more fields for DRAM
Congrats!
configuration in the struct bd_info (Ep93xx has complex DRAM mapping), its size increased up to 160 bytes and I just forgot to change CFG_GBL_DATA_SIZE accordingly.
Ummm... are you absolutely sure that this information MUST be stored in the global data structure? It's size should be kept as small as possible!
Best regards,
Wolfgang Denk
participants (2)
-
llandre
-
Wolfgang Denk