详细分析内核汇编段代码
内核启动入口点,这通常是从解压代码中调用的。要求是:MMU关闭,D-cache关闭,I-cache无关,r0为0,r1机器编号,r2为atags或dtb指针,这段代码大部分是位置无关的,所以如果你链接内核在0xc0008000,__pa(0xc0008000)转换为物理地址调用它。参见linux/arch/arm/tools/mach-types获得r1机器枚举的完整列表。我们尽量把垃圾降到最低;
不要在这里添加任何特定于机器的垃圾——这就是引导加载程序(或者在极端、合理的情况下,zImage)的用途。
这里提到了机器码在linux/arch/arm/tools/mach-types我们简单看一下:
可以看出每个cpu有对应的编号,具体如何修改参考文件头部说明
__HEAD
#define __HEAD .section ".head.text","ax"
定义内存段到名称为.head.text的地方
"ax"表示该节区可分配并且可执行
ENTRY(stext) 用于指定汇编程序的入口点
在反汇编中可以得到印证
THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM.
THUMB( bx r9 ) @ If this is a Thumb-2 kernel,
THUMB( .thumb ) @ switch to Thumb now.
THUMB(1: )
通过宏CONFIG_THUMB2_KERNEL选择是否开启这段Thumb指令
adr r9 BSYM(1f) 把THUMB(1:)处的地址加载到r9 如果开启Thumb指令的话地址+1下面跳转的时候开启Thumb指令集
bx r9 若目标地址的bit[0]为0把目标地址的代码解释为ARM代码,若目标地址的bit[0]为1,即把目标地址的代码解释为Thumb代码。
.thumb开启thumb指令
setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
@ and irqs disabled
0x00000040| 0x00000080| 0x00000013 bit6,bit7,bit0,bit1,bit4为1故D3
上面的翻译成汇编即为msr CPSR_c, #211
cpsr_c代表的是cpsr寄存器的低8位,也就是控制位
进入管理模式,禁止中断
mrc p15, 0, r9, c0, c0 @ get processor id
MRC指令将协处理器的寄存器中数值传送到ARM处理器的寄存器中。
请求协处理器P15执行操作0,操作数为c0,c0,结果放在r9中,这里r9中存放的是cpuid,后面有机会咱会详细介绍arm的结构和汇编指令
跳转到__lookup_processor_type:
#define __CPUINIT .section ".cpuinit.text", "ax" 这段代码存放在.cpuinit.text段
adr r3, __lookup_processor_type_data 把__lookup_processor_type_data的地址加载到r3
ldmia r3, {r4 - r6} 把r3为基地址的数据依次放入r4到r6,相当于把一个地址的数据连续的拿到寄存器R4=标号3处的虚拟地址,r5=__arch_info_begin,r6=__arch_info_end。
sub r3, r3, r4 @ 物理地址-虚拟地址 r3是一个地址 r3这个地址内的第一个数据是r4内存的数据,r4内存的数据是一个链接地址,由于没有开启mmu还所以r3是个物理地址(已知链接地址和物理地址去找链接地址的实际物理地址)
add r5, r5, r3 @ convert virt addresses to 实际的开始地址
add r6, r6, r3 @ physical address space 实际的结束地址
1: ldmia r5, {r3, r4} @ value, mask
and r4, r4, r9 @ mask wanted bits
teq r3, r4
beq 2f
add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
cmp r5, r6
blo 1b
mov r5, #0 @ unknown processor
2: mov pc, lr
ENDPROC(__lookup_processor_type)
循环匹配cpuid和掩码,匹配后就会返回,不行的话R5为0后面会进入__error_p
R3存储后方2标号地址
ldmia r3, {r4, r8} r4=2标号的链接地址 r8是PAGE_OFFSET(0x00000000)
sub r4, r3, r4 @ (物理地址 – 链接地址)
add r8, r8, r4 @ 偏移地址
到目前为止
r1 =机器号,r2 = atags或dtb,
r8 = 偏移地址 r9 = cpuid, r10 = procinfo