久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Device Tree(二):基本概念

 jiffes 2015-07-09
分類: linux相關(guān) 2014-06-28 15:42 1765人閱讀 評(píng)論(0) 收藏 舉報(bào)

一,、前言

一些背景知識(shí)(例如:為何要引入Device Tree,,這個(gè)機(jī)制是用來(lái)解決什么問(wèn)題的)請(qǐng)參考引入Device Tree的原因,本文主要是介紹Device Tree的基礎(chǔ)概念,。

簡(jiǎn)單的說(shuō),,如果要使用Device Tree,,首先用戶要了解自己的硬件配置和系統(tǒng)運(yùn)行參數(shù),并把這些信息組織成Device Tree source file,。通過(guò)DTC(Device Tree Compiler),,可以將這些適合人類閱讀的Device Tree source file變成適合機(jī)器處理的Device Tree binary file(有一個(gè)更好聽(tīng)的名字,DTB,,device tree blob),。在系統(tǒng)啟動(dòng)的時(shí)候,boot program(例如:firmware,、bootloader)可以將保存在flash中的DTB copy到內(nèi)存(當(dāng)然也可以通過(guò)其他方式,,例如可以通過(guò)bootloader的交互式命令加載DTB,或者firmware可以探測(cè)到device的信息,,組織成DTB保存在內(nèi)存中),,并把DTB的起始地址傳遞給client program(例如OS kernel,bootloader或者其他特殊功能的程序),。對(duì)于計(jì)算機(jī)系統(tǒng)(computer system),,一般是firmware->bootloader->OS,對(duì)于嵌入式系統(tǒng),,一般是bootloader->OS,。

本文主要描述下面兩個(gè)主題:

1、Device Tree source file語(yǔ)法介紹

2,、Device Tree binaryfile格式介紹

 

二,、Device Tree的結(jié)構(gòu)

在描述Device Tree的結(jié)構(gòu)之前,我們先問(wèn)一個(gè)基礎(chǔ)問(wèn)題:是否Device Tree要描述系統(tǒng)中的所有硬件信息,?答案是否定的,。基本上,那些可以動(dòng)態(tài)探測(cè)到的設(shè)備是不需要描述的,,例如USB device,。不過(guò)對(duì)于SOC上的usb host controller,它是無(wú)法動(dòng)態(tài)識(shí)別的,,需要在device tree中描述,。同樣的道理,在computer system中,,PCI device可以被動(dòng)態(tài)探測(cè)到,,不需要在device tree中描述,但是PCI bridge如果不能被探測(cè),,那么就需要描述之,。

為了了解Device Tree的結(jié)構(gòu),我們首先給出一個(gè)Device Tree的示例:

/ o device-tree 
      |- name = "device-tree" 
      |- model = "MyBoardName" 
      |- compatible = "MyBoardFamilyName" 
      |- #address-cells = <2> 
      |- #size-cells = <2> 
      |- linux,phandle = <0> 
      | 
      o cpus 
      | | - name = "cpus" 
      | | - linux,phandle = <1> 
      | | - #address-cells = <1> 
      | | - #size-cells = <0> 
      | | 
      | o PowerPC,970@0 
      |   |- name = "PowerPC,970" 
      |   |- device_type = "cpu" 
      |   |- reg = <0> 
      |   |- clock-frequency = <0x5f5e1000> 
      |   |- 64-bit 
      |   |- linux,phandle = <2> 
      | 
      o memory@0 
      | |- name = "memory" 
      | |- device_type = "memory" 
      | |- reg = <0x00000000 0x00000000 0x00000000 0x20000000>
      | |- linux,phandle = <3> 
      | 
      o chosen 
        |- name = "chosen" 
        |- bootargs = "root=/dev/sda2" 
        |- linux,phandle = <4>

從上圖中可以看出,device tree的基本單元是node,。這些node被組織成樹(shù)狀結(jié)構(gòu),,除了root node,每個(gè)node都只有一個(gè)parent,。一個(gè)device tree文件中只能有一個(gè)root node,。每個(gè)node中包含了若干的property/value來(lái)描述該node的一些特性。每個(gè)node用節(jié)點(diǎn)名字(node name)標(biāo)識(shí),,節(jié)點(diǎn)名字的格式是node-name@unit-address,。如果該node沒(méi)有reg屬性(后面會(huì)描述這個(gè)property),那么該節(jié)點(diǎn)名字中必須不能包括@和unit-address,。unit-address的具體格式是和設(shè)備掛在那個(gè)bus上相關(guān),。例如對(duì)于cpu,其unit-address就是從0開(kāi)始編址,,以此加一,。而具體的設(shè)備,例如以太網(wǎng)控制器,,其unit-address就是寄存器地址,。root node的node name是確定的,必須是“/”,。

