[IMX6Q][Android4.4] kernel匹配machine type

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值