dts加载流程

boot_linux_from_mmc

       |-> dt_table_offset=((uint32_t)image_addr+page_size+kernel_actual_ramdisk_actual+second_actual);  ------------------------------找到dts的偏移地址

       |->table = (structdt_table*) dt_table_offset;                                    ----------------------------------找到dts的地址

      |->dev_tree_get_entry_into(table ,&dt_entry)                                  ----------------------------------进入匹配接口函数

            |->target_variant_id = board_target_id()                                      -----------------------------------获取board.platform对应的platform id

            |->__dev_tree_get_entry_info(table,dt_entry_info,target_variant_id,0xff)         -----------------------------------获取dts里面的platform id与board.platform对应的platform id

                  |->table_ptr=(unsigned char*)table + DEV_TREE_HEADER_SIZE

                   |->dt_entry_v1=(structdt_entry_v1 *)table_ptr

                  |->platform_dt_match(cur_dt_entry, target_variant_id, subtype_mask)

                  |->if(fond != 0) -----------------------------------如果找到,匹配成功                   

 

 

Kmain()---------------------------------------------汇编进入lk的第一个函数

       |->platform_early_init();

             |->board_init();

                   |->platform_detect()

                         |->board.platform =board_info_v8.board_info_v3.msm_id;

 

 

进入kernel之后进入下面流程

//---------------------------------------------kernel/arch/arm/mach-msm/board-8916.c

DT_MACHINE_START(MSM8916_DT,

                "Qualcomm Technologies,Inc. MSM 8916 (Flattened Device Tree)")

        .map_io = msm8916_map_io,

        .init_machine = msm8916_init,

        .dt_compat = msm8916_dt_match,

        .reserve = msm8916_dt_reserve,

        .init_very_early =msm8916_early_memory,

        .smp = &msm8916_smp_ops,

MACHINE_END

 

static const char *msm8916_dt_match[]__initconst = {

        "qcom,msm8916",

        "qcom,apq8016",

        NULL

};

 

#define DT_MACHINE_START(_name,_namestr)               \

static const structmachine_desc __mach_desc_##_name    \

 __used                                                \

 __attribute__((__section__(".arch.info.init")))= {    \

        .nr             = ~0,                           \

        .name           = _namestr,

 

这些不同的machine会有不同的MACHINEID,Uboot在启动Linux内核时会将MACHINE ID存放在r1寄存器,Linux启动时会匹配Bootloader传递的MACHINE ID和

MACHINE_START声明的MACHINEID,然后执行相应machine的一系列初始化函数。

引入Device Tree之后,MACHINE_START变更为DT_MACHINE_START,其中含有一个.dt_compat成员,用于表明相关的machine.dtsroot结点的compatible属性兼容关系。如果Bootloader传递给内核的DeviceTree中root结点的compatible属性出现在某machine的.dt_compat表中,相关的machine就与对应的Device Tree匹配,从而引发这一machine的一系列初始化函数被执行。

 

这个类型的变量放在内核代码段.arch.info.init中,在内核运行初期,被函数lookup_machine_type(此函数用汇编实现,在汇编文件中)取出,读取流程为

Start_kernel()-> setup_arch() -> setup_machine() -> lookup_machine_type()

你可能感兴趣的:(linux-dts)