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與.dts中root結點的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()