本文主要分析入口函数中的 bl __lookup_processor_type,即匹配相应的处理器,获取信息句柄proc_info_list 内容。
__lookup_processor_type: @ 查询对应的处理器信息
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(从段开始位置加载数据到 r3、r4 中)
and r4, r4, r9 @ mask wanted bits (r4 = 0xff0ffff0 & 0x410fc075)
teq r3, r4 @ 判断处理器ID是否一致(0x410f,c070)
beq 2f
add r5, r5, #PROC_INFO_SZ @ 偏移到下一个处理信息条目 sizeof(proc_info_list) == 52
cmp r5, r6 @ 判断是否到达位置 __proc_info_end
blo 1b
mov r5, #0 @ unknown processor(未知处理器 r5=0, 当前CPSR.C=1)
2: ret lr @ 查找成功!! 返回之前的位置 head.S P100(信息入口保存在 r5 中)
ENDPROC(__lookup_processor_type)
/*
* Look in <asm/procinfo.h> for information about the __proc_info structure.
*/
.align 2
.type __lookup_processor_type_data, %object @ 定义数据类型
__lookup_processor_type_data:
.long . @ 当前位置
.long __proc_info_begin @ 段 ".proc.info.init" 开始(proc-v7.S P591)
.long __proc_info_end @ 结束位置
.size __lookup_processor_type_data, . - __lookup_processor_type_data
由于笔者使用的soc为IMX6ULL,为ARMV7内核版本,查阅文档可知如下图:
获取段 .section ".proc.info.init", #alloc 中的条目,比较其中的Main ID值,进而获取到具体的处理器句柄,对于我这一款开发板,则是:
这里补充一下如何获取MIDR寄存器的值:
采用命令 mrc p15, 0, r9, c0, c0 ,此命令操作协处理器15,将指定的寄存器值存入cpu通用寄存器r9中,这里附上 c0寄存器的对应表:
至于寄存器MIDR的具体位意义请自行查阅文档
《ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition》。