当前位置: 首页 > article >正文

深入解析 Linux 内核如何解析和获取设备树属性

1. 引言

设备树(Device Tree, DT)是 Linux 内核用于描述硬件的平台抽象方式。设备树中的 属性(Properties) 存储了设备的配置信息,Linux 内核通过特定的 API 解析和读取这些属性,以正确初始化设备驱动。

本篇文章将详细讲解 Linux 内核如何解析设备树属性,并提供一个 标准内核模块代码 以及 对应的设备树配置,帮助你理解关键技术点。


在这里插入图片描述

2. 内核解析设备树的基本机制

Linux 内核解析设备树时,主要依赖 Flattened Device Tree (FDT) 解析框架,其核心组件包括:

  • drivers/of/ 文件夹:存放设备树解析代码。
  • of.h 头文件:定义了设备树 API。
  • of_device.h 头文件:定义了 struct device_node 结构体。

2.1 设备树解析核心数据结构

(1)设备节点 struct device_node
struct device_node {
    const char *name;                // 设备节点名称
    struct property *properties;     // 指向该节点的属性列表
    struct device_node *parent;      // 父节点
    struct device_node *child;       // 子节点
    struct device_node *sibling;     // 兄弟节点
};
(2)设备树属性 struct property
struct property {
    char *name;      // 属性名
    int length;      // 属性值长度
    void *value;     // 指向属性值的指针
};

3. 如何在 Linux 设备驱动中解析设备树属性

Linux 提供了一系列 API 来解析设备树中的属性信息。常用 API 如下:

API 函数作用
of_find_node_by_path()通过路径查找设备树节点
of_find_node_by_name()通过名称查找设备树节点
of_property_read_u32()读取 32-bit 数值类型属性
of_property_read_string()读取字符串属性
of_property_read_bool()读取布尔值属性(存在即为 true)

示例 1:解析 compatible 属性

struct device_node *np;
const char *compat;
np = of_find_node_by_path("/soc/i2c@40066000");
if (np) {
    if (of_property_read_string(np, "compatible", &compat) == 0) {
        pr_info("Compatible: %s\n", compat);
    }
}

说明

  • 通过路径 /soc/i2c@40066000 查找 I2C 设备节点。
  • 读取 compatible 属性并打印。

4. 完整示例:解析设备树信息并注册字符设备驱动

4.1 设备树节点 (example.dts)

/example {
    compatible = "mydevice,example";
    example_device: example@0 {
        compatible = "myvendor,mydevice";
        reg = <0x1000 0x100>;
        example-property = <42>;
        example-string = "Hello, Device Tree";
    };
};

解析:

  • compatible = "myvendor,mydevice";:用于驱动匹配。
  • reg = <0x1000 0x100>;:设备寄存器信息。
  • example-property = <42>;:自定义数值属性。
  • example-string = "Hello, Device Tree";:自定义字符串属性。

4.2 内核驱动 (example_driver.c)

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>

static int example_probe(struct platform_device *pdev) {
    struct device_node *np = pdev->dev.of_node;
    u32 example_value;
    const char *example_str;
    
    if (!np)
        return -EINVAL;
    
    if (of_property_read_u32(np, "example-property", &example_value) == 0)
        pr_info("example-property: %d\n", example_value);
    
    if (of_property_read_string(np, "example-string", &example_str) == 0)
        pr_info("example-string: %s\n", example_str);
    
    return 0;
}

static const struct of_device_id example_of_match[] = {
    { .compatible = "myvendor,mydevice" },
    {},
};
MODULE_DEVICE_TABLE(of, example_of_match);

static struct platform_driver example_driver = {
    .probe = example_probe,
    .driver = {
        .name = "example_driver",
        .of_match_table = example_of_match,
    },
};
module_platform_driver(example_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Embedded Dev");
MODULE_DESCRIPTION("Example Device Tree Driver");

解析:

  • example_probe():驱动探测函数,解析设备树属性。
  • of_property_read_u32()of_property_read_string():分别解析 example-propertyexample-string
  • example_of_match:设备树 compatible 匹配表。

4.3 设备树加载与测试

  1. 编译设备树
    dtc -I dts -O dtb -o example.dtb example.dts
    
  2. 加载设备树
    sudo cp example.dtb /boot/
    
  3. 编译并加载驱动
    make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
    sudo insmod example_driver.ko
    dmesg | grep example
    

5. 总结

  • Linux 通过 struct device_node 解析设备树结构。
  • 常用 API 如 of_property_read_u32() 读取设备树属性。
  • 设备树 compatible 用于匹配驱动,驱动必须注册 of_match_table
  • 完整示例展示了如何编写标准内核模块并解析设备树信息。

这篇文章提供了一套完整、准确的 Linux 设备树解析方案,希望能帮助你深入理解 Linux 内核如何解析设备树属性!


http://www.kler.cn/a/565998.html

相关文章:

  • 【汽车ECU电控数据管理篇】HEX文件格式解析篇章
  • iphone上ios设备开启safari开发者debug模式,配合mac电脑使用
  • 华为云设备接入
  • 本地部署阿里万象2.1文生视频模型(Wan2.1-T2V)完全指南
  • OOM故障排查指南:生成 JVM 内存快照并使用快照分析工具定位问题
  • vscode 版本
  • 2025年2月21日优雅草内测分发站全新升级-测试运营-优雅草内测分发站新用户提供免费100下载点-2月28日正式运营并且提供私有化部署版本
  • Centos7源码编译安装Sqlite最新版本
  • deepseek使用记录12
  • 监控 docker 的容器对资源的占用情况
  • MR30系列分布式I/O:高稳定与高精准赋能锂电池覆膜工艺革新
  • 七星棋牌 6 端 200 子游戏全开源修复版源码(乐豆 + 防沉迷 + 比赛场 + 控制)
  • Stable Diffusion(SD)系列模型及关联算法深度解析
  • 服务端驱动UI架构解析:React Server Components与流式渲染的革命
  • 16.1 LangChain 表达式语言(LCEL)深度解析:构建灵活高效的大模型应用流水线
  • SOME/IP 教程知识点总结
  • 网络安全大赛模拟
  • 深度学习基础--ResNet50V2网络的讲解,ResNet50V2的复现(pytorch)以及用复现的ResNet50做鸟类图像分类
  • ERP系统的库存模块业务逻辑及设计
  • 51c大模型~合集48