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

深度解析Linux设备树(DTS):设计原理、实现框架与实例分析

文章目录

    • 深度解析Linux设备树(DTS):设计原理、实现框架与实例分析
      • 一、设备树诞生的根本原因:ARM生态的"碎片化困境"
        • 传统BSP开发模式的问题:
      • 二、设备树设计框架:分层硬件描述模型
        • 设备树框架架构图:
        • 典型设备树结构示例:
      • 三、设备树核心机制深度解析
        • 1. 地址映射机制
        • 2. 中断映射机制
      • 四、设备树编译与运行时流程
        • 完整生命周期:
      • 五、高级应用:设备树覆盖(Overlay)实战
        • Overlay框架图:
      • 六、设备树与传统开发模式对比
        • 架构差异图:
        • 开发流程对比表:
      • 七、设备树设计最佳实践
      • 总结:设备树的技术本质与价值

深度解析Linux设备树(DTS):设计原理、实现框架与实例分析

一、设备树诞生的根本原因:ARM生态的"碎片化困境"

传统BSP开发模式的问题:
内核源码
mach-boardA.c
开发板A
board-specifc.h
mach-boardB.c
开发板B
board-specifc.h
mach-boardC.c
开发板C
board-specifc.h
ARM SoC

典型问题案例
三星S3C2410 ARM9处理器在内核中的实现:

  • arch/arm/mach-s3c2410/mach-smdk2410.c (1500+行代码)
  • 硬编码资源定义:
static struct resource smdk2410_uart0_resources[] = {[0] = {.start = S3C2410_PA_UART0,.end   = S3C2410_PA_UART0 + 0x3fff,.flags = IORESOURCE_MEM,},[1] = {.start = IRQ_S3CUART_RX0,.end   = IRQ_S3CUART_ERR0,.flags = IORESOURCE_IRQ,}
};

后果:内核中仅ARM架构就有200+个mach-目录,每次硬件变更都需要重新编译内核。


二、设备树设计框架:分层硬件描述模型

设备树框架架构图:
内核解析层
编译/运行层
DTS设计层
物理连接
dts -> dtb
传递DTB
OF Core
device_node树
platform_device
驱动匹配
DTB二进制
DTC编译器
Linux内核
Bootloader
dtsi - SoC级定义
设备树源文件
dts - 板级定义
CPU核心
内存映射
时钟体系
外设配置
扩展接口
硬件层
典型设备树结构示例:
// ----- SoC级定义 (sun20i-d1.dtsi) -----
/ {#address-cells = <2>;#size-cells = <2>;cpus {cpu0: cpu@0 {compatible = "riscv";reg = <0>;};};soc {ranges;serial0: serial@2500000 {compatible = "snps,dw-apb-uart";reg = <0x0 0x02500000 0x0 0x400>;interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;clocks = <&ccu CLK_BUS_UART0>;};};
};// ----- 板级定义 (board.dts) -----
#include "sun20i-d1.dtsi"/ {memory@40000000 {device_type = "memory";reg = <0x0 0x40000000 0x0 0x20000000>; // 512MB RAM};leds {compatible = "gpio-leds";led0 {label = "board:red:status";gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; // PC3};};
};

三、设备树核心机制深度解析

1. 地址映射机制
#address-cells=2
#size-cells=1
父节点
子节点
reg属性
cell0: 片选0
cell1: 偏移0x30000000
cell2: 长度0x1000000

实际案例

soc {#address-cells = <2>;  // 地址用2个32位数表示#size-cells = <1>;     // 大小用1个32位数表示ethernet@10000000 {compatible = "davicom,dm9000";reg = <00x10000000   // 高32位地址0x10000000   // 低32位地址0x1000>;     // 寄存器区大小4KB};
};
2. 中断映射机制
设备节点中断控制器内核驱动interrupts = <0 23 1>0:中断类型23:中断号1:触发方式转换为全局中断号request_irq(global_irq)设备节点中断控制器内核驱动

代码实现

// 驱动获取中断号
int irq = platform_get_irq(pdev, 0);// 内核内部转换
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
{struct of_phandle_args oirq;if (of_irq_parse_one(dev, index, &oirq))return 0;return irq_create_of_mapping(&oirq);
}

四、设备树编译与运行时流程

完整生命周期:
DTB地址
dts/dtsi源码
DTC编译器
DTB二进制
Bootloader
Linux内核
unflatten_device_tree
device_node树
of_platform_populate
platform_device
驱动匹配
probe函数

关键步骤详解

  1. 编译阶段

    # 编译命令
    dtc -I dts -O dtb -o board.dtb board.dts# 反编译查看
    fdtdump board.dtb
    
  2. 启动阶段

    // ARM启动协议
    r0 = 0, r1 = 机器ID, r2 = DTB物理地址
    
  3. 内核解析

    // 初始化流程
    start_kernel()-> setup_arch()-> unflatten_device_tree()  // 构建device_node树-> of_platform_default_populate() // 创建平台设备
    
  4. 驱动匹配

    // 驱动声明匹配表
    static const struct of_device_id my_drv_ids[] = {{ .compatible = "vendor,my-device" },{}
    };// 平台驱动注册
    platform_driver_register(&my_driver);
    

五、高级应用:设备树覆盖(Overlay)实战

Overlay框架图:
写入路径
基础DTB
运行时内存
Overlay DTBO
用户空间
sys/kernel/config/device-tree/overlays
合并设备树
内核生效

