__lookup_processor_type函数,确定内核是否支持当前CPU,如果支持,r5寄存器返回一个用于描述处理器的结构体的地址,否则r5
= 0
__lookup_processor_type函数根据前面读出的CPU
ID(存在r9寄存器中),从这些proc_info_list结构中找出匹配的
/arch/arm/kernel/head-common.S中
156 __lookup_processor_type:
157 adr r3, 3f
//r3 =
190行物理地址,adr是基于PC寄存器计算地址值,由于这时候还没
有使能MMU,PC寄存器中使用的还是物理地址
158
ldmda
r3, {r5 - r7} //[r3]->r7,[r3-4]->r6,[r3-8]->r5,也即r5
= __proc_info_begin(虚拟地址)
r6 = __proc_info_end(虚拟地址) r7 =
190行的虚拟地址
159 sub r3, r3,
r7 //r3 = r3 - r7,即物理地址 -
虚拟地址
160 add r5, r5,
r3 //r5 =
__proc_info_begin对应的物理地址
161 add r6, r6,
r3 //r6 = __proc_info_end对应的物理地址
162 1: ldmia r5,
{r3,
r4} //r3、r4=proc_info_list结构中的cpu_val、cpu_mask
163 and r4, r4, r9
//r9=CPU ID,r4 = r4&r9 =
cpu_mask&传入的CPU ID
164
teq r3,
r4 //比较
165 beq
2f //如果相等,表示找到匹配的proc_info_list结构,跳到170行
166 add r5, r5,
#PROC_INFO_SZ //r5指向下一个proc_info_list
PROC_INFO_SZ=sizeof(proc_info_list)
167
cmp r5,
r6 //是否已经比较完所有的proc_info_list结构?
168
blo
1b //r5 <
r6,没有比较完则继续比较(lo:小于则跳转)
169
mov r5,
#0 //比较完毕,但是没有匹配的proc_info_list结构,r5=0
170 2: mov pc,
lr //返回
171
ENDPROC(__lookup_processor_type)
...............
188 .long __proc_info_begin //
proc_info_list结构的开始地址,这是连接地址,也是虚拟地址
189
.long __proc_info_end //
proc_info_list结构的结束地址,这是连接地址,也是虚拟地址
190 3: .long . //“.”表示当前这行代码编译连接后的虚拟地址
191 .long __arch_info_begin
192
.long __arch_info_end
内核映象中,定义了若干个pro_info_list结构,结构体原型在
(include/asm/procinfo.h或者arch/arm/include/asm/procinfo.h)中,表示它支持的CPU
对于ARM架构的CPU,这些源码结构在arch/arm/mm/proc-arm920.S中,填充struct
proc_info_list结构体即可
不同的proc_info_list结构被用来支持不同的CPU,它们都是定义在“.proc.info.init”段中,在连接内核时,这些结构体被组织在一起,开始地址为__proc_info_begin,结束地址为__proc_info_end。这可以从链接脚本文件“arch/arm/kernel/vmlinux.lds.S”中看出来
35 __proc_info_begin = .; //proc_info_list结构的开始地址
36 *(.proc.info.init)
37 __proc_info_end = .;
//proc_info_list结构的结束地址
在使能MMU前使用的都是物理地址,而内核却是以虚拟地址连接的,所以在访问proc_init_list结构前,先将它的虚拟地址转换为物理地址,上面的157--161就是用来转换地址的
对于S3C2410和S3C2440开发板,它们的CPU
ID都是0x41129200,而在“/arch/arm/mm/proc-arm920.S”中定义的__arm920_proc_info结构中,cpu_val、cpu_mask的值分别为0x41009200、0xff00fff0,如下所示:
427 .section ".proc.info.init", #alloc, #execinstr
429 .type __arm920_proc_info,#object
430
__arm920_proc_info: (填充struc proc_info_list)
431
.long 0x41009200 //对应cpu_val
432
.long 0xff00fff0 //对应cpu_mask
.................