arm_linux_从入口到start_kernel_代码详细分析2

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1. 确定processor type

arch/arm/kernel/head.S中:

00075: mrc p15, 0, r9, c0, c0 @ get processor id 00076: bl __lookup_processor_type @ r5=procinfo r9=cpuid 00077: movs r10, r5 @ invalid processor (r5=0)?

00078: beq __error_p @ yes, error 'p'

75行: 通过cp15协处理器的c0寄存器来获得processor id的指令. 关于cp15

的详细内容可参考相关的arm手册

76行: 跳转到__lookup_processor_type.在__lookup_processor_type中,会把

processor type 存储在r5中

77,78行: 判断r5中的processor type是否是0,如果是0,说明是无效的

processor type,跳转到__error_p(出错)

__lookup_processor_type 函数主要是根据从cpu中获得的processor id和系统中的proc_info进行匹配,将匹配到的proc_info_list的基地址存到r5中, 0表示没

有找到对应的processor type.

下面我们分析__lookup_processor_type函数

arch/arm/kernel/head-common.S中:

00145: .type __lookup_processor_type, %function

00146: __lookup_processor_type:

00147: adr r3, 3f

00148: ldmda r3, {r5 - r7}

00149: sub r3, r3, r7 @ get offset between virt&phys

00150: add r5, r5, r3 @ convert virt addresses to

00151: add r6, r6, r3 @ physical address space

00152: 1: ldmia r5, {r3, r4} @ value, mask

00153: and r4, r4, r9 @ mask wanted bits

00154: teq r3, r4

00155: beq 2f

00156: add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)

00157: cmp r5, r6

00158: blo 1b

00159: mov r5, #0 @ unknown processor

00160: 2: mov pc, lr

00161:

00162:

00165: ENTRY(lookup_processor_type)

00166: stmfd sp!, {r4 - r7, r9, lr}

00167: mov r9, r0

00168: bl __lookup_processor_type

00169: mov r0, r5

00170: ldmfd sp!, {r4 - r7, r9, pc}

00171:

00172:

00176: .long __proc_info_begin

00177: .long __proc_info_end

00178: 3: .long .

00179: .long __arch_info_begin

00180: .long __arch_info_end

145, 146行是函数定义

147行: 取地址指令,这里的3f是向前symbol名称是3的位置,即第178行,将该

地址存入r3.

这里需要注意的是,adr指令取址,获得的是基于pc的一个地址,要格外注意,这个地址是3f处的"运行时地址",由于此时MMU还没有打开,也可以理解成物理地址(实地址).(详细内容可参考arm指令手册)

148行: 因为r3中的地址是178行的位置的地址,因而执行完后:

r5存的是176行符号__proc_info_begin的地址;

r6存的是177行符号__proc_info_end的地址;

r7存的是3f处的地址.

这里需要注意链接地址和运行时地址的区别. r3存储的是运行时地址(物理地址),而r7中存储的是链接地址(虚拟地址).

__proc_info_begin和__proc_info_end是在

arch/arm/kernel/vmlinux.lds.S中:

00031: __proc_info_begin = .;

00032: *(.init)

00033: __proc_info_end = .;

这里是声明了两个变量:__proc_info_begin 和__proc_info_end,其中等号后面的"."是location counter(详细内容请参考) 这三行的意思是: __proc_info_begin 的位置上,放置所有文件中的".init" 段的内容,然后紧接着是__proc_info_end 的位置.

kernel 使用struct proc_info_list来描述processor type.

在include/asm-arm/procinfo.h 中:

00029: struct proc_info_list {

00030: unsigned int cpu_val;

00031: unsigned int cpu_mask;

00032: unsigned long __cpu_mm_mmu_flags;

00033: unsigned long __cpu_io_mmu_flags;

00034: unsigned long __cpu_flush;

00035: const char *arch_name;

00036: const char *elf_name;

00037: unsigned int elf_hwcap;

00038: const char *cpu_name;

00039: struct processor *proc;

00040: struct cpu_tlb_fns *tlb;

00041: struct cpu_user_fns *user;

00042: struct cpu_cache_fns *cache;

00043: };

我们当前以at91为例,其processor是926的.

相关文档
最新文档