分类: 嵌入式
2016-08-27 10:45:33
__lookup_machine_type函数
1. 内核中对于每种支持的开发板都会使用宏MACHINE_START、MACHINE_END来定义一个machine_desc结构,它定义开发板相关的一些属性及函数,比如机器类型ID、起始I/O物理地址、Bootloader传入的参数的地址、中断初始化函数、I/O映射函数等,比如对于SMDK2440开发板,在arch/arm/mach-s3c2440/mach-smdk2440.c中定义如下:
2. 在331、341中定义的MACHINE_START、MACHINE_END在“arch/arm/include/asm/mach/arch.h”中定义如下:
3. machine_desc结构体在“arch/arm/include/asm/mach/arch.h”中定义,其如下所示:
所有machine_desc结构体都处于“.arch.info.init”段中,在连接内核时,它们被组织在一起,开始地址为__arch_info_begin,结束地址为__arch_info_end,从连接脚本“arch/arm/kernel/vmlinux.lds.S”中可以看出:
38 __arch_info_begin = .; //machine_desc结构体的开始地址
39 *(.arch.info.init) //所有machine_desc都在这里面
40 __arch_info_end = .; //machine_desc结构体的开始地址
4. 不同的machine_desc结构用于不同的开发板,U-BOOT调用内核时,会在r1寄存器中给出开发板的标记(机器类型ID);对于S3C2410、S3C2440开发板,U-Boot传入的机器类型ID为MACH_TYPE_SMDK2410、MACH_TYPE_S3C2440,它们对应的machine_desc结构分别在arch/arm/mach-s3c2410/mach-smdk2410.c和
arch/arm/mach-s3c2440/mach-smdk2440.c中定义
190 3: .long . //当前行编译链接后的虚拟地址
191 .long __arch_info_begin //machine_desc结构体的开始地址(虚拟地址)
192 .long __arch_info_end //machine_desc结构体的结束地址(虚拟地址)
.........................
205 __lookup_machine_type:
206 adr r3, 3b //r3 = 190行的物理地址
207 ldmia r3, {r4, r5, r6} //[r3]->r4,[r3+4]->r5,[r3+8]->r6
r4 = 190行的虚拟地址
r5 = __arch_info_begin (VA)
r6 = __arch_info_end (VA)
208 sub r3, r3, r4 //r3=(190行的物理地址)-(190行的虚拟地址)
209 add r5, r5, r3 //r5= __arch_info_begin(物理地址)
210 add r6, r6, r3 //r6= __arch_info_end(物理地址)
211 1: ldr r3, [r5, #MACHINFO_TYPE] //r5是machine_desc结构体地址
r3 = r5 + MACHINFO_TYPE=machine_desc结构中定义的nr成员,即机器类型ID
212 teq r3, r1 //r1是Bootloader调用内核时传入的机器类型ID
213 beq 2f //相等则跳转到218行
214 add r5, r5, #SIZEOF_MACHINE_DESC //否则跳转到下一个machine_desc结构体
215 cmp r5, r6 //是否已经比较完所有的machine_desc结构体
216 blo 1b //没有则继续比较(lo:无符号小于)
217 mov r5, #0 //比较完毕,但没有匹配的machine_desc结构体,r5=0
218 2: mov pc, lr //返回
上面代码功能说明:
__lookup_machine_type函数将这个r1寄存器中的机器类型ID与machine_desc结构中的nr成员比较,如果相等则表示找到了匹配的machine_desc结构,于是返回它的地址(存于r5中),如果__arch_machine_begin和__arch_machine_end间所有machine_desc结构的nr成员都不等于r1寄存器中的值,则返回0(r5等于0)
在配置菜单时,选中两个开发板即可:
System Type--->
S3C2410 Machines--->
[*] SMDK2410/A9M2410
S3C2440 Machines--->
[*] SMDK2440
NB:其实,__lookup_machine_type和__lookup_processor_type两个函数非常相似,只需理解一个即可