在一個(gè)樹(shù)狀結(jié)構(gòu)的device tree中,,如何引用一個(gè)node呢?要想唯一指定一個(gè)node必須使用full path,,例如/node-name-1/node-name-2/node-name-N。在上面的例子中,,cpu node我們可以通過(guò)/cpus/PowerPC,970@0訪問(wèn),。

屬性(property)值標(biāo)識(shí)了設(shè)備的特性,它的值(value)是多種多樣的:

1,、可能是空,,也就是沒(méi)有值的定義。例如上圖中的64-bit ,,這個(gè)屬性沒(méi)有賦值,。

2、可能是一個(gè)u32,、u64的數(shù)值(值得一提的是cell這個(gè)術(shù)語(yǔ),,在Device Tree表示32bit的信息單位)。例如#address-cells = <1> ,。當(dāng)然,,可能是一個(gè)數(shù)組。例如<0x00000000 0x00000000 0x00000000 0x20000000>

4、可能是一個(gè)字符串,。例如device_type = "memory" ,,當(dāng)然也可能是一個(gè)string list。例如"PowerPC,970"

 

三,、Device Tree source file語(yǔ)法介紹

了解了基本的device tree的結(jié)構(gòu)后,,我們總要把這些結(jié)構(gòu)體現(xiàn)在device tree source code上來(lái)。在linux kernel中,,擴(kuò)展名是dts的文件就是描述硬件信息的device tree source file,,在dts文件中,一個(gè)node被定義成:

[label:] node-name[@unit-address] { 
   [properties definitions] 
   [child nodes] 
}

“[]”表示option,,因此可以定義一個(gè)只有node name的空節(jié)點(diǎn),。label方便在dts文件中引用,具體后面會(huì)描述,。child node的格式和node是完全一樣的,,因此,一個(gè)dts文件中就是若干嵌套組成的node,,property以及child note,、child note property描述。

考慮到空泛的談比較枯燥,,我們用實(shí)例來(lái)講解Device Tree Source file 的數(shù)據(jù)格式,。假設(shè)蝸窩科技制作了一個(gè)S3C2416的開(kāi)發(fā)板,我們把該development board命名為snail,,那么需要撰寫(xiě)一個(gè)s3c2416-snail.dts的文件,。如果把所有的開(kāi)發(fā)板的硬件信息(SOC以及外設(shè))都描述在一個(gè)文件中是不合理的,因此有可能其他公司也使用S3C2416搭建自己的開(kāi)發(fā)板并命令pig,、cow什么的,,如果大家都用自己的dts文件描述硬件,那么其中大部分是重復(fù)的,,因此我們把和S3C2416相關(guān)的硬件描述保存成一個(gè)單獨(dú)的dts文件可以供使用S3C2416的target board來(lái)引用并將文件的擴(kuò)展名變成dtsi(i表示include),。同理,三星公司的S3C24xx系列是一個(gè)SOC family,,這些SOCs(2410,、2416、2450等)也有相同的內(nèi)容,,因此同樣的道理,,我們可以將公共部分抽取出來(lái),變成s3c24xx.dtsi,,方便大家include,。同樣的道理,,各家ARM vendor也會(huì)共用一些硬件定義信息,這個(gè)文件就是skeleton.dtsi,。我們自下而上(類似C++中的從基類到頂層的派生類)逐個(gè)進(jìn)行分析,。

1、skeleton.dtsi,。位于linux-3.14\arch\arm\boot\dts目錄下,,具體該文件的內(nèi)容如下:

/ { 
    #address-cells = <1>; 
    #size-cells = <1>; 
    chosen { }; 
    aliases { }; 
    memory { device_type = "memory"; reg = <0 0>; }; 
};

