linux 设备树相关的数据结构

Linux设备树(Device Tree)是一种描述硬件配置的树形数据结构,通过节点(Node)和属性(Property)的层级关系,抽象化表示CPU、内存、总线、外设等硬件信息。其核心数据结构及实现逻辑如下:

一、设备树节点(Device Tree Node)

设备树由节点构成,每个节点表示一个硬件设备或逻辑组件。节点可嵌套子节点,形成树状结构。

1. 节点结构
  • 节点命名:格式为node-name@unit-address,其中node-name为设备类型(如cpui2c),unit-address为设备地址(可选)。
  • 根节点:唯一根节点/,描述整个系统信息(如compatible属性定义硬件平台)。
  • 子节点:例如CPU节点、内存节点、外设节点等。
2. 内核表示

在Linux内核中,节点通过struct device_node表示,关键字段包括:

  • name: 节点名称。
  • parent: 父节点指针。
  • child: 子节点链表。
  • properties: 属性链表(struct property)。
  • full_name: 节点完整路径(如/soc/i2c@021a0000)。

二、属性(Property)

属性是键值对,描述节点配置信息。属性值可以是字符串、整数、字节数组等。

1. 标准属性示例
  • compatible:驱动匹配关键属性,格式为"厂商,型号"(如compatible = "fsl,imx6ull-gpmi-nand")。
  • reg:设备地址及长度,格式为<address length>,受父节点#address-cells#size-cells影响。
  • interrupts:中断号及触发方式(如interrupts = <0 2 4>表示IRQ 0,边沿触发)。
  • status:设备状态("okay"启用,"disabled"禁用)。
2. 自定义属性

用户可定义任意属性(如custom-data = <0x12 0x34>),驱动通过of_property_read_u32_array等API读取。

3. 内核表示

属性通过struct property表示,关键字段包括:

  • name: 属性名。
  • length: 属性值长度。
  • value: 属性值指针(字节数组)。

三、设备树二进制格式(DTB)

设备树源文件(.dts)编译为二进制文件(.dtb),内核启动时解析。DTB结构包括:

  1. Header:魔数(0xd00dfeed)、总大小、结构块偏移等。
  2. Structure Block:线性化节点数据,包含节点开始/结束标记、属性数据。
  3. Strings Block:所有属性名的字符串表,通过偏移量引用。

四、内核解析流程

  1. Bootloader传递:U-Boot将DTB加载到内存,通过寄存器(如ARM的r2)传递地址给内核。
  2. 解压与校验:内核验证DTB完整性,解压为内存中的设备树结构。
  3. 遍历与初始化
    • 使用of_find_node_by_pathof_get_property等API遍历节点和属性。
    • 根据compatible属性匹配驱动,调用probe函数初始化设备。

五、关键数据结构关系图

设备树结构
├─ / (根节点)
│  ├─ compatible = "vendor,platform"
│  └─ memory@80000000
│     ├─ device_type = "memory"
│     └─ reg = <0x80000000 0x40000000>
├─ soc (SoC节点)
│  ├─ #address-cells = <1>
│  ├─ #size-cells = <1>
│  └─ i2c@021a0000
│     ├─ compatible = "fsl,imx6q-i2c"
│     └─ reg = <0x021a0000 0x4000>
└─ chosen (启动参数节点)
   └─ bootargs = "console=ttyS0,115200"

六、操作API示例

#include <linux/of.h>

// 查找节点
struct device_node *np = of_find_node_by_path("/soc/i2c@021a0000");

// 读取属性
const u32 *reg;
u32 reg_len;
of_property_read_u32_array(np, "reg", reg, &reg_len);

// 遍历子节点
for_each_child_of_node(np, child) {
    // 处理子节点
}

总结

设备树通过节点和属性抽象硬件,内核通过struct device_nodestruct property解析配置,实现驱动与硬件解耦。这种设计使得同一内核支持多硬件平台,无需修改内核代码,仅需更换设备树文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值