Linux系统-设备树介绍(四)

Linux系统-设备树介绍(四)
什么是设备树三种文件格式设备树工作原理与核心机制设备树数据流架构设备树核心数据结构设备树与驱动匹配机制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

最新新闻

日新闻

周新闻

月新闻