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,
#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