dts文件能否單獨編譯
A. 嵌入式linux 修改dts文件同時需要修改preloader么
U-Boot 引入了扁平設備樹FDT 這樣的動態介面,使用一個單獨的FDT blob(二進制大對象,是一個可以存儲二進制文件的容器)存儲傳遞給內核的參數[3]。一些確定信息,例如cache 大小、中斷路由等直接由設備樹提供,而其他的信息,例如eTSEC 的MAC 地址、頻率、PCI 匯流排數目等由U-Boot 在運行時修改。U-Boot 使用扁平設備樹取代了bd_t,而且也不再保證對bd_t 的後向兼容。需要修改的,重新編譯dts文件。
B. 如何編譯高通kernal設備樹
DTS (device tree source)
.dts文件是一種ASCII 文本格式的Device
Tree描述,此文本格式非常人性化,適合人類的閱讀習慣。基本上,在ARM
Linux在,一個。dts文件對應一個ARM的machine,一般放置在內核的arch/arm/boot/dts/目錄。由於一個SoC可能對應多個machine(一個SoC可以對應多個產品和電路板),勢必這些。dts文件需包含許多共同的部分,Linux內核為了簡化,把SoC公用的部分或者多個machine共同的部分一般提煉為。dtsi,類似於C語言的頭文件。其他的machine對應的。dts就include這個。dtsi。譬如,對於VEXPRESS而言,vexpress-v2m.dtsi就被vexpress-v2p-ca9.dts所引用,
vexpress-v2p-ca9.dts有如下一行:
/include/
「vexpress-v2m.dtsi」
當然,和C語言的頭文件類似,。dtsi也可以include其他的。dtsi,譬如幾乎所有的ARM
SoC的。dtsi都引用了skeleton.dtsi。
.dts(或者其include的。dtsi)基本元素即為前文所述的結點和屬性:
[plain] view
plainprint?
/ {
node1 {
a-string-property = 「A string」;
a-string-list-property = 「first string」, 「second string」;
a-byte-data-property = [0x01 0x23 0x34 0x56];
child-node1 {
first-child-property;
second-child-property = <1>;
a-string-property = 「Hello, world」;
};
child-node2 {
};
};
node2 {
an-empty-property;
a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
child-node1 {
};
};
};
/ {
node1 {
a-string-property = 「A string」;
a-string-list-property = 「first string」, 「second string」;
a-byte-data-property = [0x01 0x23 0x34 0x56];
child-node1 {
first-child-property;
second-child-property = <1>;
a-string-property = 「Hello, world」;
};
child-node2 {
};
};
node2 {
an-empty-property;
a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
child-node1 {
};
};
};
上述。dts文件並沒有什麼真實的用途,但它基本表徵了一個Device
Tree源文件的結構:
1個root結點「/」;
root結點下面含一系列子結點,本例中為「node1」 和
「node2」;
結點「node1」下又含有一系列子結點,本例中為「child-node1」 和
「child-node2」;
各結點都有一系列屬性。這些屬性可能為空,如「
an-empty-property」;可能為字元串,如「a-string-property」;可能為字元串數組,如「a-string-list-property」;可能為Cells(由u32整數組成),如「second-child-property」,可能為二進制數,如「a-byte-data-property」。
下面以一個最簡單的machine為例來看如何寫一個。dts文件。假設此machine的配置如下:
1個雙核ARM
Cortex-A9 32位處理器;
ARM的local bus上的內存映射區域分布了2個串口(分別位於0x101F1000 和
0x101F2000)、GPIO控制器(位於0x101F3000)、SPI控制器(位於0x10170000)、中斷控制器(位於0x10140000)和一個external
bus橋;
External bus橋上又連接了SMC SMC91111
Ethernet(位於0x10100000)、I2C控制器(位於0x10160000)、64MB NOR
Flash(位於0x30000000);
External bus橋上連接的I2C控制器所對應的I2C匯流排上又連接了Maxim
DS1338實時鍾(I2C地址為0x58)。
其對應的。dts文件為:
[plain] view
plainprint?
/ {
compatible = 「acme,coyotes-revenge」;
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = 「arm,cortex-a9」;
reg = <0>;
};
cpu@1 {
compatible = 「arm,cortex-a9」;
reg = <1>;
};
};
serial@101f0000 {
compatible = 「arm,pl011」;
reg = <0x101f0000 0x1000 >;
interrupts = < 1 0 >;
};
serial@101f2000 {
compatible = 「arm,pl011」;
reg = <0x101f2000 0x1000 >;
interrupts = < 2 0 >;
};
gpio@101f3000 {
compatible = 「arm,pl061」;
reg = <0x101f3000 0x1000
0x101f4000 0x0010>;
interrupts = < 3 0 >;
};
intc: interrupt-controller@10140000 {
compatible = 「arm,pl190」;
reg = <0x10140000 0x1000 >;
interrupt-controller;
#interrupt-cells = <2>;
};
spi@10115000 {
compatible = 「arm,pl022」;
reg = <0x10115000 0x1000 >;
interrupts = < 4 0 >;
};
external-bus {
#address-cells = <2>
#size-cells = <1>;
ranges = <0 0 0x10100000 0x10000 // Chipselect 1, Ethernet
1 0 0x10160000 0x10000 // Chipselect 2, i2c controller
2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flash
ethernet@0,0 {
compatible = 「smc,smc91c111」;
reg = <0 0 0x1000>;
interrupts = < 5 2 >;
};
i2c@1,0 {
compatible = 「acme,a1234-i2c-bus」;
#address-cells = <1>;
#size-cells = <0>;
reg = <1 0 0x1000>;
interrupts = < 6 2 >;
rtc@58 {
compatible = 「maxim,ds1338」;
reg = <58>;
interrupts = < 7 3 >;
};
};
flash@2,0 {
compatible = 「samsung,k8f1315ebm」, 「cfi-flash」;
reg = <2 0 0x4000000>;
};
};
};
/ {
compatible = 「acme,coyotes-revenge」;
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = 「arm,cortex-a9」;
reg = <0>;
};
cpu@1 {
compatible = 「arm,cortex-a9」;
reg = <1>;
};
};
serial@101f0000 {
compatible = 「arm,pl011」;
reg = <0x101f0000 0x1000 >;
interrupts = < 1 0 >;
};
serial@101f2000 {
compatible = 「arm,pl011」;
reg = <0x101f2000 0x1000 >;
interrupts = < 2 0 >;
};
gpio@101f3000 {
compatible = 「arm,pl061」;
reg = <0x101f3000 0x1000
0x101f4000 0x0010>;
interrupts = < 3 0 >;
};
intc: interrupt-controller@10140000 {
compatible = 「arm,pl190」;
reg = <0x10140000 0x1000 >;
interrupt-controller;
#interrupt-cells = <2>;
};
spi@10115000 {
compatible = 「arm,pl022」;
reg = <0x10115000 0x1000 >;
interrupts = < 4 0 >;
};
external-bus {
#address-cells = <2>
#size-cells = <1>;
ranges = <0 0 0x10100000 0x10000 // Chipselect 1, Ethernet
1 0 0x10160000 0x10000 // Chipselect 2, i2c controller
2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flash
ethernet@0,0 {
compatible = 「smc,smc91c111」;
reg = <0 0 0x1000>;
interrupts = < 5 2 >;
};
i2c@1,0 {
compatible = 「acme,a1234-i2c-bus」;
#address-cells = <1>;
#size-cells = <0>;
reg = <1 0 0x1000>;
interrupts = < 6 2 >;
rtc@58 {
compatible = 「maxim,ds1338」;
reg = <58>;
interrupts = < 7 3 >;
};
};
flash@2,0 {
compatible = 「samsung,k8f1315ebm」, 「cfi-flash」;
reg = <2 0 0x4000000>;
};
};
};
上述。dts文件中,root結點「/」的compatible 屬性compatible =
「acme,coyotes-revenge」;定義了系統的名稱,它的組織形式為:<manufacturer>,<model>。Linux內核透過root結點「/」的compatible
屬性即可判斷它啟動的是什麼machine。
在。dts文件的每個設備,都有一個compatible
屬性,compatible屬性用戶驅動和設備的綁定。compatible
屬性是一個字元串的列表,列表中的第一個字元串表徵了結點代表的確切設備,形式為「<manufacturer>,<model>」,其後的字元串表徵可兼容的其他設備。可以說前面的是特指,後面的則涵蓋更廣的范圍。如在arch/arm/boot/dts/vexpress-v2m.dtsi中的Flash結點:
[plain] view
plainprint?
flash@0,00000000 {
compatible = 「arm,vexpress-flash」, 「cfi-flash」;
reg = <0 0x00000000 0x04000000>,
<1 0x00000000 0x04000000>;
bank-width = <4>;
};
flash@0,00000000 {
compatible = 「arm,vexpress-flash」, 「cfi-flash」;
reg = <0 0x00000000 0x04000000>,
<1 0x00000000 0x04000000>;
bank-width = <4>;
};
compatible屬性的第2個字元串「cfi-flash」明顯比第1個字元串「arm,vexpress-flash」涵蓋的范圍更廣。
再比如,Freescale
MPC8349 SoC含一個串口設備,它實現了國家半導體(National Semiconctor)的ns16550
寄存器介面。則MPC8349串口設備的compatible屬性為compatible = 「fsl,mpc8349-uart」,
「ns16550」。其中,fsl,mpc8349-uart指代了確切的設備, ns16550代表該設備與National Semiconctor
的16550
UART保持了寄存器兼容。
接下來root結點「/」的cpus子結點下面又包含2個cpu子結點,描述了此machine上的2個CPU,並且二者的compatible
屬性為「arm,cortex-a9」。
注意cpus和cpus的2個cpu子結點的命名,它們遵循的組織形式為:<name>[@<unit-address>],<>中的內容是必選項,[]中的則為可選項。name是一個ASCII字元串,用於描述結點對應的設備類型,如3com
Ethernet適配器對應的結點name宜為ethernet,而不是3com509。如果一個結點描述的設備有地址,則應該給出@unit-address。多個相同類型設備結點的name可以一樣,只要unit-address不同即可,如本例中含有cpu@0、cpu@1以及serial@101f0000與serial@101f2000這樣的同名結點。設備的unit-address地址也經常在其對應結點的reg屬性中給出。ePAPR標准給出了結點命名的規范。
C. 編譯linux內核設備樹文件使用什麼命令
Linux源碼的arch/powerpc/boot/dts/目錄下存放了很多dts文件,可以作為參考文件。另外dtc編譯器在內核源碼2.6.25版本之後已經被包含進去。在2.6.26版本之後,生成blob的簡單規則已經加入makefile,如下命令:
$ make ARCH=powerpc canyonlands.dtb
也可以根據自己的硬體修改好dts文件後,用下面類似命令生成dtb文件。
$ dtc -f -I dts -O dtb -R 8 -S 0x3000 test.dts > mpc836x_mds.dtb
$ mkimage -A ppc -O Linux -T flat_dt -C none -a 0x300000 -e 0 -d mpc836x_mds.dtb mpc836x_mds.dtu
D. linux怎麼調用dts生成dtb
dtb文件作用的描述是,使用dtb可以減少linux內核版本的數量。同一份linux 內核代碼可以在多個板卡上運行,每個板卡可以使用自己的dtb文件。
1,在linux內核啟動過程中會解析dtb文件,根據dtb文件中設備列表進行加註各個外設的驅動模塊。
2,PC機在啟動時會自動掃描外設,而在嵌入式中,linux內核啟動過程中只是解析dtb文件,從而載入對應的模塊。
3,編譯linux內核時必須選擇某外設模塊,並且dtb中包括該外設的信息。在linux內核啟動過程中才能自動載入該模塊。
要使用dtb,需要uboot啟動內核時,在bootm命令中指定dtb的位置,格式為:
bootm uImage_addr ramdisk_addr dtb_addr
如果沒有ramdisk,就需要寫成bootm uImage_addr - dtb_addr,用「-」表示沒有ramdisk