高通平台dts的匹配过程分析

在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

你可能感兴趣的:(高通平台dts的匹配过程分析)