第一步就是要為這個模型機構建乙個基本結構,這是乙個有效的裝置樹最基本的結構。在這個階段你需要唯一的標識該機器。
compatible= " marvell ,armada38x"
};compatible 指定了系統的名稱。它包含了乙個「《製造商》,《型號》」形式的字串。重要的是要指定乙個確切的裝置,並且包括製造商的名子,以避免命名空間衝突。由於作業系統會使用 compatible 的值來決定如何在機器上執行,所以正確的設定這個屬性變得非常重要。
接下來就應該描述每個 cpu 了。先新增乙個名為「cpus」的容器節點,然後為每個 cpu 分別新增子節點。具體到我們的情況是乙個 arm 的 雙核 cortex a9 系統
compatible= " marvell ,armada38x";
cpus;
};每個 cpu 節點的 compatible 屬性是乙個「《製造商》,《型號》」形式的字串,並指定了確切的 cpu,就像頂層的 compatible 屬性一樣
節點名稱:現在應該花點時間來討論命名約定了。每個節點必須有乙個「《名稱》[@《裝置位址》]」形式的名字。
1).名稱》 就是乙個不超過31位的簡單 ascii 字串。通常,節點的命名應該根據它所體現的是什麼樣的裝置。比如乙個 3com 乙太網介面卡的節點就應該命名為 ethernet,而不應該是 3com509。
2).如果該節點描述的裝置有乙個位址的話就還應該加上裝置位址(unit-address)。通常,裝置位址就是用來訪問該裝置的主位址,並且該位址也在節點的 reg 屬性中列出
3).同級節點命名必須是唯一的,但只要位址不同,多個節點也可以使用一樣的通用名稱(例如 serial@101f1000 和 serial@101f2000)
裝置:系統中每個裝置都表示為乙個裝置樹節點。所以接下來就應該為這個裝置樹填充裝置節點。現在,知道我們討論如何進行定址和中斷請求如何處理之前這些新節點將一直為空。
/ ;cpu@1 ;
};serial@101f0000 ;
serial@101f2000 ;
gpio@101f3000 ;
interrupt-controller@10140000 ;
spi@10115000 ;
external-bus ;
i2c@1,0 ;
};flash@2,0 ;
};};在此樹中,已經為系統中的每個裝置新增了節點,而且這個·層次結構也反映了裝置與系統的連線方式。例如,外部匯流排上的裝置就是外部匯流排節點的子節點,i2c 裝置就是 i2c 匯流排節點的子節點。通常,這個層次結構表現的是 cpu 視角的系統檢視。現在這棵樹還是無效的,因為它缺少關於裝置之間互聯的資訊。稍後將新增這些資訊。
在這顆樹中,應該注意這些事情:
每個裝置節點都擁有乙個 compatible 屬性,
快閃儲存器(flash)節點的 compatible 屬性由兩個字串構成。欲知為何,請閱讀下一節
理解 compatible 屬性:
1).樹中每個表示乙個裝置的節點都需要乙個 compatible 屬性。compatible 屬性是作業系統用來決定使用哪個裝置驅動來繫結到乙個裝置上的關鍵因素。
2).compatible 是乙個字串列表,之中第乙個字串指定了這個節點所表示的確切的裝置,該字串的格式為:"《製造商》,《型號》"。剩下的字串的則表示其它與之相相容的裝置。
3).freescale mpc8349 片上系統(soc)擁有乙個實現了美國國家半導體 ns16550 的暫存器介面的序列裝置,那麼 mpc8349 的序列裝置的 compatible 屬性就應該是:compatible = "fsl,mpc8349-uart", "ns16550"。在這裡,mpc8349-uart 指定了確切的裝置,而 ns16550 則說明這是與美國國家半導體 ns16550 uart 的暫存器級相容
4).不要使用帶萬用字元的 compatible 值,比如「fsl,mpc83xx-uart」或類似情況。晶元提供商無不會做出一些能夠輕易打破你萬用字元猜想的變化,這時候在修改已經為時已晚了。相反,應該選擇乙個特定的晶元然後是所有後續晶元都與之相容。
如何編址:
1>可編址裝置使用以下屬性將位址資訊編碼進裝置樹
■ reg
■ #address-cells
■ #size-cells
2>每個可編址裝置都有乙個元組列表的 reg,元組的形式為:reg = 《位址1 長度1 [位址2 長度2] [位址3 長度3] ... >。每個元組都表示乙個該裝置使用的位址範圍。每個位址值是乙個或多個 32 位整型數列表,稱為 cell。同樣,長度值也可以是乙個 cell 列表或者為空。
3>由於位址和長度欄位都是可變大小的變數,那麼父節點的 #address-cells 和 #size-cells 屬性就用來宣告各個欄位的 cell 的數量。換句話說,正確解釋乙個 reg 屬性需要用到父節點的 #address-cells 和 #size-cells 的值。要知道這一切是如何運作的,我們將給模型機新增編址屬性,就從 cpu 開始。
cpu 編址:
cpu 節點表示了乙個關於編址的最簡單的例子。每個 cpu 都分配了乙個唯一的 id,並且沒有 cpu id 相關的大小資訊。
cpus ;
cpu@1 ;
};在 cpu 節點中,#address-cells 設定為 1,#size-cells 設定為 0。這意味著子節點的 reg 值是乙個單一的 uint32,這是乙個不包含大小欄位的位址,為這兩個 cpu 分配的位址是 0 和 1。cpu 節點的 #size-cells 為 0 是因為只為每個 cpu 分配乙個單獨的位址。你可能還會注意到 reg 的值和節點名字是相同的。按照慣例,如果乙個節點有 reg 屬性,那麼該節點的名字就必須包含裝置位址,這個裝置位址就是 reg 屬性裡第乙個位址值
記憶體對映裝置:
與 cpu 節點裡單一位址值不同,應該分配給記憶體對映裝置乙個位址範圍。#size-cells 宣告每個子節點的 reg 元組中長度欄位的大小。在接下來的例子中,每個位址值是 1 cell(32 位),每個長度值也是 1 cell,這是典型的 32 位系統。64 位的機器則可以使用值為 2 的 #address-cells 和 #size-cells 來獲得在裝置樹中的 64 位編址。
/ ;serial@101f2000 ;
gpio@101f3000 ;
interrupt-controller@10140000 ;
spi@10115000 ;
...};每個裝置都被分配了乙個基址以及該區域的大小。這個例子中為 gpio 分配了兩個位址範圍:0x101f3000...0x101f3fff 和 0x101f4000..0x101f400f。
一些掛在匯流排上的裝置有不同的編址方案。例如乙個帶獨立片選線的裝置也可以連線至外部匯流排。由於父節點會為其子節點定義位址域,所以可以選擇不同的位址對映來最恰當的描述該系統。下面的**展示了裝置連線至外部匯流排並將其片選號編碼進製址的位址分配
external-bus ;
i2c@1,0 ;
};flash@2,0 ;
};外部匯流排的位址值使用了兩個 cell,乙個用於片選號;另乙個則用於片選基址的偏移量。而長度欄位則還是單個 cell,這是因為只有位址的偏移部分才需要乙個範圍量。所以,在這個例子中,每個 reg 項都有三個 cell:片選號、偏移量和長度。
由於位址域是包含於乙個節點及其子節點的,所以父節點可以自由的定義任何對於該匯流排來說有意義的編址方案。那些在直接父節點和子節點以外的節點通常不關心本地位址域,而位址應該從乙個域對映到另乙個域
chosen 節點:
chosen 節點並不代表乙個真正的裝置,只是作為乙個為韌體和作業系統之間傳遞資料的地方,比如引導引數。chosen 節點裡的資料也不代表硬體。通常,chosen 節點在 .dts 原始檔中為空,並在啟動時填充。
chosen ;
裝置樹詳解dts
在linux3.x版本後,arch arm plat 和arch arm mach 中,描述板級細節的 比如platform device i2c board info等 被大量取消,取而代之的是裝置樹,其目錄位於arch arm boot dts 1個dts檔案 n個dtsi檔案,它們編譯而成的d...
dts裝置樹概述
一.字元裝置驅動基礎 1.字元裝置驅動的幾種不同寫法 在學習裝置樹之前,首先了解一下字元裝置驅動的三種寫法,參考文件 字元裝置驅動的三種寫法 這篇文章很好的描述並對比了三種字元裝置驅動的寫法及各自的優缺點。三種寫法分別為 字元裝置驅動的傳統寫法 匯流排裝置驅動模型寫法 以及接下來要介紹的dts裝置樹...
裝置樹 dts格式 語法
在之前提到過裝置樹就是平台匯流排中的平台裝置的衍生,是用於表述硬體裝置資源的,對於arm平台,裝置樹檔案存放在arch arm boot dts下,繫結文件存在documentation devicetree bindings下。我把jz2440 led 裝置樹之點亮led燈中的裝置樹檔案拷貝過來,...