From kernel startup entry point to start_kernel (1)


arch/arm/kernel/head.s

Kernel startup entry point

/*
 * Kernel startup entry point.
 * ---------------------------
 *
 * This is normally called from the decompressor code.  The requirements
 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
 * r1 = machine nr, r2 = atags or dtb pointer.
 *
 * This code is mostly position independent, so if you link the kernel at
 * 0xc0008000, you call this at __pa(0xc0008000).
 *
 * See linux/arch/arm/tools/mach-types for the complete list of machine
 * numbers for r1.
 *
 * We're trying to keep crap to a minimum; DO NOT add any machine specific
 * crap here - that's what the boot loader (or in extreme, well justified
 * circumstances, zImage) is for.
 */


The whole process seen from the kernel crash file

    .arm

    __HEAD
ENTRY(stext)
可知代码的入口是stext
crash> sym stext
c0008000 (T) stext

crash> dis stext

0xc0008000 <.head.text>:        msr     CPSR_c, #211    ; 0xd3
0xc0008004 <stext+4>:   mrc     15, 0, r9, cr0, cr0, {0}
0xc0008008 <stext+8>:   bl      0xc044c960 <__lookup_processor_type>
0xc000800c <stext+12>:  movs    r10, r5
0xc0008010 <stext+16>:  beq     0xc044c9a4 <__error>
0xc0008014 <stext+20>:  add     r3, pc, #44     ; 0x2c
0xc0008018 <stext+24>:  ldm     r3, {r4, r8}
0xc000801c <stext+28>:  sub     r4, r3, r4
0xc0008020 <stext+32>:  add     r8, r8, r4
0xc0008024 <stext+36>:  bl      0xc0008110 <__vet_atags>
0xc0008028 <stext+40>:  bl      0xc058d000 <__fixup_smp>
0xc000802c <stext+44>:  bl      0xc0008050 <__create_page_tables>
0xc0008030 <stext+48>:  ldr     sp, [pc, #12]   ; 0xc0008044
0xc0008034 <stext+52>:  add     lr, pc, #4
0xc0008038 <stext+56>:  mov     r8, r4
0xc000803c <stext+60>:  add     pc, r10, #16
0xc0008040 <stext+64>:  b       0xc044c934 <__enable_mmu>

crash> dis __enable_mmu

0xc044c934 <__enable_mmu>:      bic     r0, r0, #2
0xc044c938 <__enable_mmu+4>:    mov     r5, #21
0xc044c93c <__enable_mmu+8>:    mcr     15, 0, r5, cr3, cr0, {0}
0xc044c940 <__enable_mmu+12>:   mcr     15, 0, r4, cr2, cr0, {0}
0xc044c944 <__enable_mmu+16>:   b       0xc0452950 <__turn_mmu_on>

crash> dis __turn_mmu_on

0xc0452950 <__idmap_text_start>:        nop                     ; (mov r0, r0)
0xc0452954 <__turn_mmu_on+4>:   isb     sy
0xc0452958 <__turn_mmu_on+8>:   mcr     15, 0, r0, cr1, cr0, {0}
0xc045295c <__turn_mmu_on+12>:  mrc     15, 0, r3, cr0, cr0, {0}
0xc0452960 <__turn_mmu_on+16>:  isb     sy
0xc0452964 <__turn_mmu_on+20>:  mov     r3, r3
0xc0452968 <__turn_mmu_on+24>:  mov     r3, sp
0xc045296c <__turn_mmu_on+28>:  mov     pc, r3

pc值从r3得到,而r3来自sp,从代码看只有一处压栈过程:
0xc0008030 <stext+48>:  ldr     sp, [pc, #12]   ; 0xc0008044
当前pc值是0xc0008030+12+8(流水线)=0xc0008044;
crash> rd 0xc0008044
c0008044:  c058d05c
间接寻址,固sp的内容为0xc058d05c,则pc指向的内容是0xc058d05c
0xc058d05c <__mmap_switched>:从这里可以确定__turn_mmu_on最后调用了__mmap_switche。
因为该代码段是__INIT,运行后被释放,所以在 crash中不能得到。
#define __INIT        .section    ".init.text","ax"

/*
 * 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

    ldmia    r3, {r4, r5, r6, r7, sp}
    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

ENDPROC(__mmap_switched)

Next, all the bl xx will be analyzed.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值