NWR04B: Why won't it puts?
21 Apr 2005Still trying to figure out what the hell is going on here, and why it
won't print the messages I expect it to (while still printing the
FIXME
I stuck in at the end of the puts
routine w/o any
problems). I've been looking at the disassembled zImage, and I'm
scratching my head. Here's the deal: shortly after power-on, the
decompress_kernel
routine is run:
000074 EB000915 BL &000024D0
In C, decompress_kernel
looks like this:
ulg
decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
int arch_id)
{
output_data = (uch *)output_start; /* Points to kernel start */
free_mem_ptr = free_mem_ptr_p;
free_mem_ptr_end = free_mem_ptr_end_p;
__machine_arch_type = arch_id;
puts("EMXIF");
proc_decomp_setup();
arch_decomp_setup();
makecrc();
puts("Uncompressing Linux...");
gunzip();
puts(" done, booting the kernel.\n");
return output_ptr;
}
At 0x24D0, we've got some initilization, some register saving, and then the puts
routine is called:
0024FC E59F0034 LDR r0, &00002538
002500 EBFFF769 BL &000002AC
This is the first call to puts: puts("EXMIF");
(which is FIXME backwards; I had it frontwards at first, and wanted to see if the output was any different if I changed the string; it's not). puts
looks like this in C:
static void cx84200_puts(const char *s)
{
while(*s != '\0')
cx84200_putc(*s++);
cx84200_putc('F');
cx84200_putc('I');
cx84200_putc('X');
cx84200_putc('M');
cx84200_putc('E');
}
(more checking to see what works) and like this in ARM assembly:
0002AC E1A0C00D MOV ip, sp
0002B0 E92DD810 STMFD sp!, {r4,r11,ip,lr,pc}
Save the registers for later...
0002B4 E1A04000 MOV r4, r0
0002B8 E5D43000 LDRB r3, [r4, #0]
0002BC E24CB004 SUB r11, ip, #4
0002C0 E3530000 CMP r3, #0
0002C4 0A000004 BEQ &000002DC
r0 held the argument, and it's moved to r4. Check the first byte to see if it's zero (ie, if we're printing a null string), and jump ahead if it is. Not sure what we're doing with r11 here.
0002C8 E5D40000 LDRB r0, [r4, #0]
0002CC EBFFFFEB BL &00000280
0002D0 E5F43001 LDRB r3, [r4, #1]!
0002D4 E3530000 CMP r3, #0
0002D8 1AFFFFFA BNE &000002C8
Load the first byte again into r0, then go to 0x280 (putc
) with it. Increment r4 and see if it now points to a zero. If not, go through the routine again.
0002DC E3A00046 MOV r0, #70
0002E0 EBFFFFE6 BL &00000280
0002E4 E3A00049 MOV r0, #73
0002E8 EBFFFFE4 BL &00000280
0002EC E3A00058 MOV r0, #88
0002F0 EBFFFFE2 BL &00000280
0002F4 E3A0004D MOV r0, #77
0002F8 EBFFFFE0 BL &00000280
0002FC E3A00045 MOV r0, #69
000300 EBFFFFDE BL &00000280
This is the printing of FIXME
at the end of puts.
000304 E59F0008 LDR r0, &00000314
000308 E20000FF AND r0, r0, #&FF
00030C EBFFFFDB BL &00000280
Put 0x314 into r0, AND with 0xFF, then call putc
again.
000310 E91BA810 LDMDB r11, {r4,r11,sp,pc}
000314 00042548 ANDEQ r2, r4, r8, ASR #10
And I think this is where we fall off the end of puts
. Finally, a quick look at putc
, first in C:
static int cx84200_putc(char c) {
int i;
int j = 10;
CSR_WRITE(UART0_BASE, c);
for (i= 0; i < 60000; i++)
;
}
(j
left over from another bit of debugging) and assembly:
000280 E1A0C00D MOV ip, sp
000284 E92DD800 STMFD sp!, {r11,ip,lr,pc}
000288 E24CB004 SUB r11, ip, #4
00028C E3A02CEA MOV r2, #&EA00
000290 E2822060 ADD r2, r2, #96
000294 E20000FF AND r0, r0, #&FF
000298 E3A03209 MOV r3, #&90000000
00029C E5830000 STR r0, [r3, #0]
0002A0 E2522001 SUBS r2, r2, #1
0002A4 1AFFFFFD BNE &000002A0
0002A8 E91BA800 LDMDB r11, {r11,sp,pc}
So here are my many bits of confusion:
- That first call to
puts
should have r0 pointing toEXMIF
, right? Only it doesn't: 0x28A0 is where you can find this string, and r0 points to 0x2538. There's no ASCII there, and certainly no copy of the string I want. If I change the instruction so that r0 points to 0x28A0, the thing crashes badly -- just spews out hexdumps of something (presumably memory). - That last call to
putc
fromputs
, where r0 points to 0x314. WTF? It explains why I'm seeingH%
at the end of the strings, but as far as I can tell it certainly shouldn't be doing that. Again, there's nothing around 0x314 that would explain why we're trying to print it. - And in
putc
, what is withAND r0, r0, #&FF
? As far as I can tell, this has absolutely no effect on r0: it's a NOP.
I can only think of three things:
- I'm wrong.
- The disassembler I'm using has a bug.
- GCC has a bug.
If anyone has any insight to share, please let me know. This is really bugging me.
1 Comment
From: Joe
22-April-2005-02:46:00
I have.. how you say.. the faith.
Add a comment:
Name and email required; email is not displayed.
Related Posts
QRP weekend 08 Oct 2018
Open Source Cubesat Workshop 2018 03 Oct 2018
mpd crash? try removing files in /var/lib/mpd/ 11 Aug 2018