kernel版本: 3.0.35
之前有提过u-boot对machine type的赋值:
int board_init(void)
{
......
/* board id for linux */
gd->bd->bi_arch_number = MACH_TYPE_MX6Q_SABRESD;
......
}
然后传给kernel:
void do_booti_linux (boot_img_hdr *hdr)
{
......
theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
}
那么kernel是如何得到的呢?
kernel_imx/arch/arm/kernel/head-common.S
__mmap_switched:
adr r3, __mmap_switched_data
......
str r9, [r4] @ Save processor ID
/*r1就是u-boot传过来的第二个参数,即machine type*/
str r1, [r5] @ Save machine type
str r2, [r6] @ Save atags pointer
bic r4, r0, #CR_A @ Clear 'A' bit
stmia r7, {r0, r4} @ Save control register values
b start_kernel
ENDPROC(__mmap_switched)
得到了machine type之后又是如何使用的呢
看 start_kernel -> setup_processor -> lookup_processor_type
ENTRY(lookup_processor_type)
stmfd sp!, {r4 - r6, r9, lr}
/*r9即machine type传给了r0*/
mov r9, r0
bl __lookup_processor_type
mov r0, r5
ldmfd sp!, {r4 - r6, r9, pc}
ENDPROC(lookup_processor_type)
__lookup_processor_type:
__lookup_processor_type:
/*得到__proc_info_begin里的内容,什么东西?别急*/
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
/*循环比较__proc_info_begin里存放的东西,相比肯定里面放了很多
相似结构的东东,下面讲哈。*/
1: ldmia r5, {r3, r4} @ value, mask
and r4, r4, r9 @ mask wanted bits
teq r3, r4
/*和传进来的r9即machine type比较,如何相等说明匹配上了!*/
beq 2f
add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
cmp r5, r6
blo 1b
mov r5, #0 @ unknown processor
2: mov pc, lr
ENDPROC(__lookup_processor_type)
__lookup_processor_type_data:
__lookup_processor_type_data:
.long .
.long __proc_info_begin
.long __proc_info_end
.size __lookup_processor_type_data, . - __lookup_processor_type_data
__proc_info_begin是什么东东?
arch/arm/kernel/vmlinux.lds.S:
__proc_info_begin = .;
*(.proc.info.init)
__proc_info_end = .;
__arch_info_begin = .;
*(.arch.info.init)
__arch_info_end = .;
__tagtable_begin = .;
*(.taglist.init)
tagtable_end = .;
.proc_info.init是怎么被用到的呢,举例:
kernel_imx\arch\arm\mach-mx6\board-mx6q_sabresd.c
MACHINE_START(MX6Q_SABRESD, "Freescale i.MX 6Quad/DualLite/Solo Sabre-SD Board")
/* Maintainer: Freescale Semiconductor, Inc. */
.boot_params = MX6_PHYS_OFFSET + 0x100,
.fixup = fixup_mxc_board,
.map_io = mx6_map_io,
.init_irq = mx6_init_irq,
.init_machine = mx6_sabresd_board_init,
.timer = &mx6_sabresd_timer,
.reserve = mx6q_sabresd_reserve,
MACHINE_START:
#define MACHINE_START(_type,_name) \
static const struct machine_desc __mach_desc_##_type \
__used \
__attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_##_type, \
.name = _name,
#define MACHINE_END \
};
这样,MACHINE_START和__proc_info_begin联系起来了,
其中里面的.nr就是machine type值,__lookup_processor_type中就是用它
和u-boot传进来的machine type值比较匹配的。
refer to : http://blog.sina.com.cn/s/blog_63ac1cef0100vbcj.html