全志D1开发板添加PWM设备

// pwm-overlay.dts
/dts-v1/;
/plugin/;&pio {pwm7_pin: pwm7 {pins = "PD22";function = "pwm7";};
};&pwm {pinctrl-names = "default";pinctrl-0 = <&pwm7_pin>;status = "okay";
};

加载流程

# 编译overlay
dtc -@ -I dts -O dtb -o pwm7.dtbo pwm-overlay.dts# 加载overlay
mkdir /config/device-tree/overlays/pwm7
cat pwm7.dtbo > /config/device-tree/overlays/pwm7/dtbo

六、设备树与传统开发模式对比

架构差异图:
设备树架构
通用内核
硬件H1
硬件H2
DTB1
DTB2
传统架构
内核镜像K1
硬件H1
硬件H2
内核镜像K2
包含板级代码
包含板级代码
开发流程对比表:
阶段传统模式设备树模式
硬件变更修改内核源码,重新编译修改.dts,单独编译DTB
驱动获取参数从platform_data结构体读取通过OF API解析设备树节点属性
多板卡支持每个板卡需独立内核镜像单一内核+不同DTB文件
外设扩展修改内核并重新编译动态加载DT Overlay

驱动代码对比

// 传统模式(硬编码)
struct mydev_platform_data {u32 clock_rate;u8 mode;
};static struct mydev_platform_data board_data = {.clock_rate = 50000000,.mode = 0x2,
};// 设备树模式
const struct of_device_id mydev_ids[] = {{ .compatible = "vendor,mydev" },{}
};static int mydev_probe(struct platform_device *pdev)
{struct device_node *np = pdev->dev.of_node;u32 clock_rate;u8 mode;of_property_read_u32(np, "clock-frequency", &clock_rate);of_property_read_u8(np, "operating-mode", &mode);
}

七、设备树设计最佳实践

  1. 分层设计原则

    ├── arch/
    │   └── arm/
    │       └── boot/
    │           └── dts/
    │               ├── vendor-soc.dtsi  // SoC通用定义
    │               ├── vendor-board.dts // 基础板级
    │               └── variants/
    │                   ├── board-1.dts  // 派生版本1
    │                   └── board-2.dts  // 派生版本2
    
  2. 兼容性声明规范

    // 精确到具体型号
    compatible = "ti,bq25601", "ti,bq25600";// 芯片系列通用
    compatible = "nvidia,tegra210-i2c";
    
  3. 引脚控制设计

    &i2c1 {pinctrl-names = "default", "sleep";pinctrl-0 = <&i2c1_pins_a>;pinctrl-1 = <&i2c1_pins_b>;status = "okay";
    };
    

总结:设备树的技术本质与价值

设备树通过结构化数据描述(DTS)、标准化编译链(DTC)、运行时解析框架(OF API)三位一体的设计,实现了:

  1. 硬件抽象层

    物理硬件
    设备树描述
    内核通用驱动
    用户空间
  2. 核心价值点

    • 解耦性:硬件描述与内核代码分离
    • 可扩展性:Overlay支持动态配置
    • 可维护性:减少80%板级特定代码
    • 标准化:跨ARM架构统一硬件接口
  3. 性能数据

    • 内核镜像大小减少:35-60%
    • 启动时间减少:15-30% (省去硬编码初始化)
    • 支持硬件变体数量:无限扩展
http://www.dtcms.com/a/324650.html

相关文章:

  • 阿里云ECS云服务器临时升级带宽方法
  • JP3-4-MyClub后台前端(三)
  • 胖虎的菜品
  • 一劳永逸解决Mayplotlib绘图中中文字体显示乱码的问题
  • 嵌入式软件分层架构的设计原理与实践验证(有限状态机理解及结构体封装理解)
  • 进度、质量、安全的关系随笔
  • 力扣面试150(52/150)
  • NY155NY170美光固态闪存NY175NY184
  • Zabbix优化指南:提升监控效率与性能
  • Pytorch深度学习框架实战教程-番外篇07-Pytorch优化器详解和实战指南
  • 机器学习——DBSCAN
  • 【人工智能99问】LLaMA的训练过程和推理过程是怎么样的?(22/99)
  • 【GPT入门】第43课 使用LlamaFactory微调Llama3
  • AI大模型提示词工程完全指南:从入门到精通
  • 【自用】JavaSE--IO流(二)--缓冲流、转换流、打印流、数据流、序列化流、IO框架
  • 硬件开发_基于STM32单片机的智能电梯系统
  • 【RocketMQ 生产者和消费者】- ConsumeMessageConcurrentlyService 并发消费消息
  • 自然语言处理入门路线-实践篇
  • AutoCAD 2026 的主要功能
  • 如何选择适合自己电商业务的 API?​
  • 解决RuoYi-Cloud项目ruoyi-system模块启动失败问题以及Naco容器部署问题
  • 【21】OpenCV C++实战篇——OpenCV C++案例实战二十七《角度测量》
  • SpringAI智能航空助手实战<Demo>
  • 《算法导论》第 17 章 - 摊还分析
  • XGBoost 与 GBDT 的比较:改进与性能提升
  • MATLAB绘制水的蒸汽压曲线(Antoine方程)
  • GitHub上为什么采用Gradle编译要多于Maven
  • DBSACN算法的一些应用
  • 【算法】图的 深度优先搜索(DFS)与 广度优先搜索(BFS)
  • Stream流应用