)
什么是設備樹三種文件格式設備樹工作原理與核心機制設備樹數據流架構設備樹核心數據結構設備樹與驅動匹配機制DTS 語法基礎節點定義關鍵屬性詳解數據類型引用其他節點Phandle編寫一個簡單的 LED 驅動設備樹編譯設備樹調試技巧如何查看運行時設備樹常用命令查看完整設備樹結構?查看某個屬性的值?查看特定設備節點?使用 dtc 工具反編譯 DTB?什么是設備樹設備樹Device Tree是一種描述硬件配置的數據結構它采用樹狀結構以文本形式描述系統硬件資源包括CPU、內存、總線、外設等。設備樹的核心思想是將硬件描述與操作系統內核分離使得同一內核 鏡像 能夠支持不同的硬件平臺。三種文件格式設備樹Device Tree主要包含三種文件格式每種格式在開發流程中扮演不同的角色后綴名稱說明.dtsDevice Tree Source人類可讀的文本源文件采用類似 C 語言的語法結構。每個開發板通常對應一個獨立的 .dts 文件用于描述該板卡的硬件配置。.dtsiDevice Tree Source Include設備樹頭文件用于定義 SoC系統級芯片的通用配置或公共模塊。多個 .dts 文件可以引用同一個 .dtsi 文件實現代碼復用。.dtbDevice Tree Blob編譯后的二進制文件由 .dts 文件通過設備樹編譯器DTC生成。Bootloader 將其加載到內存中并傳遞給 Linux 內核使用。這三種文件構成了設備樹從源碼編寫到最終使用的完整流程。設備樹工作原理與核心機制設備樹數據流架構設備樹核心數據結構// 內核中設備樹核心數據結構structdevice_node{constchar*name;// 節點名稱constchar*type;// 設備類型phandle phandle;// 節點句柄constchar*full_name;// 節點全路徑名structproperty*properties;// 屬性鏈表structdevice_node*parent;// 父節點structdevice_node*child;// 子節點structdevice_node*sibling;// 兄弟節點structkobjectkobj;// kobject用于sysfsunsignedlong_flags;// 內部標志位void*data;// 設備私有數據};structproperty{char*name;// 屬性名稱intlength;// 屬性值長度void*value;// 屬性值指針structproperty*next;// 下一個屬性unsignedlong_flags;// 內部標志位unsignedintunique_id;// 唯一ID};設備樹與驅動匹配機制設備樹通過compatible屬性實現與驅動的匹配// 設備樹中的定義mydevice0x10000000{compatiblevendor,device-model,generic-driver;reg0x100000000x1000;interrupts0254;};// 驅動中的匹配表staticconststructof_device_idmy_driver_match[]{{.compatiblevendor,device-model},{.compatiblegeneric-driver},{}};MODULE_DEVICE_TABLE(of,my_driver_match);// 平臺驅動結構staticstructplatform_drivermy_driver{.probemy_probe,.removemy_remove,.driver{.namemy-device,.of_match_tablemy_driver_match,},};DTS 語法基礎節點定義dts /node-nameaddress{propertyvalue;};node-name節點名稱通常反映設備功能如 serial, i2c。address可選表示該設備在父總線上的基地址。{ … }花括號內包含屬性和子節點。關鍵屬性詳解屬性說明示例?compatible?驅動匹配標識“rockchip,rk3568-pcie”, “snps,dw-pcie”?reg?寄存器地址/大小0x40000000 0x1000 (地址, 長度)?interrupts?中斷描述GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH?clocks?時鐘引用clk_core, clk_bus?gpios?GPIO 引用gpio1 5 GPIO_ACTIVE_HIGH?status?啟用狀態“okay” (啟用), “disabled” (禁用)?pinctrl-0?引腳復用配置uart0_pins數據類型單元格Cells?用 包裹的 32 位整數。reg 0x1000 0x100;字符串?用 包裹。compatible “my-device”;字節數組?用 [ ] 包裹十六進制。local-mac-address [00 11 22 33 44 55];字符串列表?compatible “a,b”, “c,d”;引用其他節點Phandle使用 label 引用其他節點常用于引腳配置pinctrl、時鐘、GPIO。pinctrl-0uart0_pins;// 引用名為 uart0_pins 的節點 clocksclk_uart0;// 引用時鐘節點編寫一個簡單的 LED 驅動設備樹通常在 arch/arm64/boot/dts/rockchip/rk3568-your-board.dts 中添加/dts-v1/;#include rk3568.dtsi // 包含 SoC 基礎定義/{modelMy RK3568 Board;compatiblemyvendor,rk3568-board,rockchip,rk3568;/*1. 定義 GPIO LED 節點 */ gpio-leds{compatiblegpio-leds;// 使用內核自帶的 gpio-leds 驅動 led-user{labeluser-led;gpiosgpio3 RK_PD2 GPIO_ACTIVE_HIGH;// 引用 GPIO3 控制器 linux,default-triggerheartbeat;// 默認心跳閃爍};};};/*2. 如果需要自定義引腳復用Pinctrl通常在pinctrl 節點下添加 */pinctrl{vcc3v3_pcie3: vcc3v3-pcie3-regulator{rockchip,pins3RK_PD2 RK_FUNC_GPIOpcfg_pull_none;};};編譯設備樹在內核源碼根目錄執行makeARCHarm64CROSS_COMPILEaarch64-linux-gnu- rk3568-your-board.dtb生成的 rk3568-your-board.dtb 即為最終文件。調試技巧如何查看運行時設備樹Linux 啟動后會將解析后的設備樹暴露在 ?/proc/device-tree/? 目錄下。這是調試的神器。常用命令查看完整設備樹結構?ls/proc/device-tree/# 你會看到 chosen,memory,soc,aliases 等目錄查看某個屬性的值?# 查看內核命令行參數 cat/proc/device-tree/chosen/bootargs # 查看根節點的 compatible cat/proc/device-tree/compatible查看特定設備節點?# 假設你的 LED 節點路徑是/gpio-leds/led-user cat/proc/device-tree/gpio-leds/led-user/gpios # 注意二進制數據直接 cat 可能亂碼可用 hexdump hexdump-C/proc/device-tree/gpio-leds/led-user/gpios使用 dtc 工具反編譯 DTB?如果你只有 .dtb 文件想看看里面寫了什么dtc-I dtb-O dts-o output.dts input.dtb