在arch/arm/mach-msm/board-8909.c中:
DT_MACHINE_START(MSM8909_DT,
"Qualcomm Technologies, Inc. MSM 8909 (Flattened Device Tree)")
.map_io = msm8909_map_io,
.init_machine = msm8909_init,
.dt_compat = msm8909_dt_match,
.reserve = msm8909_dt_reserve,
.smp = &msm8916_smp_ops,
MACHINE_END
经过宏替换,最终变为:
static const struct machine_desc __mach_desc_MSM8909_DT __used __attribute__((__section__(".arch.info.init"))) = {
.nr = ~0,
.name = "Qualcomm Technologies, Inc. MSM 8909 (Flattened Device Tree)",
.map_io = msm8909_map_io,
.init_machine = msm8909_init,
.dt_compat = msm8909_dt_match,
.reserve = msm8909_dt_reserve,
.smp = &msm8916_smp_ops,
}
msm8909_dt_match定义如下:
static const char *msm8909_dt_match[] __initconst = {
"qcom,msm8909",
"qcom,apq8009",
NULL
};
编译器会将machine_desc放在一个叫.arch.info.init的段中,具体可以参考arch/arm/kernel/vmlinux.lds.S文件:
.init.arch.info : {
__arch_info_begin = .;
*(.arch.info.init)
__arch_info_end = .;
}
另外在高通的dts文件中,会定义compatible = "qcom,msm8909-qrd", "qcom,msm8909", "qcom,qrd";通过"qcom,msm8909"匹配,具体过程如下:
在arch/arm/kernel/setup.c中,setup_arch会调用setup_machine_fdt(__atags_pointer)来匹配machine:
const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
{
//删除了部分代码
for_each_machine_desc(mdesc) {
score = of_flat_dt_match(dt_root, mdesc->dt_compat);
if (score > 0 && score < mdesc_score) {
mdesc_best = mdesc;
mdesc_score = score;
}
}
//删除了部分代码
return mdesc_best;
}
for_each_machine_desc宏展开如下:
#define for_each_machine_desc(p) \
for (p = __arch_info_begin; p < __arch_info_end; p++)
由此可见,在.arch.info.init段中,依次取出每个machine描述符,根据dt_compat属性来匹配dts,对应msm8909来说就是"qcom,msm8909"。
__atags_pointer是指向dts的指针,它的值在arch/arm/kernel/head-common.S文件中被赋值:
__mmap_switched:
adr r3, __mmap_switched_data
ldmia r3!, {r4, r5, r6, r7}
cmp r4, r5 @ Copy data segment if needed
1: cmpne r5, r6
ldrne fp, [r4], #4
strne fp, [r5], #4
bne 1b
mov fp, #0 @ Clear BSS (and zero fp)
1: cmp r6, r7
strcc fp, [r6],#4
bcc 1b
ARM( ldmia r3, {r4, r5, r6, r7, sp})
THUMB( ldmia r3, {r4, r5, r6, r7} )
THUMB( ldr sp, [r3, #16] )
str r9, [r4] @ Save processor ID
str r1, [r5] @ Save machine type
str r2, [r6] @ Save atags pointer
cmp r7, #0
bicne r4, r0, #CR_A @ Clear 'A' bit
stmneia r7, {r0, r4} @ Save control register values
b start_kernel
ENDPROC(__mmap_switched)
.align 2
.type __mmap_switched_data, %object
__mmap_switched_data:
.long __data_loc @ r4
.long _sdata @ r5
.long __bss_start @ r6
.long _end @ r7
.long processor_id @ r4
.long __machine_arch_type @ r5
.long __atags_pointer @ r6
#ifdef CONFIG_CPU_CP15
.long cr_alignment @ r7
#else
.long 0 @ r7
#endif
.long init_thread_union + THREAD_START_SP @ sp
.size __mmap_switched_data, . - __mmap_switched_data