device tree顧名思義是一個(gè)樹(shù)狀的結(jié)構(gòu),既然是樹(shù),,必然有根,。“/”是根節(jié)點(diǎn)的node name,?!皗”和“}”之間的內(nèi)容是該節(jié)點(diǎn)的具體的定義,其內(nèi)容包括各種屬性的定義以及child node的定義,。chosen,、aliases和memory都是sub node,sub node的結(jié)構(gòu)和root node是完全一樣的,,因此,,sub node也有自己的屬性和它自己的sub node,最終形成了一個(gè)樹(shù)狀的device tree,。屬性的定義采用property = value的形式,。例如#address-cells和#size-cells就是property,而<1>就是value,。value有三種情況:

1)屬性值是text string或者string list,,用雙引號(hào)表示。例如device_type = "memory"

2)屬性值是32bit unsigned integers,,用尖括號(hào)表示,。例如#size-cells = <1>

3)屬性值是binary data,用方括號(hào)表示,。例如binary-property = [0x01 0x23 0x45 0x67]

如果一個(gè)device node中包含了有尋址需求(要定義reg property)的sub node(后文也許會(huì)用child node,和sub node是一樣的意思),,那么就必須要定義這兩個(gè)屬性,。“#”是number的意思,,#address-cells這個(gè)屬性是用來(lái)描述sub node中的reg屬性的地址域特性的,,也就是說(shuō)需要用多少個(gè)u32的cell來(lái)描述該地址域。同理可以推斷#size-cells的含義,,下面對(duì)reg的描述中會(huì)給出更詳細(xì)的信息,。

chosen node主要用來(lái)描述由系統(tǒng)firmware指定的runtime parameter。如果存在chosen這個(gè)node,其parent node必須是名字是“/”的根節(jié)點(diǎn),。原來(lái)通過(guò)tag list傳遞的一些linux kernel的運(yùn)行時(shí)參數(shù)可以通過(guò)Device Tree傳遞,。例如command line可以通過(guò)bootargs這個(gè)property這個(gè)屬性傳遞;initrd的開(kāi)始地址也可以通過(guò)linux,initrd-start這個(gè)property這個(gè)屬性傳遞,。在本例中,,chosen節(jié)點(diǎn)是空的,在實(shí)際中,,建議增加一個(gè)bootargs的屬性,,例如:

"root=/dev/nfs nfsroot=1.1.1.1:/nfsboot ip=1.1.1.2:1.1.1.1:1.1.1.1:255.255.255.0::usbd0:off console=ttyS0,115200 mem=64M@0x30000000"

通過(guò)該command line可以控制內(nèi)核從usbnet啟動(dòng),當(dāng)然,,具體項(xiàng)目要相應(yīng)修改command line以便適應(yīng)不同的需求,。我們知道,device tree用于HW platform識(shí)別,,runtime parameter傳遞以及硬件設(shè)備描述,。chosen節(jié)點(diǎn)并沒(méi)有描述任何硬件設(shè)備節(jié)點(diǎn)的信息,它只是傳遞了runtime parameter,。

aliases 節(jié)點(diǎn)定義了一些別名,。為何要定義這個(gè)node呢?因?yàn)镈evice tree是樹(shù)狀結(jié)構(gòu),,當(dāng)要引用一個(gè)node的時(shí)候要指明相對(duì)于root node的full path,,例如/node-name-1/node-name-2/node-name-N。如果多次引用,,每次都要寫(xiě)這么復(fù)雜的字符串多少是有些麻煩,,因此可以在aliases 節(jié)點(diǎn)定義一些設(shè)備節(jié)點(diǎn)full path的縮寫(xiě)。skeleton.dtsi中沒(méi)有定義aliases,,下面的section中會(huì)進(jìn)一步用具體的例子描述之,。

