2011年4月22日 星期五

How to debug kernel startup assembly code?

arm-linux-objdump --source -C -G -l {elf or obj file}

  • -S, --source
    Intermix source code with disassembly
  • -C, --demangle[=STYLE]
    Decode mangled/processed symbol names.The STYLE, if specified, can be `auto', `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java' or `gnat'
  • -G, --stabs
    Display (in raw form) any STABS info in the file
  • -l, --line-numbersInclude line numbers and filenames in output


Tracing example:
Got following error while booting zImage/bootpImage:
## Starting application at 0x04000000 ...
Uncompressing Li done, booting t


with RVDS, CPU stops at
0000815c e1a00000 MOV r0,r0
00008160 eafffffd B 0x815c


arch/arm/boot/bootp/init.S : bootpImage first code
arch/arm/boot/compressed/head.S: zImage first code
arch/arm/kernel/head.S: Image first code

This failure occur after decompression done, therefore arch/arm/kernel/head.S and Image are suspect. But how do I know where is the source code of this "0x815c"? RVDS doesn't provide source code debug (or, can't).

Since suspect is in Image, which is created by vmlinux, we can use the above command to dump a mixed binary code and the assembly source code of vmlinux:
arm-linux-objdump --source -C -G -l arch/arm/boot/Image

/home/prj/vega_trunk/kernels/linux-2.6.35.12-cavm1/arch/arm/kernel/head.S:82
bl __lookup_processor_type @ r5=procinfo r9=cpuid
c0008008: eb000055 bl c0008164 <__lookup_processor_type>
/home/prj/vega_trunk/kernels/linux-2.6.35.12-cavm1/arch/arm/kernel/head.S:83
movs r10, r5 @ invalid processor (r5=0)?
c000800c: e1b0a005 movs sl, r5
/home/prj/vega_trunk/kernels/linux-2.6.35.12-cavm1/arch/arm/kernel/head.S:84
beq __error_p @ yes, error 'p'
c0008010: 0a000051 beq c000815c <__error>
/home/prj/vega_trunk/kernels/linux-2.6.35.12-cavm1/arch/arm/kernel/head.S:85
bl __lookup_machine_type @ r5=machinfo
c0008014: eb00006b bl c00081c8 <__lookup_machine_type>
/home/prj/vega_trunk/kernels/linux-2.6.35.12-cavm1/arch/arm/kernel/head.S:86
movs r8, r5 @ invalid machine (r5=0)?
c0008018: e1b08005 movs r8, r5
/home/prj/vega_trunk/kernels/linux-2.6.35.12-cavm1/arch/arm/kernel/head.S:87
beq __error_a @ yes, error 'a'
c000801c: 0a00004e beq c000815c <__error>

(..............)

c000815c <__error>:
__error():
/home/prj/vega_trunk/kernels/linux-2.6.35.12-cavm1/arch/arm/kernel/head-common.S:142
str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
#endif
1: mov r0, r0
c000815c: e1a00000 nop (mov r0,r0)
/home/prj/vega_trunk/kernels/linux-2.6.35.12-cavm1/arch/arm/kernel/head-common.S:143
b 1b
c0008160: eafffffd b c000815c <__error>

(..............)

c00081c8 <__lookup_machine_type>:
__lookup_machine_type():
/home/prj/vega_trunk/kernels/linux-2.6.35.12-cavm1/arch/arm/kernel/head-common.S:212
* Returns:
* r3, r4, r6 corrupted
* r5 = mach_info pointer in physical address space
*/



When calling __lookup_processor_type, r5(procinfo) is 0x4000000, r9(cpuid)=410fb024, return r10/r5=23fc0,
__lookup_machine_type @ r5=machinfo (23fc0), return r8/r5=0 ==> __error....

TODO: HOW does providing correct machid leads to correct result of __lookup_processor_type and __lookup_machine_type

[PATCH 3/3] Add ARM kernel debug macros for locating the boot problems quickly
https://lkml.org/lkml/2011/1/17/44

But it seems CONFIG_DEBUG_LL is not implemented since nothing printed on cns3420vb2x.

Linux启动(3)【转】
http://blogold.chinaunix.net/u3/104985/showart_2507730.html

ARM Linux Kernel Boot Requirements
http://www.arm.linux.org.uk/developer/booting.php
3. Detect the machine type

Existing boot loaders: OPTIONAL
New boot loaders: MANDATORY

The boot loader should detect the machine type its running on by some method. Whether this is a hard coded value or some algorithm that looks at the connected hardware is beyond the scope of this document. The boot loader must ultimately be able to provide a MACH_TYPE_xxx value to the kernel. (see linux/arch/arm/tools/mach-types).
(..................)

* CPU register settings
o r0 = 0.
o r1 = machine type number discovered in (3) above.
o r2 = physical address of tagged list in system RAM.




Apply any of following to fix this issue:
  1. hack arch/arm/boot/compressed/head.S:
    +ldr r7,=0xad8
  2. add arch/arm/boot/compressed/head-cns3xxx.S like head-sa1100.S did.
  3. hack u-boot do_go_exec(common/cmd_boot.c) to pass machid like do_bootm_linux(lib_arm/bootm.c)
    return entry (0, machid);
  4. TODO: How does 2.6.38 fixed this issue??


沒有留言: