基于Linux2.6.38.8内核启动过程完全解析(2)

三:__lookup_processor_type函数
 __lookup_processor_type函数是一个非常讲究技巧的函数,Kernel代码将所有CPU信息的定义都放到.proc.info.init段中,因此可以认为.proc.info.init段就是一个数组,每个元素都定义了一个或一种CPU的信息。目前__lookup_processor_type使用该元素的前两个字段cpuid和mask来匹配当前CPUID,如果满足CPUID & mask == cpuid,则找到当前cpu的定义并返回。

[cpp]

/*   * Read processor ID register (CP#15, CR0), and look up in the linker-built   * supported processor list.  Note that we can't use the absolute addresses   * for the __proc_info lists since we aren't running with the MMU on   * (and therefore, we are not in the correct address space).  We have to   * calculate the offset.   *   *  r9 = cpuid   * Returns:   *  r3, r4, r6 corrupted   *  r5 = proc_info pointer in physical address space   *  r9 = cpuid (preserved)   */       __CPUINIT   __lookup_processor_type:           /* adr 是相对寻址,它的寻计算结果是将当前PC值加上__lookup_processor_type_data符号与PC的偏移量,            * 而PC是物理地址,因此r3的结果也是__lookup_processor_type_data符号的物理地址 */       adr r3, __lookup_processor_type_data       ldmia   r3, {r4 - r6}       sub r3, r3, r4          @ get offset between virt&phys       add r5, r5, r3          @ convert virt addresses to       add r6, r6, r3          @ physical address space   1:  ldmia   r5, {r3, r4}            @ value, mask            /* 将当前CPUID和mask相与,并与数组元素中的CPUID比较是否相同             * 若相同,则找到当前CPU的__proc_info定义,r5指向访元素并返回。            */        and r4, r4, r9          @ mask wanted bits       teq r3, r4       beq 2f           /* r5指向下一个__proc_info元素 */        add r5, r5, #PROC_INFO_SZ       @ sizeof(proc_info_list)           /* 是否遍历完所有__proc_info元素 */        cmp r5, r6       blo 1b           /* 找不到则返回NULL */        mov r5, #0              @ unknown processor   2:  mov pc, lr   ENDPROC(__lookup_processor_type)  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/22526.html