memory device node是所有設(shè)備樹(shù)文件的必備節(jié)點(diǎn),它定義了系統(tǒng)物理內(nèi)存的layout,。device_type屬性定義了該node的設(shè)備類型,,例如cpu、serial等,。對(duì)于memory node,,其device_type必須等于memory。reg屬性定義了訪問(wèn)該device node的地址信息,,該屬性的值被解析成任意長(zhǎng)度的(address,,size)數(shù)組,具體用多長(zhǎng)的數(shù)據(jù)來(lái)表示address和size是在其parent node中定義(#address-cells和#size-cells),。對(duì)于device node,,reg描述了memory-mapped IO register的offset和length,。對(duì)于memory node,定義了該memory的起始地址和長(zhǎng)度,。

本例中的物理內(nèi)存的布局并沒(méi)有通過(guò)memory node傳遞,,其實(shí)我們可以使用command line傳遞,我們command line中的參數(shù)“mem=64M@0x30000000”已經(jīng)給出了具體的信息,。我們用另外一個(gè)例子來(lái)加深對(duì)本節(jié)描述的各個(gè)屬性以及memory node的理解,。假設(shè)我們的系統(tǒng)是64bit的,physical memory分成兩段,,定義如下:

RAM: starting address 0x0, length 0x80000000 (2GB) 
RAM: starting address 0x100000000, length 0x100000000 (4GB)

對(duì)于這樣的系統(tǒng),,我們可以將root node中的#address-cells和#size-cells這兩個(gè)屬性值設(shè)定為2,可以用下面兩種方法來(lái)描述物理內(nèi)存:

方法1:

memory@0 { 
    device_type = "memory"; 
    reg = <0x000000000 0x00000000 0x00000000 0x80000000 
              0x000000001 0x00000000 0x00000001 0x00000000>; 
};

方法2:

memory@0 { 
    device_type = "memory"; 
    reg = <0x000000000 0x00000000 0x00000000 0x80000000>; 
};

memory@100000000 { 
    device_type = "memory"; 
    reg = <0x000000001 0x00000000 0x00000001 0x00000000>; 
};

2,、s3c24xx.dtsi,。位于linux-3.14\arch\arm\boot\dts目錄下,具體該文件的內(nèi)容如下(有些內(nèi)容省略了,,領(lǐng)會(huì)精神即可,,不需要描述每一個(gè)硬件定義的細(xì)節(jié)):

#include "skeleton.dtsi"

/ { 
    compatible = "samsung,s3c24xx"; -------------------(A) 
    interrupt-parent = <&intc>; ----------------------(B)

    aliases { 
        pinctrl0 = &pinctrl_0; ------------------------(C) 
    };

    intc:interrupt-controller@4a000000 { ------------------(D) 
        compatible = "samsung,s3c2410-irq"; 
        reg = <0x4a000000 0x100>; 
        interrupt-controller; 
        #interrupt-cells = <4>; 
    };

    serial@50000000 { ----------------------(E)  
        compatible = "samsung,s3c2410-uart"; 
        reg = <0x50000000 0x4000>; 
        interrupts = <1 0 4 28>, <1 1 4 28>; 
        status = "disabled"; 
    };

    pinctrl_0: pinctrl@56000000 {------------------(F) 
        reg = <0x56000000 0x1000>;

        wakeup-interrupt-controller { 
            compatible = "samsung,s3c2410-wakeup-eint"; 
            interrupts = <0 0 0 3>,
                     <0 0 1 3>,
                     <0 0 2 3>,
                     <0 0 3 3>,
                     <0 0 4 4>,
                     <0 0 5 4>;
        }; 
    };

…… 
};

這個(gè)文件描述了三星公司的S3C24xx系列SOC family共同的硬件block信息。首先提出的問(wèn)題就是:為何定義了兩個(gè)根節(jié)點(diǎn),?按理說(shuō)Device Tree只能有一個(gè)根節(jié)點(diǎn),,所有其他的節(jié)點(diǎn)都是派生于根節(jié)點(diǎn)的。我的猜測(cè)是這樣的:Device Tree Compiler會(huì)對(duì)DTS的node進(jìn)行合并,,最終生成的DTB只有一個(gè)root node,。OK,我們下面開(kāi)始逐一分析:

(A)在描述compatible屬性之前要先描述model屬性,。model屬性指明了該設(shè)備屬于哪個(gè)設(shè)備生產(chǎn)商的哪一個(gè)model,。一般而言,我們會(huì)給model賦值“manufacturer,model”,。例如model = "samsung,s3c24xx",。samsung是生產(chǎn)商,s3c24xx是model類型,,指明了具體的是哪一個(gè)系列的SOC,。OK,現(xiàn)在我們回到compatible屬性,,該屬性的值是string list,,定義了一系列的modle(每個(gè)string是一個(gè)model)。這些字符串列表被操作系統(tǒng)用來(lái)選擇用哪一個(gè)driver來(lái)驅(qū)動(dòng)該設(shè)備,。假設(shè)定義該屬性:compatible = “aaaaaa”, “bbbbb",。那么操作操作系統(tǒng)可能首先使用aaaaaa來(lái)匹配適合的driver,,如果沒(méi)有匹配到,,那么使用字符串bbbbb來(lái)繼續(xù)尋找適合的driver,,對(duì)于本例,compatible = "samsung,s3c24xx",,這里只定義了一個(gè)modle而不是一個(gè)list,。對(duì)于root node,compatible屬性是用來(lái)匹配machine type的(在device tree代碼分析文章中會(huì)給出更細(xì)致的描述),。對(duì)于普通的HW block的節(jié)點(diǎn),,例如interrupt-controller,compatible屬性是用來(lái)匹配適合的driver的,。

(B)具體各個(gè)HW block的interrupt source是如何物理的連接到interruptcontroller的呢,?在dts文件中是用interrupt-parent這個(gè)屬性來(lái)標(biāo)識(shí)的。且慢,,這里定義interrupt-parent屬性的是root node,,難道root node會(huì)產(chǎn)生中斷到interrupt controller嗎?當(dāng)然不會(huì),,只不過(guò)如果一個(gè)能夠產(chǎn)生中斷的device node沒(méi)有定義interrupt-parent的話,,其interrupt-parent屬性就是跟隨parent node。因此,,與其在所有的下游設(shè)備中定義interrupt-parent,,不如統(tǒng)一在root node中定義了。

intc是一個(gè)lable,,標(biāo)識(shí)了一個(gè)device node(在本例中是標(biāo)識(shí)了interrupt-controller@4a000000 這個(gè)device node),。實(shí)際上,interrupt-parent屬性值應(yīng)該是是一個(gè)u32的整數(shù)值(這個(gè)整數(shù)值在Device Tree的范圍內(nèi)唯一識(shí)別了一個(gè)device node,,也就是phandle),,不過(guò),在dts文件中中,,可以使用類似c語(yǔ)言的Labels and References機(jī)制,。定義一個(gè)lable,唯一標(biāo)識(shí)一個(gè)node或者property,,后續(xù)可以使用&來(lái)引用這個(gè)lable,。DTC會(huì)將lable轉(zhuǎn)換成u32的整數(shù)值放入到DTB中,用戶層面就不再關(guān)心具體轉(zhuǎn)換的整數(shù)值了,。

關(guān)于interrupt,,我們值得進(jìn)一步描述。在Device Tree中,,有一個(gè)概念叫做interrupt tree,,也就是說(shuō)interrupt也是一個(gè)樹(shù)狀結(jié)構(gòu)。我們以下圖為例(該圖來(lái)自Power_ePAPR_APPROVED_v1.1):

it

系統(tǒng)中有一個(gè)interrrupt tree的根節(jié)點(diǎn),,device1、device2以及PCI host bridge的interrupt line都是連接到root interrupt controller的,。PCI host bridge設(shè)備中有一些下游的設(shè)備,也會(huì)產(chǎn)生中斷,,但是他們的中斷都是連接到PCI host bridge上的interrupt controller(術(shù)語(yǔ)叫做interrupt nexus),,然后報(bào)告到root interrupt controller的。每個(gè)能產(chǎn)生中斷的設(shè)備都可以產(chǎn)生一個(gè)或者多個(gè)interrupt,,每個(gè)interrupt source(另外一個(gè)術(shù)語(yǔ)叫做interrupt specifier,,描述了interrupt source的信息)都是限定在其所屬的interrupt domain中。

在了解了上述的概念后,,我們可以回頭再看看interrupt-parent這個(gè)屬性,。其實(shí)這個(gè)屬性是建立interrupt tree的關(guān)鍵屬性。它指明了設(shè)備樹(shù)中的各個(gè)device node如何路由interrupt event,。另外,,需要提醒的是interrupt controller也是可以級(jí)聯(lián)的,上圖中沒(méi)有表示出來(lái),。那么在這種情況下如何定義interrupt tree的root呢,?那個(gè)沒(méi)有定義interrupt-parent的interrupt controller就是root。

(C)pinctrl0是一個(gè)縮寫(xiě),,他是/pinctrl@56000000的別名,。這里同樣也是使用了Labels and References機(jī)制。

(D)intc(node name是interrupt-controller@4a000000 ,,我這里直接使用lable)是描述interrupt controller的device node,。根據(jù)S3C24xx的datasheet,我們知道interrupt controller的寄存器地址從0x4a000000開(kāi)始,,長(zhǎng)度為0x100(實(shí)際2451的interrupt的寄存器地址空間沒(méi)有那么長(zhǎng),,0x4a000074是最后一個(gè)寄存器),也就是reg屬性定義的內(nèi)容,。interrupt-controller屬性為空,,只是用來(lái)標(biāo)識(shí)該node是一個(gè)interrupt controller而不是interrupt nexus(interrupt nexus需要在不同的interrupt domains之間進(jìn)行翻譯,需要定義interrupt-map的屬性,,本文不涉及這部分的內(nèi)容),。#interrupt-cells 和#address-cells概念是類似的,也就是說(shuō),,用多少個(gè)u32來(lái)標(biāo)識(shí)一個(gè)interrupt source,。我們可以看到,在具體HW block的interrupt定義中都是用了4個(gè)u32來(lái)表示,,例如串口的中斷是這樣定義的:

interrupts = <1 0 4 28>, <1 1 4 28>; 

(E) 從reg屬性可以serial controller寄存器地址從0x50000000 開(kāi)始,,長(zhǎng)度為0x4000。對(duì)于一個(gè)能產(chǎn)生中斷的設(shè)備,必須定義interrupts這個(gè)屬性,。也可以定義interrupt-parent這個(gè)屬性,,如果不定義,則繼承其parent node的interrupt-parent屬性,。 對(duì)于interrupt屬性值,各個(gè)interrupt controller定義是不一樣的,,有的用3個(gè)u32表示,,有的用4個(gè)。具體上面的各個(gè)數(shù)字的解釋權(quán)歸相關(guān)的interrupt controller所有,。對(duì)于中斷屬性的具體值的描述我們會(huì)在device tree的第三份文檔-代碼分析中描述,。

(F)這個(gè)node是描述GPIO控制的。這個(gè)節(jié)點(diǎn)定義了一個(gè)wakeup-interrupt-controller 的子節(jié)點(diǎn),,用來(lái)描述有喚醒功能的中斷源,。

3、s3c2416.dtsi,。位于linux-3.14\arch\arm\boot\dts目錄下,,具體該文件的內(nèi)容如下(有些內(nèi)容省略了,領(lǐng)會(huì)精神即可,,不需要描述每一個(gè)硬件定義的細(xì)節(jié)):

#include "s3c24xx.dtsi" 
#include "s3c2416-pinctrl.dtsi"

/ { 
    model = "Samsung S3C2416 SoC";  
    compatible = "samsung,s3c2416"; ---------------A

    cpus { ----------------------------B 
        #address-cells = <1>; 
        #size-cells = <0>;

        cpu { 
            compatible = "arm,arm926ejs"; 
        }; 
    };

    interrupt-controller@4a000000 { -----------------C 
        compatible = "samsung,s3c2416-irq"; 
    };

……

};

(A)在s3c24xx.dtsi文件中已經(jīng)定義了compatible這個(gè)屬性,,在s3c2416.dtsi中重復(fù)定義了這個(gè)屬性,一個(gè)node不可能有相同名字的屬性,,具體如何處理就交給DTC了,。經(jīng)過(guò)反編譯,可以看出,,DTC是丟棄掉了前一個(gè)定義,。因此,到目前為止,,compatible = samsung,s3c2416,。在s3c24xx.dtsi文件中定義了compatible的屬性值被覆蓋了。

(B)對(duì)于根節(jié)點(diǎn),,必須有一個(gè)cpus的child node來(lái)描述系統(tǒng)中的CPU信息,。對(duì)于CPU的編址我們用一個(gè)u32整數(shù)就可以描述了,因此,,對(duì)于cpus node,,#address-cells 是1,而#size-cells是0,。其實(shí)CPU的node可以定義很多屬性,,例如TLB,cache,、頻率信息什么的,,不過(guò)對(duì)于ARM,,這里只是定義了compatible屬性就OK了,arm926ejs包括了所有的processor相關(guān)的信息,。

(C)s3c24xx.dtsi文件和s3c2416.dtsi中都有interrupt-controller@4a000000這個(gè)node,,DTC會(huì)對(duì)這兩個(gè)node進(jìn)行合并,最終編譯的結(jié)果如下:

interrupt-controller@4a000000 { 
        compatible = "samsung,s3c2416-irq"; 
        reg = <0x4a000000 0x100>; 
        interrupt-controller; 
        #interrupt-cells = <0x4>; 
        linux,phandle = <0x1>; 
        phandle = <0x1>; 
    };

4,、s3c2416-pinctrl.dtsi

  這個(gè)文件定義了pinctrl@56000000 這個(gè)節(jié)點(diǎn)的若干child node,,主要用來(lái)描述GPIO的bank信息。

5,、s3c2416-snail.dts

  這個(gè)文件應(yīng)該定義一些SOC之外的peripherals的定義,。

四、Device Tree binary格式

1,、DTB整體結(jié)構(gòu)

經(jīng)過(guò)Device Tree Compiler編譯,,Device Tree source file變成了Device Tree Blob(又稱作flattened device tree)的格式。Device Tree Blob的數(shù)據(jù)組織如下圖所示:

dt

2,、DTB header,。

對(duì)于DTB header,其各個(gè)成員解釋如下:

header field name description
magic 用來(lái)識(shí)別DTB的,。通過(guò)這個(gè)magic,,kernel可以確定bootloader傳遞的參數(shù)block是一個(gè)DTB還是tag list。
totalsize DTB的total size
off_dt_struct device tree structure block的offset
off_dt_strings device tree strings block的offset
off_mem_rsvmap offset to memory reserve map,。有些系統(tǒng),,我們也許會(huì)保留一些memory有特殊用途(例如DTB或者initrd image),或者在有些DSP+ARM的SOC platform上,,有寫(xiě)memory被保留用于ARM和DSP進(jìn)行信息交互,。這些保留內(nèi)存不會(huì)進(jìn)入內(nèi)存管理系統(tǒng)。
version 該DTB的版本,。
last_comp_version 兼容版本信息
boot_cpuid_phys 我們?cè)谀囊粋€(gè)CPU(用ID標(biāo)識(shí))上booting
dt_strings_size device tree strings block的size,。和off_dt_strings一起確定了strings block在內(nèi)存中的位置
dt_struct_size device tree structure block的size。和和off_dt_struct一起確定了device tree structure block在內(nèi)存中的位置

