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

【Linux驱动开发】第10天:设备树零基础入门——DTS/DTB/DTC全解+编译流程

目录

  1. 为什么需要设备树?传统驱动的终极痛点
  2. DTS/DTB/DTC 大白话定义+核心区别
  3. 三者关系+完整编译流程图
  4. 最简单的DTS示例+语法解析
  5. 设备树编译与反编译实操命令
  6. 内核如何加载和使用设备树
  7. 核心总结+面试必背考点

1. 为什么需要设备树?传统驱动的终极痛点

在设备树出现之前,Linux内核采用硬编码的方式描述硬件信息:

  • 所有寄存器地址、中断号、GPIO号都直接写死在驱动代码里
  • 换一个开发板,就要修改驱动代码重新编译
  • 一个ARM内核要支持几十上百个开发板,就要在代码里写几百个硬件信息的分支
  • 内核变得无比臃肿,维护成本极高

设备树的诞生,就是为了彻底解决这个问题

硬件描述信息从内核代码中抽离出来,用一个独立的文件来描述硬件。内核只需要一份通用的代码,通过读取这个文件来识别不同的硬件。

大白话类比

  • 传统驱动:厨师把所有客人的口味都写在菜谱里,来了一个客人就要改一次菜谱
  • 设备树:厨师用通用菜谱,客人自己带一张写着自己口味的纸条,厨师照着纸条做菜

2. DTS/DTB/DTC 大白话定义+核心区别

设备树体系由三个核心部分组成:DTS、DTB、DTC,三者分工明确,缺一不可。

2.1 三者大白话定义

缩写全称中文名称大白话解释
DTSDevice Tree Source设备树源文件人类可读的文本文件,用C语言风格的语法描述硬件信息,相当于Word文档
DTCDevice Tree Compiler设备树编译器把人类可读的DTS文本文件,编译成内核能识别的二进制文件,相当于Word转PDF的转换器
DTBDevice Tree Blob设备树二进制文件DTC编译后的二进制文件,内核启动时加载并解析,相当于PDF文件

2.2 核心区别对比表

对比项DTSDTCDTB
文件类型纯文本文件可执行程序二进制文件
可读性人类可读不可读不可读
作用描述硬件信息编译DTS为DTB内核加载解析
编辑方式任何文本编辑器无需编辑不能直接编辑
后缀名.dts.dtsi无后缀.dtb

2.3 补充:什么是.dtsi文件?

.dtsi是设备树头文件,相当于C语言的.h头文件,用于存放多个DTS文件共享的公共硬件信息。

  • 比如同一个芯片的所有开发板,芯片内部的外设信息是相同的,可以放在.dtsi文件中
  • 每个开发板自己的.dts文件只需要包含这个.dtsi,然后添加自己独有的硬件信息即可
  • 大大提高了代码复用性,减少了重复代码

3. 三者关系+完整编译流程图

3.1 三者核心关系

DTS(源文件) --DTC编译--> DTB(二进制文件) --内核加载解析--> 识别硬件

3.2 完整编译与运行流程图

开发者编写DTS设备树源文件

包含公共的.dtsi头文件

DTC编译器编译DTS

生成DTB二进制设备树文件

将DTB烧录到开发板的指定分区

内核启动

bootloader将DTB地址传递给内核

内核解析DTB文件

根据DTB创建platform_device设备

platform总线匹配设备和驱动

调用驱动的probe函数初始化硬件

设备正常工作

3.3 关键流程说明

  1. bootloader的作用:bootloader(如U-Boot)负责在启动内核之前,将DTB文件加载到内存中,并将DTB的内存地址传递给内核
  2. 内核解析DTB:内核启动时,根据bootloader传递的地址,解析DTB文件,创建对应的platform_device设备
  3. 总线匹配:platform总线将创建的设备和已注册的驱动进行匹配,匹配成功后调用probe函数

4. 最简单的DTS示例+语法解析

