首页主机资讯Linux驱动如何管理设备树

Linux驱动如何管理设备树

时间2025-12-16 15:15:04发布访客分类主机资讯浏览1271
导读:Linux 驱动与设备树的管理机制 一 核心流程总览 构建与传递:板级描述使用 .dts/.dtsi 编写,经 dtc 编译为 .dtb;Bootloader(如 U‑Boot)将 DTB 物理地址 传递给内核入口(ARM64 通过 x0...

Linux 驱动与设备树的管理机制

一 核心流程总览

  • 构建与传递:板级描述使用 .dts/.dtsi 编写,经 dtc 编译为 .dtb;Bootloader(如 U‑Boot)将 DTB 物理地址 传递给内核入口(ARM64 通过 x0,ARM32 传统用 r2,RISC‑V 常用 a1)。内核早期使用 libfdt 做最小解析(如 chosen/bootargs、memory、reserved-memory),随后调用 unflatten_device_tree() 将 FDT 展开为内核的 struct device_node 树,并扫描 /aliases 建立稳定别名映射。
  • 设备实例化:内核通过 of_platform_populate() 遍历带 compatible 的节点,在 /sys/devices/platform/ 下生成 platform_device;各总线桥接(如 I2C/SPI/MDIO/PCIe)在自身适配器就绪后,解析子节点生成对应的 i2c_client/spi_device 等设备对象。
  • 驱动匹配与绑定:驱动通过 of_match_table 声明支持的 compatible 列表,注册时由内核按“最具体 → 最通用”的规则匹配节点,匹配成功后执行驱动的 probe() 完成硬件初始化与 sysfs 属性创建。

二 驱动侧如何读取设备树信息

  • 匹配表与兼容性:在驱动中声明 of_device_id 表并使用 MODULE_DEVICE_TABLE(of, …),驱动注册时与设备节点的 compatible 进行匹配,命中后进入 probe
  • 资源获取:用 of_address_to_resource()/platform_get_resource() 解析 reg 得到 struct resource,再用 devm_ioremap_resource() 映射寄存器;多区域可用 reg-names 区分并通过索引访问。
  • 中断与时钟:用 of_irq_get()interrupts 映射为 Linux irq 号;用 of_clk_get_by_name()/devm_clk_get() 获取并启用时钟;GPIO/引脚复用通过 gpiospinctrl 子系统配合。
  • 属性读取:常用 of_property_read_u32/u64/string() 系列读取整型/字符串属性;枚举子节点可用 of_get_child_count()/of_for_each_child_of_node()

三 典型驱动绑定示例

  • 平台驱动骨架(精简版)
#include <
    linux/module.h>
    
#include <
    linux/platform_device.h>
    
#include <
    linux/of.h>
    
#include <
    linux/of_address.h>
    
#include <
    linux/of_irq.h>
    
#include <
    linux/clk.h>


static const struct of_device_id mydev_dt_ids[] = {

    {
 .compatible = "vendor,mydev" }
,
    {
 /* sentinel */ }

}
    ;
    
MODULE_DEVICE_TABLE(of, mydev_dt_ids);


static int mydev_probe(struct platform_device *pdev)
{
    
    struct device_node *np = pdev->
    dev.of_node;
    
    struct resource res;
    
    void __iomem *base;
    
    int irq, ret;
    
    struct clk *clk;
    

    /* 1) 地址映射 */
    ret = of_address_to_resource(np, 0, &
    res);
    
    if (ret) return ret;
    
    base = devm_ioremap_resource(&
    pdev->
    dev, &
    res);
    
    if (IS_ERR(base)) return PTR_ERR(base);
    

    /* 2) 中断 */
    irq = of_irq_get(np, 0);
    
    if (irq <
     0) return irq;
    

    /* 3) 时钟 */
    clk = devm_clk_get(&
    pdev->
    dev, NULL);
    
    if (IS_ERR(clk)) return PTR_ERR(clk);
    
    ret = clk_prepare_enable(clk);
    
    if (ret) return ret;
    

    /* TODO: 硬件初始化,注册字符/网络/其他接口 */

    dev_info(&
    pdev->
    dev, "mydev probed @ %pa, irq %d\n", &
    res.start, irq);
    
    return 0;

}


static int mydev_remove(struct platform_device *pdev)
{
    
    /* TODO: 关闭时钟、资源释放 */
    return 0;

}


static struct platform_driver mydev_driver = {

    .driver = {

        .name = "mydev",
        .of_match_table = mydev_dt_ids,
    }
,
    .probe = mydev_probe,
    .remove = mydev_remove,
}
    ;
    
module_platform_driver(mydev_driver);
    
MODULE_LICENSE("GPL");
    
  • 总线设备举例
    • I2C 设备:控制器驱动注册 i2c_adapter 后,调用 of_i2c_register_devices() 解析总线子节点生成 i2c_client,按 compatible 触发对应 I2C 驱动 probe
    • SPI 设备:控制器就绪后,调用 spi_of_register_spi_devices() 生成 spi_device 并绑定 SPI 驱动。

四 构建 传递 与 动态管理

  • 构建与部署:在内核树中编写 .dts/.dtsi,使用 make dtbs 生成 .dtb;将 Image + DTB [+ initramfs] 放入存储并在 Bootloader 中加载与传递。
  • 启动期修补:Bootloader 可更新 /chosen/bootargs、/chosen/stdout-path、内存/保留区、MAC/SN 等,必要时叠加 Overlay(.dtbo) 实现增量配置。
  • 动态覆盖:系统运行时可通过 configfs/sysfs 接口加载 .dtbo,调用 of_overlay_apply() 合并到主设备树并触发受影响设备重新枚举,常用于扩展板、插件化外设场景。

五 调试与最佳实践

  • 查看与核对:用 /proc/device-tree/ 浏览展开后的节点与属性;用 of_node_full_name()/of_find_node_by_path() 在代码中定位节点;确认 status = “okay” 才会被枚举。
  • 资源与时钟:优先使用 devm_* 系列资源管理;对 reg/interrupts/clocks/reg-names 做完备性与边界检查;必要时在 probe 中验证关键资源可用性。
  • 绑定策略:在 of_match_table 中按“最具体 → 最通用”排序;为可复用外设提供通用兼容字符串,便于多平台共享驱动。
  • 可维护性:公共片段放入 .dtsi,通过 #include 复用;板级差异集中在 .dts;使用 aliases 提供稳定设备名;对可选节点使用 status 控制启用状态。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: Linux驱动如何管理设备树
本文地址: https://pptw.com/jishu/772860.html
怎样启用Debian SFTP日志记录 如何在Linux上使用GIMP进行图像旋转

游客 回复需填写必要信息