[U-Boot] Help Request - Command parsing, find_cmd (), possible linker script problem

Hi All,
So far I have my sc520 board booting into main_loop (), DRAM configured and serial ports working. Now I seem to be stuck on getting commands to execute (even help). Using printf() I have traced my problem into find_cmd (). I added the following into find_cmd() just before the for loop:
printf ("Searching for Command '%s'\n", cmd); printf ("Command Table Start : %08lx\n", (ulong)&__u_boot_cmd_start); printf ("Command Table End : %08lx\n", (ulong)&__u_boot_cmd_end); printf ("sizeof(int) : %x\n", sizeof(int)); printf ("sizeof(cmd_tbl_t) : %x\n", sizeof(cmd_tbl_t));
and
printf ("Checking : %08lx\n", (ulong)cmdtp);
just inside the for loop
The output is (there are a few other printf()'s leadinf up to find_cmd () as well):
boot > help
[RUN_COMMAND] cmd[00400ccc]="help" [PROCESS_SEPARATORS] help token: "help"
Processing Macros... [PROCESS_MACROS] INPUT len 4: "help" [PROCESS_MACROS] OUTPUT len 4: "help" Extracting Arguments... parse_line: "help"
parse_line: nargs=1 Looking up Command... Searching for Command 'help' Command Table Start : 0000053e Command Table End : 00000870 sizeof(int) : 4 sizeof(cmd_tbl_t) : 18 Checking : 0000053e Checking : 00000556 Checking : 0000056e . . . Checking : 00000856 Checking : 0000086e Checking : 00000886 Checking : 0000089e Checking : 000008b6
There are a few weird things going on...
a) sizeof(cmd_tbl_t) is 18, but the loop is incrementing by 24 (I would have thought a 4 byte alignment would push it to 20 maybe)
b) The loop never completes since cmdtp never actually equals &__u_boot_cmd_end
c) The bootrom flash is mapped to 0x38000000. The flash is 512k with U-Boot image being 256k puts U-Boot at 0x38040000. I have adjusted TEXT_BASE = 0x38040000 in config.mk and adjusted u-boot.lds (see full u-boot.lds below) (for those that don't know the AMD sc520, the boot flash memory region can be 'mapped' to wherever you want it, and I have confirmed the mapping be dumping the address of the last_stage_init() function which resides at 0x38046d57 - right were I expect it). I would, therefore, expect the command table to live somewhere in 0x38040000 - 0x3807ffff
Can anyone point me an a rough direction to look? Any help at all would be greatly appreciated
Regards,
Graeme
u-boot.lds:
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) ENTRY(_start)
SECTIONS { . = 0x38040000; /* Where bootcode in the flash is mapped */ .text : { *(.text); }
. = ALIGN(4); .rodata : { *(.rodata) *(.rodata.str1.1) *(.rodata.str1.32) }
. = 0x400000; /* Ram data segment to use */ _i386boot_romdata_dest = ABSOLUTE(.); .data : AT ( LOADADDR(.rodata) + SIZEOF(.rodata) ) { *(.data) } _i386boot_romdata_start = LOADADDR(.data);
. = ALIGN(4); .got : AT ( LOADADDR(.data) + SIZEOF(.data) ) { *(.got) } _i386boot_romdata_size = SIZEOF(.data) + SIZEOF(.got);
. = ALIGN(4); _i386boot_bss_start = ABSOLUTE(.); .bss (NOLOAD) : { *(.bss) } _i386boot_bss_size = SIZEOF(.bss);
/* 16bit realmode trampoline code */ .realmode 0x7c0 : AT ( LOADADDR(.got) + SIZEOF(.got) ) { *(.realmode) }
_i386boot_realmode = LOADADDR(.realmode); _i386boot_realmode_size = SIZEOF(.realmode);
/* 16bit BIOS emulation code (just enough to boot Linux) */ .bios 0 : AT ( LOADADDR(.realmode) + SIZEOF(.realmode) ) { *(.bios) }
_i386boot_bios = LOADADDR(.bios); _i386boot_bios_size = SIZEOF(.bios);
. = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .;
/* The load addresses below assumes that the flash * will be mapped so that 0x387f0000 == 0xffff0000 * at reset time * * The fe00 and ff00 offsets of the start32 and start16 * segments are arbitrary, the just have to be mapped * at reset and the code have to fit. * The fff0 offset of reset is important, however. */
. = 0xfffffe00; .start32 : AT (0x3807fe00) { *(.start32); }
. = 0xf800; .start16 : AT (0x3807f800) { *(.start16); }
. = 0xfff0; .reset : AT (0x3807fff0) { *(.reset); } _i386boot_end = (LOADADDR(.reset) + SIZEOF(.reset) ); }