下面是一个最小可运行的DTS文件,我会逐行解释每个部分的含义,让你快速掌握设备树的基本语法。

4.1 最简单的DTS示例

/dts-v1/; // 设备树版本号,必须是第一行 / { // 根节点,所有设备节点都在根节点下面 compatible = "myvendor,myboard"; // 板级兼容属性,内核用它来匹配板级支持包 model = "My Custom Development Board"; // 开发板名称 // 自定义LED设备节点 led@12340000 { compatible = "myvendor,my-led"; // 设备兼容属性,和驱动的of_device_id匹配 reg = <0x12340000 0x1000>; // 寄存器基地址和长度 status = "okay"; // 设备状态:okay表示启用,disabled表示禁用 }; // 自定义UART设备节点 uart@12341000 { compatible = "myvendor,my-uart"; reg = <0x12341000 0x1000>; interrupts = <5>; // 中断号 status = "okay"; }; };

4.2 核心语法解析

1. 节点(Node)
  • 设备树用树形结构描述硬件,每个硬件对应一个节点
  • 节点格式:节点名@地址 { ... };
  • 节点名:描述设备类型,如leduartgpio
  • @地址:设备的寄存器基地址,用于区分同类型的不同设备
2. 属性(Property)
  • 每个节点包含多个属性,用于描述设备的具体信息
  • 属性格式:属性名 = 属性值;
  • 常见属性:
    • compatible:最重要的属性,用于和驱动匹配,格式为"厂商,设备名"
    • reg:描述设备的寄存器地址范围,格式为<基地址 长度>
    • interrupts:描述设备使用的中断号
    • status:描述设备状态,okay表示启用,disabled表示禁用
    • model:设备的人类可读名称
3. 根节点
  • 所有节点的父节点,用/表示
  • 根节点的compatible属性用于匹配板级支持包
  • 根节点的model属性用于描述开发板名称

5. 设备树编译与反编译实操命令

5.1 安装DTC编译器

Ubuntu系统下直接安装:

sudoapt-getinstalldevice-tree-compiler

5.2 编译DTS为DTB

# 基本语法:dtc -I dts -O dtb -o 输出文件.dtb 输入文件.dtsdtc-Idts-Odtb-omyboard.dtb myboard.dts

5.3 反编译DTB为DTS

这是调试设备树最常用的命令,可以把内核正在使用的DTB文件反编译成可读的DTS文件:

# 基本语法:dtc -I dtb -O dts -o 输出文件.dts 输入文件.dtbdtc-Idtb-Odts-omyboard.dts myboard.dtb

5.4 查看开发板当前使用的设备树

在运行中的Linux系统中,可以通过/proc/device-tree目录查看内核解析后的设备树:

# 查看根节点的compatible属性cat/proc/device-tree/compatible# 查看所有设备节点ls/proc/device-tree/# 查看LED节点的reg属性cat/proc/device-tree/led@12340000/reg|hexdump-C

6. 内核如何加载和使用设备树

6.1 两种加载方式

方式1:DTB编译进内核
  • 将DTB文件和内核镜像编译在一起,生成一个单一的镜像文件
  • 优点:简单,不需要单独管理DTB文件
  • 缺点:修改设备树需要重新编译内核
方式2:DTB单独加载(推荐)
  • DTB文件和内核镜像分开存储
  • bootloader在启动内核时,将DTB加载到内存中,并将地址传递给内核
  • 优点:修改设备树只需要重新编译DTB,不需要重新编译内核
  • 现代Linux系统全部采用这种方式

6.2 U-Boot传递DTB地址的命令

# 加载内核镜像到内存0x80800000地址tftp 0x80800000 zImage# 加载DTB文件到内存0x83000000地址tftp 0x83000000 myboard.dtb# 启动内核,传递DTB地址bootz 0x80800000 - 0x83000000

