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.