3,、 memory reserve map的格式描述

這個(gè)區(qū)域包括了若干的reserve memory描述符,。每個(gè)reserve memory描述符是由address和size組成。其中address和size都是用U64來(lái)描述,。


4,、device tree structure block的格式描述

device tree structure block區(qū)域是由若干的分片組成,每個(gè)分片開(kāi)始位置都是保存了token,,以此來(lái)描述該分片的屬性和內(nèi)容,。共計(jì)有5種token:

(1)FDT_BEGIN_NODE (0x00000001)。該token描述了一個(gè)node的開(kāi)始位置,緊挨著該token的就是node name(包括unit address)

(2)FDT_END_NODE (0x00000002),。該token描述了一個(gè)node的結(jié)束位置。

(3)FDT_PROP (0x00000003),。該token描述了一個(gè)property的開(kāi)始位置,,該token之后是兩個(gè)u32的數(shù)據(jù),分別是length和name offset,。length表示該property value data的size,。name offset表示該屬性字符串在device tree strings block的偏移值。length和name offset之后就是長(zhǎng)度為length具體的屬性值數(shù)據(jù),。

(4)FDT_NOP (0x00000004)。

(5)FDT_END (0x00000009),。該token標(biāo)識(shí)了一個(gè)DTB的結(jié)束位置,。

一個(gè)可能的DTB的結(jié)構(gòu)如下:

(1)若干個(gè)FDT_NOP(可選)

(2)FDT_BEGIN_NODE

              node name

              paddings

(3)若干屬性定義。

(4)若干子節(jié)點(diǎn)定義,。

(5)若干個(gè)FDT_NOP(可選)

(6)FDT_END


5,、device tree strings bloc的格式描述

device tree strings bloc定義了各個(gè)node中使用的屬性的字符串表,。由于很多屬性會(huì)出現(xiàn)在多個(gè)node中,,因此,,所有的屬性字符串組成了一個(gè)string block,。這樣可以壓縮DTB的size,。


原創(chuàng)文章,,轉(zhuǎn)發(fā)請(qǐng)注明出處,。蝸窩科技,,www.,。

轉(zhuǎn)自:http://www./linux_kenrel/dt_basic_concept.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多