Graeme Russ wrote:
Hi All,
So far I have my sc520 board booting into main_loop (), DRAM configured and serial ports working. Now I seem to be stuck on getting commands to execute (even help). Using printf() I have traced my problem into find_cmd (). I added the following into find_cmd() just before the for loop:
printf ("Searching for Command '%s'\n", cmd); printf ("Command Table Start : %08lx\n", (ulong)&__u_boot_cmd_start); printf ("Command Table End : %08lx\n", (ulong)&__u_boot_cmd_end); printf ("sizeof(int) : %x\n", sizeof(int)); printf ("sizeof(cmd_tbl_t) : %x\n", sizeof(cmd_tbl_t));
Aaargh, you printed %x, not 0x%x. That really threw me on the printout of sizeof(cmd_tbl_t).
[snip]
The output is (there are a few other printf()'s leadinf up to find_cmd () as well):
boot > help
[RUN_COMMAND] cmd[00400ccc]="help" [PROCESS_SEPARATORS] help token: "help"
Processing Macros... [PROCESS_MACROS] INPUT len 4: "help" [PROCESS_MACROS] OUTPUT len 4: "help" Extracting Arguments... parse_line: "help"
parse_line: nargs=1 Looking up Command... Searching for Command 'help' Command Table Start : 0000053e Command Table End : 00000870
0x870 - 0x53e = 0x332 = 818. 818 / 24 = 34 with a remainder of 2. I believe this is your problem. I bet you need to word-align the start of your table... the end label is getting word aligned which is padding out your end so your loop doesn't end.
I suspect this is the problem with not recognizing the commands as well? Perhaps the processor/compiler doesn't like having the table poorly aligned so one of the pointers is getting messed up?
sizeof(int) : 4 sizeof(cmd_tbl_t) : 18
0x18 == 24
Checking : 0000053e Checking : 00000556
0x56 - 0x3e == 0x18 == 24 (check)
Checking : 0000056e . . . Checking : 00000856 Checking : 0000086e
0x86e is the proper table end given 34 commands and 24 bytes per table entry.
Checking : 00000886 Checking : 0000089e Checking : 000008b6
There are a few weird things going on...
a) sizeof(cmd_tbl_t) is 18, but the loop is incrementing by 24 (I would have thought a 4 byte alignment would push it to 20 maybe)
Nope, just radix issues (see above).
b) The loop never completes since cmdtp never actually equals &__u_boot_cmd_end
Alignment padding problems are preventing it (see above).
[snip]
Can anyone point me an a rough direction to look? Any help at all would be greatly appreciated
I think you need a 4 byte alignment before the command table in the linker control file (below)
Regards,
Graeme
u-boot.lds:
[snip]
/* 16bit BIOS emulation code (just enough to boot Linux) */ .bios 0 : AT ( LOADADDR(.realmode) + SIZEOF(.realmode) ) { *(.bios) }
_i386boot_bios = LOADADDR(.bios); _i386boot_bios_size = SIZEOF(.bios);
. = .;
I think you need to add . = ALIGN(2); here
(ALIGN(4)? IIRC, the ALIGN is 2^n so ALIGN(2) is 4-byte alignment)
__u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .;
[snip]
HTH, gvb

