1. 设备树基础概念
各位同学好,我是老李。做车载Linux驱动开发这些年,我最大的感触就是——设备树这东西,你绕不开。今天咱们就来聊聊设备树的基础概念。
1.1 什么是设备树
设备树,英文叫Device Tree,简称DT。说白了,它就是一个描述硬件信息的数据结构。你想想看,以前Linux内核里塞满了各种板级文件,每个板子一个board-xxx.c,改个引脚都得重新编译内核,多麻烦。
设备树就是来解决这个问题的。它用树形结构来描述硬件:
- 根节点是
/,代表整个系统 - 子节点是各种设备,比如CPU、内存、I2C控制器、SPI控制器
- 每个节点里放的是设备的属性,比如寄存器地址、中断号、时钟频率
我习惯把设备树想象成一张硬件配置表。内核启动时读这张表,就知道该怎么跟硬件打交道了。
核心要点:设备树是硬件描述语言,不是驱动代码。它告诉内核「有什么硬件」,而不是「怎么驱动硬件」。
1.2 为什么需要设备树
这个问题我经常被问到。其实原因很简单——硬件太多了,内核管不过来。
在设备树出现之前,Linux用的是什么方式?
- 每个ARM平台都有自己的
arch/arm/mach-xxx目录 - 每个板子都要写一个
board-xxx.c文件 - 改一个GPIO引脚,就得重新编译整个内核
我在2012年刚入行时,就吃过这个亏。当时给一个车载信息娱乐系统换了个新屏幕,只是改了背光控制的GPIO号,结果编译内核花了快半小时。你说这效率能忍吗?
设备树带来的好处很明显:
- 硬件与驱动解耦:驱动代码不用改,改设备树就行
- 减少内核代码量:不再需要成百上千的板级文件
- 支持多平台:同一份内核镜像,换设备树就能跑不同硬件
- 启动参数灵活:内存大小、时钟频率等参数可以在设备树里配
我的经验:在车载项目中,设备树最大的价值就是「快速适配」。客户换了个传感器,或者改了引脚分配,我们只需要改dts文件,重新编译设备树,不用动内核。这在项目交付阶段特别重要。
1.3 设备树在车载Linux中的角色
车载系统和普通嵌入式系统不太一样。它有几个特点:
- 硬件复杂:一个域控制器可能有几十个外设
- 变种多:同一款车型,高配低配硬件不一样
- 安全要求高:不能随便改内核,但又要适配不同硬件
设备树在车载系统里扮演什么角色?我总结了三点:
| 角色 | 说明 | 实际案例 |
|---|---|---|
| 硬件抽象层 | 把硬件细节从内核代码中抽离出来 | 不同车型的摄像头接口,通过设备树配置 |
| 配置中心 | 统一管理所有外设的参数 | CAN总线波特率、I2C地址、GPIO复用 |
| 版本管理 | 不同硬件版本对应不同设备树 | 2023款和2024款车型,用不同dts文件 |
我记得有一次,客户要求在一周内适配三款不同配置的域控制器。要是没有设备树,我得改三份内核代码,测试三遍。有了设备树,我只需要写三个dts文件,内核镜像完全一样。嗯,这就是设备树的威力。
1.4 设备树文件格式
设备树源文件是.dts,编译后是.dtb。咱们先看看最基本的格式:
/dts-v1/;
/ {
model = "TI AM5728 EVM";
compatible = "ti,am5728-evm", "ti,am5728";
memory@0 {
device_type = "memory";
reg = <0x0 0x80000000>;
};
chosen {
stdout-path = &uart3;
};
&i2c1 {
status = "okay";
clock-frequency = <400000>;
eeprom@50 {
compatible = "atmel,24c02";
reg = <0x50>;
};
};
};
这里有几个关键点:
/dts-v1/:版本声明,必须写在第一行/:根节点,整个设备树的起点model和compatible:标识这个板子是谁家的memory节点:告诉内核内存布局chosen节点:启动参数,比如控制台用哪个串口&i2c1:引用外部定义的节点,添加或覆盖属性
注意:设备树里的reg属性,第一个值是地址,第二个值是长度。很多新手搞反了,导致内存映射出错。我曾经调试过一个CAN控制器不工作的问题,查了两天才发现是reg写反了。
1.5 设备树在启动流程中的位置
搞懂设备树,还得知道它在系统启动时是怎么被用的。我画个简单的流程:
- Bootloader(U-Boot):加载dtb文件到内存
- Bootloader:把dtb地址传给内核(通过r2寄存器)
- 内核启动早期:解析dtb,建立设备树结构
- 内核驱动初始化:遍历设备树,匹配驱动
- 驱动probe:从设备树读取资源,初始化硬件
说白了,设备树就是内核和硬件之间的「翻译官」。没有它,内核不知道内存多大、串口在哪、中断号是多少。
我在调试一个车载摄像头驱动时,发现设备树里配的中断号是32,但芯片手册上写的是33。内核启动时中断注册失败,摄像头死活不出图。后来查了三天才发现是设备树写错了。嗯,从那以后我养成了一个习惯——拿到新板子,先对照芯片手册核对设备树里的所有中断号和地址。
1.6 小结
今天咱们聊了设备树的基础概念。记住三点:
- 设备树是硬件描述,不是驱动代码
- 它让硬件和驱动解耦,适配更灵活
- 在车载系统里,它是硬件抽象和配置中心
下一章,我会带大家深入设备树的语法和常用属性。到时候咱们手把手写一个完整的设备树文件,把今天讲的东西用起来。
课后练习:找一块你手头的开发板,看看它的dts文件。找到memory节点、chosen节点、至少一个外设节点。试着理解每个属性的含义。下次课我会抽查哦。