亚洲欧洲国产欧美一区精品,激情五月亚洲色五月,最新精品国偷自产在线婷婷,欧美婷婷丁香五月天社区

      考試首頁 | 考試用書 | 培訓(xùn)課程 | 模擬考場 | 考試論壇  
        當(dāng)前位置:操作系統(tǒng) > Linux > 文章內(nèi)容
        

      Linux基礎(chǔ)教程:Linux設(shè)備樹(Devicetree)

       [ 2016年2月18日 ] 【

      第221行檢查fdt指針是否為空并且調(diào)用early_init_dt_verify函數(shù),該函數(shù)代碼位于drivers/of/fdt.c,這個函數(shù)算是of模塊(還記得么?是open firmware的縮寫)的第一個函數(shù),復(fù)制代碼如下:

      1060
      1061 bool __init early_init_dt_verify(void *params)
      1062 {
      1063    if (!params)
      1064        return false;
      1065
      1066    /* check device tree validity */
      1067    if (fdt_check_header(params))
      1068        return false;
      1069
      1070    /* Setup flat device-tree pointer */
      1071    initial_boot_params = params;
      1072    of_fdt_crc32 = crc32_be(~0, initial_boot_params,
      1073                fdt_totalsize(initial_boot_params));
      1074    return true;
      1075 }

      early_init_dt_verify首先檢查fdt頭部的合法性,然后設(shè)置fdt全局變量以及計算crc。這個 initial_boot_params變量后邊在訪問設(shè)備樹的時候還會用到。繼續(xù)看前邊第224行,of_flat_dt_match_machine 函數(shù)算是of模塊的第二個函數(shù)吧,在分析這個函數(shù)前,我們首先分析���個函數(shù)的第二個參數(shù)arch_get_next_mach,這是一個函數(shù)指針,arm架構(gòu)的實(shí)現(xiàn)位于arch/arm/kernel/devtree.c,復(fù)制代碼如下:

      190 static const void * __init arch_get_next_mach(const char *const **match)
      191 {
      192    static const struct machine_desc *mdesc = __arch_info_begin;
      193    const struct machine_desc *m = mdesc;
      194
      195    if (m >= __arch_info_end)
      196        return NULL;
      197
      198    mdesc++;
      199    *match = m->dt_compat;
      200    return m;
      201 } 

      這個函數(shù)很簡單,注意的是mdesc是靜態(tài)局部變量,第一次調(diào)用指向__arch_info_begin,后邊每次調(diào)用都mdesc++,如果超過了__arch_info_end就返回NULL。以上代碼說明在__arch_info_begin和__arch_info_end兩個地址之間存儲著多個machine_desc變量(也可能是一個),該函數(shù)遍歷這些變量,通過match參數(shù)返回所有machine_desc結(jié)構(gòu)體的 dt_compat變量指針。問題是__arch_info_begin和__arch_info_end地址是怎么來的呢?在arch/arm /kernel/vmlinux.lds.S連接腳本中定義了.arch.info.init段,__arch_info_begin和 __arch_info_end地址分別是該段的首尾地址。

      188    .init.arch.info : {
      189        __arch_info_begin = .;
      190        *(.arch.info.init)
      191        __arch_info_end = .;
      192    }

      那么.init.arch.info段的內(nèi)容怎么來的呢?這就要參考DT_MACHINE_START和MACHINE_END宏了,arm架構(gòu)的定義在arch/arm/include/asm/mach/arch.h文件,如下所示:

       94 #define DT_MACHINE_START(_name, _namestr)      \
       95 static const struct machine_desc __mach_desc_##_name    \
       96  __used                        \
       97  __attribute__((__section__(".arch.info.init"))) = {    \
       98    .nr    = ~0,              \
       99    .name      = _namestr,
      100
      101 #endif

      從該宏代碼看出他定義了一個machine_desc類型的靜態(tài)局部變量,該變量位于.arch.info.init段中。參考arch/arm /mach-exynos/exynos.c中如下代碼,以下代碼在.arch.info.init段定義了一個名字為 __mach_desc_EXYNOS_DT,類型為machine_desc的靜態(tài)局部變量,并且該變量的dt_compat字符串矩陣中有"samsung,exynos5420"的字符串。

      277 static char const *const exynos_dt_compat[] __initconst = {
      278    "samsung,exynos3",
      279    "samsung,exynos3250",
      280    "samsung,exynos4",
      281    "samsung,exynos4210",
      282    "samsung,exynos4212",
      283    "samsung,exynos4412",
      284    "samsung,exynos4415",
      285    "samsung,exynos5",
      286    "samsung,exynos5250",
      287    "samsung,exynos5260",
      288    "samsung,exynos5420",
      289    "samsung,exynos5440",
      290    NULL
      291 };
       
      319 DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
      320    /* Maintainer: Thomas Abraham */
      321    /* Maintainer: Kukjin Kim */
      322    .l2c_aux_val    = 0x3c400001,
      323    .l2c_aux_mask  = 0xc20fffff,
      324    .smp        = smp_ops(exynos_smp_ops),
      325    .map_io    = exynos_init_io,
      326    .init_early = exynos_firmware_init,
      327    .init_irq  = exynos_init_irq,
      328    .init_machine  = exynos_dt_machine_init,
      329    .init_late  = exynos_init_late,
      330    .dt_compat  = exynos_dt_compat,
      331    .reserve    = exynos_reserve,
      332    .dt_fixup  = exynos_dt_fixup,
      333 MACHINE_END


      我們已經(jīng)知道了get_next_compat指針的具體實(shí)現(xiàn)了,現(xiàn)在繼續(xù)看of_flat_dt_match_machine。從第 732行開始的循環(huán)就是遍歷.arch.info.init段中所有的dt_compat變量,然后通過of_flat_dt_match計算一個分?jǐn)?shù),并且尋找那個分?jǐn)?shù)最小的。

       713 /**
       714  * of_flat_dt_match_machine - Iterate match tables to find matching machine.
       715  *
       716  * @default_match: A machine specific ptr to return in case of no match.
       717  * @get_next_compat: callback function to return next compatible match table.
       718  *
       719  * Iterate through machine match tables to find the best match for the machine
       720  * compatible string in the FDT.
       721  */
       722 const void * __init of_flat_dt_match_machine(const void *default_match,
       723        const void * (*get_next_compat)(const char * const**))
       724 {
       725    const void *data = NULL;
       726    const void *best_data = default_match;
       727    const char *const *compat;
       728    unsigned long dt_root;
       729    unsigned int best_score = ~1, score = 0;
       730       
       731    dt_root = of_get_flat_dt_root();
       732    while ((data = get_next_compat(&compat))) {
       733        score = of_flat_dt_match(dt_root, compat);
       734        if (score > 0 && score < best_score) {
       735            best_data = data;
       736            best_score = score;
       737        }
       738    }
       ....
       759    return best_data;
       760 }
       761

      將考試網(wǎng)添加到收藏夾 | 每次上網(wǎng)自動訪問考試網(wǎng) | 復(fù)制本頁地址,傳給QQ/MSN上的好友 | 申請鏈接 | 意見留言 TOP
      關(guān)于本站  網(wǎng)站聲明  廣告服務(wù)  聯(lián)系方式  站內(nèi)導(dǎo)航  考試論壇
      Copyright © 2007-2013 中華考試網(wǎng)(Examw.com) All Rights Reserved