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

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

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

       [ 2016年2月18日 ] 【

      根節(jié)點

      一個最簡單的設(shè)備樹必須包含根節(jié)點,cpus節(jié)點,memory節(jié)點。根節(jié)點的名字及全路徑都是“/”,至少需要包含model和 compatible兩個屬性。model屬性我們在屬性那節(jié)已經(jīng)說過是用來描述產(chǎn)品型號的,類型為字符串,推薦的格式為 “manufacturer,model-number”(非強制的)。根節(jié)點的model屬性描述的是板子的型號或者芯片平臺的型號,如:
      model = "Atmel AT91SAM9G20 family SoC"
      model = "Samsung SMDK5420 board based on EXYNOS5420"

      從軟件的層面講model屬性僅僅表示一個名字而已,沒有更多的作用。compatible屬性則不同,該屬性決定軟件如何匹配硬件對硬件進行初始化。屬性那一節(jié)我們說過compatible屬性的類型是字符串數(shù)組,按照范圍從小到大的順序排列,每個字符串表示一種匹配類型。根節(jié)點的 compatible屬性表示平臺如何匹配,比如‘compatible = "samsung,smdk5420", "samsung,exynos5420", "samsung,exynos5"’,表示軟件應(yīng)該首先匹配'samsung,smdk5420',這個是一款開發(fā)板。如果無法匹配,再試著匹配"samsung,exynos5420",這個是一款芯片平臺。如果還是無法匹配,還可以試著匹配 "samsung,exynos5",這是一個系列的芯片平臺。這里說的匹配是指軟件根據(jù)該信息找到對應(yīng)的代碼,如對應(yīng)的初始化函數(shù)。

      根節(jié)點表示的是整個板子或者芯片平臺,所以在系統(tǒng)初始化比較早的時候就需要確認是什么平臺,怎樣初始化。對于Linux,是通過在 start_kernel函數(shù)調(diào)用setup_arch函數(shù)實現(xiàn)的。不同的架構(gòu),setup_arch函數(shù)的實現(xiàn)不同,對于arm架構(gòu),setup_arch函數(shù)源代碼位于arch/arm/kernel/setup.c中。以下是該函數(shù)的部分源代碼(代碼來自內(nèi)核版本4.4-rc7 的官方版本,本節(jié)后邊所有代碼都來自該版本)。

       935 void __init setup_arch(char **cmdline_p)
       936 {
       937    const struct machine_desc *mdesc;
       938
       939    setup_processor();
       940    mdesc = setup_machine_fdt(__atags_pointer);
       941    if (!mdesc)
       942        mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type);
       943    machine_desc = mdesc;
       944    machine_name = mdesc->name;


      第940行setup_machine_fdt函數(shù)的輸入是設(shè)備樹(DTB)首地址,返回的mdesc是描述平臺信息的結(jié)構(gòu)體。還記得我們在概述那節(jié)說過啟動程序如uboot把設(shè)備樹讀到內(nèi)存中,然后在啟動內(nèi)核的同時將設(shè)備樹首地址傳給內(nèi)核,此處__atags_pointer就是啟動程序傳給內(nèi)核的設(shè)備樹地址(此時內(nèi)存中的設(shè)備樹已經(jīng)是DTB形式)。setup_machine_fdt中的fdt是flat device tree的縮寫,fdt的意思是說設(shè)備樹在內(nèi)存中是在一塊連續(xù)地址存儲的,fdt和dtb說的都是同一個東西。setup_machine_tags是在設(shè)備樹初始化失敗的時候才調(diào)用的,所以不用管他。machine_desc和machine_name都是靜態(tài)全局變量,用來保存指針方便后邊引用的。為了更好的理解setup_machine_fdt具體實現(xiàn)了什么功能,我們首先看下machine_desc結(jié)構(gòu)體。不同的架構(gòu),該結(jié)構(gòu)體定義差別很大,arm架構(gòu)源代碼位于arch/arm/include/asm/mach/arch.h,復(fù)制如下:
       
       27 struct machine_desc {
       28    unsigned int        nr;    /* architecture number  */
       29    const char      *name;      /* architecture name    */
       30    unsigned long      atag_offset;    /* tagged list (relative) */
       31    const char *const  *dt_compat; /* array of device tree
       32                          * 'compatible' strings */
       33
       34    unsigned int        nr_irqs;    /* number of IRQs */
       35
       36 #ifdef CONFIG_ZONE_DMA
       37    phys_addr_t    dma_zone_size;  /* size of DMA-able area */
       38 #endif
       39
       40    unsigned int        video_start;    /* start of video RAM  */
       41    unsigned int        video_end;  /* end of video RAM */
       42
       43    unsigned char      reserve_lp0 :1; /* never has lp0    */
       44    unsigned char      reserve_lp1 :1; /* never has lp1    */
       45    unsigned char      reserve_lp2 :1; /* never has lp2    */
       46    enum reboot_mode    reboot_mode;    /* default restart mode */
       47    unsigned        l2c_aux_val;    /* L2 cache aux value  */
       48    unsigned        l2c_aux_mask;  /* L2 cache aux mask    */
       49    void            (*l2c_write_sec)(unsigned long, unsigned);
       50    const struct smp_operations *smp;  /* SMP operations  */
       51    bool            (*smp_init)(void);
       52    void            (*fixup)(struct tag *, char **);
       53    void            (*dt_fixup)(void);
       54    long long      (*pv_fixup)(void);
       55    void            (*reserve)(void);/* reserve mem blocks  */
       56    void            (*map_io)(void);/* IO mapping function  */
       57    void            (*init_early)(void);
       58    void            (*init_irq)(void);
       59    void            (*init_time)(void);
       60    void            (*init_machine)(void);
       61    void            (*init_late)(void);
       62 #ifdef CONFIG_MULTI_IRQ_HANDLER
       63    void            (*handle_irq)(struct pt_regs *);
       64 #endif
       65    void            (*restart)(enum reboot_mode, const char *);
       66 };
       67

      從以上結(jié)構(gòu)體的注釋可以看出,該結(jié)構(gòu)體包含了非常多的信息。注意第31行的dt_compat變量,該變量就是用來匹配設(shè)備樹的compatible屬性的。

      setup_machine_fdt函數(shù)的實現(xiàn)也是架構(gòu)相關(guān)的,arm架構(gòu)源代碼位于arch/arm/kernel/devtree.c,復(fù)制代碼如下:

      203 /**     
      204  * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
      205  * @dt_phys: physical address of dt blob
      206  * 
      207  * If a dtb was passed to the kernel in r2, then use it to choose the
      208  * correct machine_desc and to setup the system.
      209  */
      210 const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
      211 {   
      212    const struct machine_desc *mdesc, *mdesc_best = NULL;
      213
      214 #ifdef CONFIG_ARCH_MULTIPLATFORM
      215    DT_MACHINE_START(GENERIC_DT, "Generic DT based system")
      216    MACHINE_END
      217
      218    mdesc_best = &__mach_desc_GENERIC_DT;
      219 #endif
      220
      221    if (!dt_phys || !early_init_dt_verify(phys_to_virt(dt_phys)))
      222        return NULL;
      223
      224    mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach);
      225
      226    if (!mdesc) {
      227        const char *prop;
      228        int size;
      229        unsigned long dt_root;
      230
      231        early_print("\nError: unrecognized/unsupported "
      232                "device tree compatible list:\n[ ");
      233
      234        dt_root = of_get_flat_dt_root();
      235        prop = of_get_flat_dt_prop(dt_root, "compatible", &size);
      236        while (size > 0) {
      237            early_print("'%s' ", prop);
      238            size -= strlen(prop) + 1;
      239            prop += strlen(prop) + 1;
      240        }
      241        early_print("]\n\n");
      242
      243        dump_machine_table(); /* does not return */
      244    }
      245
      246    /* We really don't want to do this, but sometimes firmware provides buggy data */
      247    if (mdesc->dt_fixup)
      248        mdesc->dt_fixup();
      249
      250    early_init_dt_scan_nodes();
      251
      252    /* Change machine number to match the mdesc we're using */
      253    __machine_arch_type = mdesc->nr;
      254
      255    return mdesc;
      256 }

      將考試網(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