本文小編為大家詳細(xì)介紹“l(fā)inux dts的作用是什么”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“l(fā)inux dts的作用是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。
成都創(chuàng)新互聯(lián)公司提供高防主機(jī)、云服務(wù)器、香港服務(wù)器、四川雅安電信機(jī)房等
在linux中,dts是設(shè)備樹(shù)源文件,用于描述設(shè)備信息的;設(shè)備樹(shù)技術(shù)將設(shè)備的硬件資源信息就寫(xiě)在dts文件中。設(shè)備樹(shù)源文件dts被編譯成dtb二進(jìn)制,在bootloader運(yùn)行時(shí)傳遞給操作系統(tǒng),操作系統(tǒng)對(duì)其進(jìn)行解析展開(kāi),從而產(chǎn)生一個(gè)硬件設(shè)備的拓?fù)鋱D,有了這個(gè)拓?fù)鋱D,在編成過(guò)程可以直接通過(guò)系統(tǒng)提供的接口獲取到設(shè)備樹(shù)的節(jié)點(diǎn)和屬性信息。
設(shè)備樹(shù)(dt:device tree)是linux內(nèi)核采用的參數(shù)表示和傳遞技術(shù),在系統(tǒng)引導(dǎo)啟動(dòng)階段進(jìn)行設(shè)備初始化的時(shí)候,將設(shè)備樹(shù)中描述的硬件信息傳遞給操作系統(tǒng);
dts(device tree source):設(shè)備樹(shù)源文件,描述設(shè)備信息的;
設(shè)備樹(shù)源文件dts被編譯成dtb二進(jìn)制,在bootloader運(yùn)行時(shí)傳遞給操作系統(tǒng),操作系統(tǒng)對(duì)其進(jìn)行解析展開(kāi),從而產(chǎn)生一個(gè)硬件設(shè)備的拓?fù)鋱D,有了這個(gè)拓?fù)鋱D,在編成過(guò)程可以直接通過(guò)系統(tǒng)提供的接口獲取到設(shè)備樹(shù)的節(jié)點(diǎn)和屬性信息
dtc(device tree compiler):設(shè)備樹(shù)編譯/反編譯/調(diào)試工具;
dtb(device tree binary):二進(jìn)制設(shè)備樹(shù)鏡像;
dtsi(device tree source include):功能類(lèi)似設(shè)備樹(shù)文件的頭文件,可以被dts文件通過(guò)include引用,dtsi文件一般是描述共性部分;
在設(shè)備驅(qū)動(dòng)源碼中,分為驅(qū)動(dòng)代碼和設(shè)備代碼,驅(qū)動(dòng)代碼是操作硬件的方法,設(shè)備代碼是硬件資源、數(shù)據(jù),當(dāng)驅(qū)動(dòng)代碼和設(shè)備代碼匹配時(shí)就會(huì)調(diào)用驅(qū)動(dòng)的probe函數(shù),probe函數(shù)會(huì)利用設(shè)備代碼的資源去初始化設(shè)備;
設(shè)備樹(shù)之前,設(shè)備代碼都是直接寫(xiě)在內(nèi)核源碼中的,以platform_device結(jié)構(gòu)體的形式存在,驅(qū)動(dòng)代碼和設(shè)備代碼也是在platform總線上匹配,當(dāng)需要修改設(shè)備資源時(shí),就需要修改內(nèi)核源碼;
設(shè)備樹(shù)技術(shù)將設(shè)備的硬件資源信息就寫(xiě)在dts文件中,需要修改就修改dts文件,不必在修改內(nèi)核源碼;
不采用設(shè)備樹(shù)技術(shù):內(nèi)核源碼中會(huì)充斥大量設(shè)備硬件描述信息,導(dǎo)致內(nèi)核源碼不停增多,但是增多的硬件描述信息代碼和內(nèi)核功能并不相關(guān);
采用設(shè)備樹(shù)技術(shù)之后:設(shè)備的硬件描述信息都在dts文件中,修改方便,但是內(nèi)核要增加解析dts文件格式的代碼;
驅(qū)動(dòng)開(kāi)發(fā)者根據(jù)硬件編寫(xiě)/修改dts文件,使得將來(lái)驅(qū)動(dòng)代碼能匹配到合適的設(shè)備硬件信息;
編譯內(nèi)核時(shí),kernel會(huì)先編譯出dtc,然后再用dtc將dts文件編譯成dtb;
uboot啟動(dòng)kernel時(shí),將內(nèi)核鏡像和dtb都重定位到內(nèi)存,并告訴內(nèi)核dtb的所在內(nèi)存地址;
內(nèi)核啟動(dòng)初期調(diào)用內(nèi)部函數(shù)解析dtb,得到硬件信息后再組裝成硬件函數(shù),最后去和驅(qū)動(dòng)代碼進(jìn)行匹配;
4.1、dts文件在內(nèi)核源碼中的存放位置
arm架構(gòu):arch/arm/boot/dts目錄中
4.2、dts文件格式簡(jiǎn)介
注釋用/* */,注意#開(kāi)頭的不是注釋
分號(hào)是段落塊之間的分隔符,{}和[]和<>是段落塊的封裝符號(hào),和C語(yǔ)言語(yǔ)言類(lèi)
/dts-v1/節(jié)點(diǎn),表示dts的版本號(hào),目前都是v1
/{}是根節(jié)點(diǎn)root node,理論上只應(yīng)該有一個(gè)根節(jié)點(diǎn),有說(shuō)法dtc會(huì)合并所有root node為同一個(gè)
dts是樹(shù)狀的多節(jié)點(diǎn)組織,基本單元是node,除root外其他node都有parent,還可以有child
4.3、節(jié)點(diǎn)格式
4.3.1、格式定義
[label:] <node-name> [@<unit-address>]{
[property]
[child nodes]
[child nodes]
......
};
4.3.2、格式解讀
[]:表示該項(xiàng)可以省略,<>:表示不可省略;
[label:]:label是標(biāo)簽名,為了方便訪問(wèn)節(jié)點(diǎn),后面可以直接通過(guò)&label來(lái)訪問(wèn)該節(jié)點(diǎn)。
node-name:節(jié)點(diǎn)名稱(chēng)。根節(jié)點(diǎn)的名稱(chēng)必須是/
[@unit-address]:unit-address是設(shè)備地址,如cpu node就是0、1這種,reg node就是0x12010000這種;
4.3.3、示例代碼
cpus {
/* 下面三項(xiàng)是cpus節(jié)點(diǎn)的屬性 */
#address-cells = <1>;
#size-cells = <0>;
enable-method = "hisilicon,hi3516dv300";
/* 下面是子節(jié)點(diǎn) */
cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a7";
clock-frequency = <HI3516DV300_FIXED_1000M>;
reg = <0>;
};
};
cpus是cpu的父節(jié)點(diǎn),從形式來(lái)能直觀的看出來(lái),cpu節(jié)點(diǎn)是被cpus節(jié)點(diǎn)的大括號(hào)括起來(lái)的;
cpus節(jié)點(diǎn)省略了標(biāo)簽名和設(shè)備地址,只有節(jié)點(diǎn)名稱(chēng);
5.1、GPIO屬性格式
/{
gpx1:gpx1{
controller;
#gpio-cells=<2>;
};
key@11400c24{
compatible="fs4412,key";
reg=<0x11400c24 0x4>;
intn-key=<&gpx1 2 2>;
}
}
gpio-controller:說(shuō)明該節(jié)點(diǎn)描述的是一個(gè)gpio控制器;
#gpio-cells:描述gpio使用節(jié)點(diǎn)的屬性一個(gè)cell的內(nèi)容;
5.2、compatible屬性格式
uart0: uart@120a0000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x120a0000 0x1000>;
interrupts = <0 6 4>;
clocks = <&clock HI3516DV300_UART0_CLK>;
clock-names = "apb_pclk";
status = "disabled";
};
/* 在驅(qū)動(dòng)中對(duì)應(yīng)的結(jié)構(gòu)體*/
//struct device_driver->of_match_table->compatible
struct of_device_id {
char name[32];
char type[32];
char compatible[128];
const void *data;
};
(1)compatible屬性是用于設(shè)備節(jié)點(diǎn)和設(shè)備驅(qū)動(dòng)匹配用的,在內(nèi)核描述驅(qū)動(dòng)的structdevice_driver結(jié)構(gòu)體中,compatible變量中就會(huì)保存用于匹配的字符串,當(dāng)設(shè)備節(jié)點(diǎn)和驅(qū)動(dòng)的
compatible相同時(shí)就匹配成功;
(2)compatible后面可以有多個(gè)字符串,優(yōu)先匹配靠前的字符串,靠前的字符串匹配不上才會(huì)匹配后面的字符串;
5.3、model屬性格式
/ {
model = "Tyr DEMO Board";
compatible = "hisilicon,hi3516dv300";
memory {
device_type = "memory";
reg = <0x82000000 0x20000000>;
};};
(1)model是描述模塊信息的,一般只有根節(jié)點(diǎn)才有,標(biāo)明設(shè)備樹(shù)文件對(duì)應(yīng)的開(kāi)發(fā)板的名稱(chēng);
(2)在內(nèi)核的啟動(dòng)打印中可以看到model的值:“OF: fdt:Machine model: Tyr DEMO Board”;
5.4、status屬性格式
&uart0 {
status = "okay";
};
狀態(tài)值 | 含義 |
---|---|
okey | 表示設(shè)備是可操作的 |
disabled | 表示當(dāng)前不可操作,但是后續(xù)是可以更改為可操作性的 |
fail、failed | 表示有嚴(yán)重錯(cuò)誤,幾乎不可能再可操作了 |
(1)status描述設(shè)備信息狀態(tài),在設(shè)備樹(shù)文件中可以根據(jù)需求設(shè)置模塊的狀態(tài),功能就是開(kāi)啟/關(guān)閉某個(gè)模塊;
(2)在dtsi文件中,默認(rèn)都是關(guān)閉模塊的,在開(kāi)發(fā)板對(duì)應(yīng)的dts文件中自己去打開(kāi)需要的模塊;
5.5、reg屬性格式
clock: clock@12010000 {
compatible = "hisilicon,hi3516dv300-clock";
#address-cells = <1>; /* 表示reg里面的數(shù)據(jù)address占用一個(gè)字長(zhǎng)*/
#size-cells = <1>; /* 表示reg里面的數(shù)據(jù)size占用一個(gè)字長(zhǎng),注意字長(zhǎng)不是字節(jié)*/
#clock-cells = <1>;
#reset-cells = <2>;
reg = <0x12010000 0x1000>; /*起始地址是0x12010000,長(zhǎng)度是0x1000*/
};
reg屬性:配置某個(gè)硬件模塊對(duì)應(yīng)的地址范圍信息;
#address-cells屬性:表示reg里面的數(shù)據(jù)address占用的字長(zhǎng),注意字長(zhǎng)不是字節(jié);
#size-cells:表示reg里面的數(shù)據(jù)size占用的字長(zhǎng),注意字長(zhǎng)不是字節(jié);
reg = <address1 length2 address2 length3 …>:address一般用來(lái)表示起始地址,length一般表示持續(xù)長(zhǎng)度;
5.6、中斷屬性格式
gic: interrupt-controller@10300000 {
compatible = "arm,cortex-a7-gic";
#interrupt-cells = <3>; /*表示interrupts用三個(gè)cell來(lái)描述中斷*/
#address-cells = <0>;
interrupt-controller; /*標(biāo)明gic節(jié)點(diǎn)是中斷控制器*/
/* gic dist base, gic cpu base , no virtual support */
reg = <0x10301000 0x1000>, <0x10302000 0x100>;
};
ipcm: ipcm@045E0000 {
compatible = "hisilicon,ipcm-interrupt";
interrupt-parent = <&gic>; /*父節(jié)點(diǎn)是gic節(jié)點(diǎn)*/
interrupts = <0 10 4>; /*<中斷域 中斷 觸發(fā)方式>*/
reg = <0x10300000 0x4000>;
status = "okay";
};
(1)interrupt-controller:無(wú)值屬性,表示這是個(gè)中斷控制器node
(2)#interrupt-cells:這是中斷控制器節(jié)點(diǎn)的屬性,用來(lái)標(biāo)識(shí)這個(gè)控制器需要幾個(gè)cell做中斷描述符
(3)interrupt-parent:標(biāo)識(shí)此設(shè)備節(jié)點(diǎn)屬于哪一個(gè)中斷控制器,如果沒(méi)有這個(gè)屬性,會(huì)自動(dòng)依附父節(jié)點(diǎn)
(4)interrupts :一個(gè)中斷標(biāo)識(shí)符列表,表示每一個(gè)中斷輸出信號(hào)
6.1、chosen子節(jié)點(diǎn)
6.1.1、chosen子節(jié)點(diǎn)功能介紹
chosen {
stdout-path = "serial0:115200n8";
};
(1)chosen子節(jié)點(diǎn)不對(duì)應(yīng)真實(shí)的設(shè)備,是用來(lái)描述內(nèi)核啟動(dòng)參數(shù)的,對(duì)應(yīng)于uboot啟動(dòng)內(nèi)核時(shí)傳遞的bootargs參數(shù);
(2)上面是摘抄的內(nèi)核dts文件中的chosen子節(jié)點(diǎn),里面只設(shè)置了stdout-path屬性,也就是把輸出設(shè)置成串口0,波特率是115200;
(3)dts文件中設(shè)置的屬性會(huì)被覆蓋點(diǎn),具體就是uboot在啟動(dòng)內(nèi)核時(shí),會(huì)將bootargs啟動(dòng)參數(shù)轉(zhuǎn)換成chosen子節(jié)點(diǎn)的屬性,替換掉dts文件中設(shè)置的屬性;
6.1.2、chosen子節(jié)點(diǎn)在內(nèi)核中的體現(xiàn)
~ # ls /proc/device-tree/chosen/
bootargs name
~ #
~ # cat /proc/device-tree/chosen/bootargs
mem=1408M console=ttyS0,115200 root=/dev/mmcblk0p7 rootfstype=squashfs rootwait
~ #
~ # cat /proc/device-tree/chosen/name
chosen
~ #
6.2、aliases子節(jié)點(diǎn)
aliases {
serial0 = &uart0;
gpio0 = &gpio_chip0;
gpio1 = &gpio_chip1;
gpio2 = &gpio_chip2;
······
};
aliases就是別名的意思,aliases節(jié)點(diǎn)主要功能就是給節(jié)點(diǎn)定義別名,為了方便訪問(wèn)節(jié)點(diǎn)。不過(guò)我們?cè)诠?jié)點(diǎn)命名的時(shí)候可以加上label標(biāo)簽,直接通過(guò)&label引用標(biāo)簽來(lái)訪問(wèn)也很方便,aliases節(jié)點(diǎn)內(nèi)部其實(shí)也是通過(guò)引用標(biāo)簽名來(lái)定義別名;
7.1、節(jié)點(diǎn)引用和內(nèi)容替換
gpio_chip1: gpio_chip@120d1000 {
compatible = "arm,pl061", "arm,primecell";
reg = <0x120d1000 0x1000>;
interrupts = <0 17 4>;
clocks = <&clock HI3516DV300_SYSAPB_CLK>;
clock-names = "apb_pclk";
#gpio-cells = <2>;
status = "disabled";
};
/*引用gpio_chip1節(jié)點(diǎn)*/
&gpio_chip1 {
status = "okay"; /*替換status屬性?xún)?nèi)容*/
};
對(duì)于已經(jīng)定義好的節(jié)點(diǎn),我們通過(guò)引用節(jié)點(diǎn)的方式,重新定義某些屬性,效果上看就是替換掉某些屬性的值;
7.2、合并節(jié)點(diǎn)內(nèi)容
/{
node{
key1=value1;
}
}
/{
node{
key2=value2;
}
}
//合并的結(jié)果
/{
node{
key1=value1;
key2=value2;
}
}
有時(shí)候我們需要增加硬件描述的信息,這時(shí)候就可以在后面創(chuàng)新定義該節(jié)點(diǎn),最后解析的時(shí)候會(huì)把同名節(jié)點(diǎn)不同的部分進(jìn)行合并。
讀到這里,這篇“l(fā)inux dts的作用是什么”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
文章題目:linuxdts的作用是什么
新聞來(lái)源:http://www.rwnh.cn/article10/jdgego.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、響應(yīng)式網(wǎng)站、微信小程序、網(wǎng)站內(nèi)鏈、網(wǎng)站維護(hù)、搜索引擎優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)