23、(2)Linux内核启动分析之 __lookup_processor_type函数

来源:互联网 发布:淘宝商城坡跟皮鞋 编辑:程序博客网 时间:2024/04/20 02:34
    __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

       .................    

因此在配置内核时,要选中

             System Type-->

                 [*] Supprot ARM920T processor

在Makefile中对应如下:

             obj-$(CONFIG_CPU_ARM920T)  += proc_arm920t.o

   

原创粉丝点击