設(shè)備樹
參考:https://www.pianshen.com/article/428276673/
基本概念:
設(shè)備數(shù)是一種描述硬件的數(shù)據(jù)結(jié)構(gòu)
DTS:是一個文本形式的文件,用于描述硬件信息宜肉,包括CPU的數(shù)量和類別匀钧、內(nèi)存基地址和大小、中斷控制器谬返、總線和橋之斯、外設(shè)、時鐘和GPIO控制器等遣铝。
DTSI:把soc公用的部分或者多個設(shè)備共同的部分提煉為dtsi佑刷,類似于c語言的頭文件。
DTB:是一個二進制形式的文件翰蠢,由linux內(nèi)核識別,為其中的設(shè)備匹配合適的驅(qū)動程序啰劲。
DTC:將DTS編譯成DTB
bootloader:不同的設(shè)備會有不同的machine id梁沧,uboot在啟動Linux內(nèi)核的時候會將machine id存放到r1寄存器,Linux啟動時會匹配bootloader傳遞的machine id和machine start聲明的machine id蝇裤,然后執(zhí)行相應(yīng)設(shè)備的一系列初始化函數(shù)廷支。
linux內(nèi)核啟動以后,先解析并注冊dts中的設(shè)備栓辜,然后再注冊驅(qū)動恋拍,比較驅(qū)動中的compatible 屬性和設(shè)備中的compatible 屬性,或者比較兩者的name屬性藕甩,如果一致則匹配成功施敢。
1、解析dtb
在start_kernel() --> setup_arch(0 --> unflatten_device_tree() --> __unflatten_device_tree()函數(shù)中掃描dtb,并轉(zhuǎn)換成節(jié)點是device_node的樹狀結(jié)構(gòu)僵娃。
2概作、注冊dts設(shè)備
imx6q_init_machine() --> of_platform_populate()。
在of_platform_populate()中循環(huán)掃描根節(jié)點下的各節(jié)點
調(diào)用of_platform_device_create_pdata() —> of_device_add() 注冊設(shè)備并添加到對應(yīng)的鏈表中默怨。
3讯榕、注冊驅(qū)動
4、匹配設(shè)備
追蹤driver_register()函數(shù)匙睹,driver_register() --> bus_add_driver() --> driver_attach() --> __driver_attach
尋找匹配的設(shè)備愚屁,匹配成功則執(zhí)行驅(qū)動的probe函數(shù)
根節(jié)點的兼容性:
Linux內(nèi)核根據(jù)根節(jié)點‘/’的兼容屬性可以判斷啟動什么設(shè)備
設(shè)備節(jié)點的兼容性
在.dts文件中的每一個設(shè)備節(jié)點都有一個兼容屬性况增,用于驅(qū)動和設(shè)備之間的綁定陶冷。
兼容性的設(shè)置都是從具體到抽象
使用設(shè)備樹之后,驅(qū)動需要與.dts中描述的設(shè)備節(jié)點進行匹配绿鸣,從而使驅(qū)動的probe()函數(shù)執(zhí)行谆棺,對于platform_driver栽燕,需要添加一個OF匹配表(competible)
而Linux內(nèi)核常用如下API來判斷具體設(shè)備是什么:
int of_device_is_compatible(const struct device_node *device,const char *compat);
此函數(shù)用于判斷設(shè)備節(jié)點的 兼容屬性是否含有compat指定的字符串,能讓一個驅(qū)動至此兩個以上設(shè)備改淑。
設(shè)備樹中中斷的連接
要聲明controller屬性和cells大小