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()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章