kernel启动失败的调试方法

来源:互联网 发布:flypro烧录机软件 编辑:程序博客网 时间:2024/06/06 08:49

最近porting linux kernel ,系统起不来,没有打印 搞了一两天,发现对kernel 启动调试已经很生疏了, 有点收获记录下来:

启动流程 

首先是执行自解压,解压后重新跳转到0x40008000执行

arch\arm\kernel\head.s :

    __HEAD
ENTRY(stext)
    setmode    PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
                        @ and irqs disabled
    mrc    p15, 0, r9, c0, c0        @ get processor id
    bl    __lookup_processor_type        @ r5=procinfo r9=cpuid                  -->这里确定cpu type来决定 后面ROCINFO_INITFUNC 调用哪个初始化函数,4412为armv7
    movs    r10, r5                @ invalid processor (r5=0)?
 THUMB( it    eq )        @ force fixup-able long branch encoding
    beq    __error_p            @ yes, error 'p'

#ifndef CONFIG_XIP_KERNEL
    adr    r3, 2f
    ldmia    r3, {r4, r8}
    sub    r4, r3, r4            @ (PHYS_OFFSET - PAGE_OFFSET)
    add    r8, r8, r4            @ PHYS_OFFSET
#else
    ldr    r8, =PLAT_PHYS_OFFSET
#endif
    /*
     * r1 = machine no, r2 = atags or dtb,
     * r8 = phys_offset, r9 = cpuid, r10 = procinfo
     */
    bl    __vet_atags
#ifdef CONFIG_SMP_ON_UP
    bl    __fixup_smp
#endif
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
    bl    __fixup_pv_table
#endif
    bl    __create_page_tables

    /*
     * The following calls CPU specific code in a position independent
     * manner.  See arch/arm/mm/proc-*.S for details.  r10 = base of
     * xxx_proc_info structure selected by __lookup_processor_type
     * above.  On return, the CPU will be ready for the MMU to be
     * turned on, and r0 will hold the CPU control register value.
     */
    ldr    r13, =__mmap_switched        @ address to jump to after
                        @ mmu has been enabled
    adr    lr, BSYM(1f)            @ return (PIC) address
    mov    r8, r4                @ set TTBR1 to swapper_pg_dir
 ARM(    add    pc, r10, #PROCINFO_INITFUNC    )
 THUMB(    add    r12, r10, #PROCINFO_INITFUNC    )
 THUMB(    mov    pc, r12                )
1:    b    __enable_mmu
ENDPROC(stext)


 __enable_mmu 之后 pc会设置为 r13中保存的 __mmap_switched 地址执行,实现在 head-common.s

/*
 * The following fragment of code is executed with the MMU on in MMU mode,
 * and uses absolute addresses; this is not position independent.
 *
 *  r0  = cp#15 control register
 *  r1  = machine ID
 *  r2  = atags/dtb pointer
 *  r9  = processor ID
 */
    __INIT
__mmap_switched:
    adr    r3, __mmap_switched_data

    ldmia    r3!, {r4, r5, r6, r7}
    cmp    r4, r5                @ Copy data segment if needed
1:    cmpne    r5, r6
    ldrne    fp, [r4], #4
    strne    fp, [r5], #4
    bne    1b

    mov    fp, #0                @ Clear BSS (and zero fp)
1:    cmp    r6, r7
    strcc    fp, [r6],#4
    bcc    1b

 ARM(    ldmia    r3, {r4, r5, r6, r7, sp})
 THUMB(    ldmia    r3, {r4, r5, r6, r7}    )
 THUMB(    ldr    sp, [r3, #16]        )
    str    r9, [r4]            @ Save processor ID
    str    r1, [r5]            @ Save machine type
    str    r2, [r6]            @ Save atags pointer
    bic    r4, r0, #CR_A            @ Clear 'A' bit
    stmia    r7, {r0, r4}            @ Save control register values

    
    b    start_kernel

从此跳转到C代码

调试方法

如果在控制台初始化之前就死掉,需要JTAG或者 在汇编中添加代码定位

汇编中添加 b  .

c代码中添加
   __asm__(
        "b  .");

可以方便JTAG定位

同时可以load vmlinux : Data.LOAD.ELF &KERNEL_ROOT\vmlinux 0x40008000-0xc0008000;/nocode; ;
查看symbol来定位代码死在了哪里。


或者打开 CONFIG_DEBUG_LL 和 eraly_printk,不过这个功能需要借助debug-macro.s中的底层实现,如果实现有问题,也会引起死机。。我就是以为打开了这个死机,导致查了很久。。


如果start_kernel 执行过了,串口没有打印,系统还是死机。这时候问题可能比较多,cpu 相关设置 , pmic相关设置。

可以在arch\arm\mach-xxx.c 中吧 i2c resigister或者其他设备都去掉,排除设备驱动影响

用JTAG跟踪如果死在 inter cpu interrupt 或者其他 interrupt 可以查查trustzone hotlplug这些