6.3 内核解析DTB的过程

  1. 内核启动时,从bootloader获取DTB的内存地址
  2. 验证DTB的完整性和有效性
  3. 解析DTB的根节点和所有子节点
  4. 为每个设备节点创建对应的platform_device结构体
  5. platform_device注册到platform总线
  6. platform总线进行设备和驱动的匹配
  7. 匹配成功后调用驱动的probe函数

7. 核心总结+面试必背考点

核心总结

  1. 设备树的核心作用是将硬件描述信息从内核代码中抽离出来,解决传统驱动硬编码的问题
  2. DTS是人类可读的设备树源文件,DTB是内核能识别的二进制文件,DTC是编译两者的编译器
  3. 设备树采用树形结构描述硬件,每个硬件对应一个节点,每个节点包含多个属性
  4. compatible属性是设备和驱动匹配的唯一依据,格式为"厂商,设备名"
  5. 现代Linux系统采用bootloader单独加载DTB的方式,修改设备树不需要重新编译内核

面试必背考点

  1. 什么是设备树?它解决了什么问题?
  2. DTS、DTB、DTC分别是什么?三者的关系是什么?
  3. 什么是.dtsi文件?它的作用是什么?
  4. 设备树的基本语法结构是什么?
  5. compatible属性的作用是什么?格式是什么?
  6. 内核如何加载和解析设备树?
  7. bootloader在设备树启动过程中起到什么作用?
  8. 如何反编译DTB文件为DTS文件?
http://www.jsqmd.com/news/862075/

相关文章:

  • AI论文软件的实战手册:什么程度算学术不端?
  • Aeneas终极指南:3步搞定音频文本自动对齐,准确率超95%
  • 【Linux驱动开发】第11天:设备树(Device Tree)超详细全解:从诞生背景到工作原理
  • 如何构建更接近真实交通的自动驾驶仿真世界:数字孪生、风险重构与物理感知全栈实践
  • 编译和链接+预处理
  • 从塑料感→博物馆级质感,Midjourney材质进阶全路径:Chaos=0.3+Texture Boost+--style raw三重锁频技术,限时公开
  • ElevenLabs高棉文语音私有化部署终极方案(含Docker+Khmer IPA音素映射表),仅限前200位技术负责人获取
  • 为什么这款文档转换工具能同时实现高效与精准?揭秘Marker的核心优势
  • 2026.5.12【芯片设计面试经验分享】上海车载芯片设计公司
  • 079.自监督学习预训练:在无标签数据上预训练YOLO骨干网络
  • ElevenLabs挪威文语音API调用全链路拆解,从HTTP头配置到SSML韵律标记实战,零基础30分钟上线商用级语音
  • rk3588/rk3576使用rkllm推理大模型,提供OpenAI服务
  • VCG Mesh平滑整形
  • AI赋能光伏电站智能运维:边缘计算网关如何成为运维中枢?
  • AI 的持续学习:从会话中提取可复用知识
  • 一文搞懂 Linux 驱动并发与竞争(学习笔记)
  • 2026年工业胶粘材料国产化趋势白皮书:PI 金手指胶带的高温性能与应用突破
  • 深入拆解 MySQL InnoDB 隔离级别:从 MVCC 到临键锁
  • Go语言内存管理:从tcmalloc到GC优化
  • 2026年AI写作辅助网站实测排行,哪款真正适合写论文?
  • AI 术语通俗词典:LSTM
  • 注释与常用快捷键
  • Harness Engineering:智能体异常处理机制
  • 080.领域自适应:当你的YOLO在新车间“水土不服”时
  • 算法28,前缀和,寻找数组中的中心下标
  • C语言06(操作符)
  • VxWorks网络通信模块:网络协议栈解析(第五部分)
  • 鸿蒙备考题库页面构建:错题本、小组榜单与备考提示模块详解
  • QQ家园迷你屋单机版下载:复刻05年经典网页社区,像素风直接拉满
  • ComfyUI全面掌握-知识点详解——ComfyUI 开发与扩展基础(开发指南+环境搭建)