Thanks for such a quick response Jerry. Your suggestion fixed one problem, but it still doesn't work
Jerry Van Baren wrote:
Graeme Russ wrote:
Hi All,
Aaargh, you printed %x, not 0x%x. That really threw me on the printout of sizeof(cmd_tbl_t).
0x18 == 24
How embarrassing - I've changed it to %i
b) The loop never completes since cmdtp never actually equals &__u_boot_cmd_end
Alignment padding problems are preventing it (see above).
Fixed with . = ALIGN(4) (ALIGN(2) made no difference)
I've added a few more debugs in the loop (and my startup code) with the following results:
U-Boot 2008.10-rc2-00002-gd6aaec1-dirty (Sep 20 2008 - 14:37:52)
U-Boot code: 38040000 -> 3805158F data: 00400000 -> 00400A57
BSS: 00400A58 -> 00404463 stack: 00404464 -> 0040C463
DRAM Configuration:
Bank #0: 00000000 64 MB
Bank #1: 04000000 64 MB
Bank #2: 08000000 0 kB
Bank #3: 08000000 0 kB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Serck Controls eNET
autoscript => do_autoscript() @ 0x38040886
bdinfo => do_bdinfo() @ 0x380408e7
<snip>
imls => do_imls() @ <undefined>
<snip>
help => do_help() @ 0x38043713
? => do_help() @ 0x38043713
boot > help
[RUN_COMMAND] cmd[00400ccc]="help"
[PROCESS_SEPARATORS] help
token: "help"
Processing Macros...
[PROCESS_MACROS] INPUT len 4: "help"
[PROCESS_MACROS] OUTPUT len 4: "help"
Extracting Arguments...
parse_line: "help"
parse_line: nargs=1
Looking up Command...
Searching for Command 'help'
Command Table Start : 0x00000540
Command Table End : 0x00000870
sizeof(int) : 4
sizeof(cmd_tbl_t) : 24
cmdtp = 0x00000540
cmdtp->name = 0xffffffff
cmdtp->maxargs = -262145
cmdtp->repeatable = -33562625
cmdtp->cmd = 0xf7ffffff
cmdtp->usage = 0xffff5fff
cmdtp->help = 0x7bffff7f
<snip>
cmdtp = 0x00000858
cmdtp->name = 0xfeffffff
cmdtp->maxargs = -513
cmdtp->repeatable = -1
cmdtp->cmd = 0xffffffff
cmdtp->usage = 0xffffffff
cmdtp->help = 0xffffffff
Searching complete
Unknown command 'help' - try 'help'
boot >
The address dumps of each command are simply achieved by:
printf("autoscript => do_autoscript() @ 0x%08lx\n", (ulong)do_autoscript); <snip> /* printf("imls => do_imls() @ 0x%08lx\n", (ulong)do_imls); */ printf("imls => do_imls() @ <undefined>\n");
For some reason do_imls always results in an undefined reference error reported by the linker, even though it ends up in the command list at 0x600 as shown in u-boot.map
0x0000000000000540 . = ALIGN (0x4) 0x0000000000000540 __u_boot_cmd_start = .
.u_boot_cmd 0x0000000000000540 0x330 load address 0x000000003805268e *(.u_boot_cmd) .u_boot_cmd 0x0000000000000540 0x18 common/libcommon.a(cmd_autoscript.o) 0x0000000000000540 __u_boot_cmd_autoscr .u_boot_cmd 0x0000000000000558 0x18 common/libcommon.a(cmd_bdinfo.o) 0x0000000000000558 __u_boot_cmd_bdinfo .u_boot_cmd 0x0000000000000570 0x30 common/libcommon.a(cmd_boot.o) 0x0000000000000588 __u_boot_cmd_reset 0x0000000000000570 __u_boot_cmd_go .u_boot_cmd 0x00000000000005a0 0x78 common/libcommon.a(cmd_bootm.o) 0x00000000000005a0 __u_boot_cmd_bootm 0x00000000000005e8 __u_boot_cmd_iminfo 0x00000000000005d0 __u_boot_cmd_bootd 0x00000000000005b8 __u_boot_cmd_boot 0x0000000000000600 __u_boot_cmd_imls .u_boot_cmd 0x0000000000000618 0x18 common/libcommon.a(cmd_console.o)
So now it is terminating the loop correctly, but it looks like the command table contains nothing garbage
I thought the load address 0x000000003805268e might be a hint, so I did a dump of u-boot.bin:
0x3805268e - 0x3804000 = 0x1268E = 75406
graeme@devel:~/Source/U-Boot/v2008.10-rc2$ xxd -s 75406 -l 160 u-boot.bin 001268e: 90e0 0438 0200 0000 0000 0000 8608 0438 ...8...........8 001269e: 98e0 0438 bae0 0438 a4e1 0438 0100 0000 ...8...8...8.... 00126ae: 0100 0000 e708 0438 abe1 0438 0000 0000 .......8...8.... 00126be: 2be2 0438 1000 0000 0100 0000 c509 0438 +..8...........8 00126ce: 2ee2 0438 5de2 0438 b8e2 0438 0100 0000 ...8]..8...8.... 00126de: 0000 0000 63c9 0438 bee2 0438 0000 0000 ....c..8...8.... 00126ee: 7ee6 0438 1000 0000 0100 0000 5a0c 0438 ~..8........Z..8 00126fe: 84e6 0438 b2e6 0438 c301 0538 0100 0000 ...8...8...8.... 001270e: 0100 0000 3a0c 0438 5ae7 0438 0000 0000 ....:..8Z..8.... 001271e: 87e7 0438 0100 0000 0100 0000 3a0c 0438 ...8........:..8
Doesn't seem to match (maybe I'm barking up the wrong tree)
Any ideas?
Regards,
Graeme

OK, I've had a closer look at u-boot.map and u-boot.bin...
The command table starts at offset 0x001268e into u-boot.bin and each entry is 24 bytes. The first entry is:
001268e: 90 e0 04 38 02 00 00 00 00 00 00 00 86 08 04 38 98 e0 04 38 ba e0 04 38
Which decodes down to:
90 e0 04 38 => cmd_tbl_t->name ASCII string at offset 0xe090 in u-boot.bin "autoscr"
02 00 00 00 => cmd_tbl_t->maxargs 2
00 00 00 00 = cmd_tbl_t->repeatable 0
86 08 04 38 => cmd_tbl_t->cmd u-boot.map => do_autoscript ()
98 e0 04 38 => cmd_tbl_t->usage ASCII string at offset 0xe098 in u-boot.bin "autoscr - run script from memory"
ba e0 04 38 => cmd_tbl_t->help ASCII string at offset 0xe0ba in u-boot.bin "[addr] - run script starting at addr - A valid autoscr header must be present"
So the table and all the references in it are valid and u-boot.map suggest it should be located at 0x540, but what is this relative to, and how does it end up there? I feel I'm getting closer, but missing one tiny, but critical, bit of info.
Sorry if this all seems obvious, but this is the first time I've dealt with data at such a low level
Regards,
Graeme
participants (2)
-
Graeme Russ
-
Jerry Van Baren