編譯dts
你用的linux內核是什麼版本?如果是3.0以上的版本,有arm/arm/boot/dts
❷ 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
❸ 編譯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
❹ 如何編譯高通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標准給出了結點命名的規范。
❺ 嵌入式linux 修改dts文件同時需要修改preloader么
U-Boot 引入了扁平設備樹FDT 這樣的動態介面,使用一個單獨的FDT blob(二進制大對象,是一個可以存儲二進制文件的容器)存儲傳遞給內核的參數[3]。一些確定信息,例如cache 大小、中斷路由等直接由設備樹提供,而其他的信息,例如eTSEC 的MAC 地址、頻率、PCI 匯流排數目等由U-Boot 在運行時修改。U-Boot 使用扁平設備樹取代了bd_t,而且也不再保證對bd_t 的後向兼容。需要修改的,重新編譯dts文件。
❻ linux編譯u-boot時顯示[arch/arm/dts/zynq-zc702.dtb]錯誤
在編譯uboot的時候,會出現出錯,因此我們要首先做 make disclean. 將原來的一些中間文件清理干凈。
因此在編譯Uboot依次執行 1.make disclean
2.make smdk2440_config
3. make
就可以編譯通過了
❼ odt在dts設置
在源碼中直接修改board.dts文件->重新編譯&打包->燒寫到設備里。
在設備BSP調試的過程中,經常會出現需要修改DTS的情況,比如調試一個新的屏幕、感測器或者wifi模組,傳統的方法是:在源碼中直接修改board.dts文件->重新編譯&打包->燒寫到設備里這種方法繁雜,編譯和燒寫都要花費時間,嚴重影響開發效率。
因此,全志(其實是uboot提供的)提供了一個啟動階段DTS調試的方法,可以讓我們在啟動階段就把DTS改掉,這次啟動載入的就是改後的DTS。*註:這種修改是一次性的,不可以保存的,只限這次啟動的時候生效,斷電或者重啟就不生效了1.設備上電過程中串口按住電腦鍵盤的"s"按鍵,讓設備進入boot:*註:是真的按住調試的電腦的鍵盤的s按鍵,和按住2另設備跳燒錄的操作一樣。如果進入boot成功,就會有如下log,這時就可以在串口對設備進行DTS修改操作。
❽ Ubuntu編譯u-boot時顯示[arch/arm/dts/zynq-zc702.dtb]錯誤
最好貼上完整的log,這樣才知道整個狀況。
❾ 如何將dtb反編譯成dts
由於device tree會將一個node的信息分布在各個文件里,查看起來很不方便,比如如下例子,ldb在三個文件中都有配置:
imx6qdl-sabresd.dtsi:
&ldb {
status = "okay";
.......
};
imx6qdl.dtsi:
ldb: ldb@020e0008 {
#address-cells = <1>;
#size-cells = <0>;
......
};
imx6q.dtsi:
&ldb {
compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb";
.......
}
其實device tree編譯之後最終是會被全部放在一個.dtb結尾的文件,
比如這里是imx6q-sabresd-ldo.dtb,用如下命令就可以看到整個ldb node的內容,而且也可以作為編譯之後的檢查。
[kris@ecovacs:~/kernel_imx/scripts/dtc]$
./dtc -I dtb -O dts ../../arch/arm/boot/dts/imx6q-sabresd-ldo.dtb > ~/f.dts
❿ linux載入dts的時候會創建設備節點嗎
From:http://m.blog.csdn.net/blog/liliyaya/9188193
1. 在\kernel\of\fdt.c 中有如下初始化函數 注釋上:展開設備樹,創建device_nodes到全局變數allnodes中
void __init unflatten_device_tree(void)
{
__unflatten_device_tree(initial_boot_params, &allnodes,
early_init_dt_alloc_memory_arch);
/* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */
of_alias_scan(early_init_dt_alloc_memory_arch);
}
unflatten_device_tree函數被setup_arch函數調用,
因為我們使用得是arm平台所以存在\kernel\arch\arm\kernel\setup.c中
void __init setup_arch(char **cmdline_p)
{
unflatten_device_tree()
}
setup_arch函數在kernel啟動是被調用,如下啟動kernel存在\kernel\init\main.c中
asmlinkage void __init start_kernel(void)
{
setup_arch(&command_line);
}
這些工作完成解析DTS文件。保存到全局鏈表allnodes中。
2、在makefile中有這段話來編譯dts文件:
$(obj)/A20%.dtb: $(src)/dts/A20%.dts FORCE
$(call if_changed_dep,dtc)
$(obj)/A68M%.dtb: $(src)/dts/A68M%.dts FORCE
$(call if_changed_dep,dtc)
和.c文件生成.o文件一樣 回生成.dtb文件。在
/home/liyang/workspace/SZ_JB-mr1-8628-bsp-1012/out/target/proct/msm8226/obj/KERNEL_OBJ/arch/arm/boot
目錄下,與zimage一個目錄。
3、
在 board-8226.c中有初始化函數-->啟動自動掉用
void __init msm8226_init(void)
{
of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
}
of_platform_populate在kernel\driver\of\platform.c中定義,回查詢
root = root ? of_node_get(root) : of_find_node_by_path("/");
for_each_child_of_node(root, child)
{
rc = of_platform_bus_create(child, matches, lookup, parent, true);
if (rc)
break;
}
of_node_put(root);
在這里用到得函數of_find_node_by_path會最終調用到kernel\driver\of\base.c中得函數
struct device_node *of_find_node_by_path(const char *path)
{
遍歷第1步中得allnodes找到根節點
}
of_platform_bus_create()函數中創建得內容存在了 adata中。
以下內容為轉載:
(2)使用DTS注冊匯流排設備的過程
以高通8974平台為例,在注冊i2c匯流排時,會調用到qup_i2c_probe()介面,該介面用於申請匯流排資源和添加i2c適配器。在成功添加i2c適配器後,會調用of_i2c_register_devices()介面。此介面會解析i2c匯流排節點的子節點(掛載在該匯流排上的i2c設備節點),獲取i2c設備的地址、中斷號等硬體信息。然後調用request_mole()載入設備對應的驅動文件,調用i2c_new_device(),生成i2c設備。此時設備和驅動都已載入,於是drvier裡面的probe方法將被調用。後面流程就和之前一樣了。
簡而言之,Linux採用DTS描述設備硬體信息後,省去了大量板文件垃圾信息。Linux在開機啟動階段,會解析DTS文件,保存到全局鏈表allnodes中,在掉用.init_machine時,會跟據allnodes中的信息注冊平台匯流排和設備。值得注意的是,載入流程並不是按找從樹根到樹葉的方式遞歸注冊,而是只注冊根節點下的第一級子節點,第二級及之後的子節點暫不注冊。Linux系統下的設備大多都是掛載在平台匯流排下的,因此在平台匯流排被注冊後,會根據allnodes節點的樹結構,去尋找該匯流排的子節點,所有的子節點將被作為設備注冊到該匯流排上。