
本文概述
Linux设备树是嵌入式Linux面试的高频考点。设备树用树形结构描述硬件信息,替代传统的板级硬编码,实现内核与硬件配置分离。设备树源文件DTS编译为DTB后由bootloader传递给内核。驱动通过of_系列函数解析节点属性,platform_driver通过compatible属性与设备匹配。常用节点类型有memory、cpus、chosen、aliases,驱动中常用of_property_read_系列函数读取属性值。
核心要点速览
设备树是描述硬件信息的数据结构,替代传统板级文件中的硬编码,实现内核与硬件分离
设备树结构:根节点、子节点、属性,属性有字符串、32位整数、二进制数据、字符串列表等类型
常用特殊节点:aliases(别名)、chosen(启动参数)、memory(内存配置)、cpus(CPU配置)
驱动中通过of_系列函数解析设备树节点,获取资源后注册platform_device
compatible属性是设备与驱动匹配的关键字,采用"厂商,设备名"的命名规范
一、面试题
请说明Linux设备树的作用和基本语法,以及驱动中怎么解析设备树节点。
二、面试官考察点
1. 设备树理念理解:为什么要有设备树?设备树解决了什么问题?反映候选人对Linux内核架构的认识深度。
2. DTS语法掌握:节点怎么写、属性有哪些类型、常用的特殊节点有哪些,反映是否实际写过设备树。
3. 驱动解析能力:驱动代码中怎么获取设备树信息,用哪些函数,反映实际驱动开发经验。
4. 匹配机制理解:platform_driver和设备树节点怎么匹配上的,compatible属性的作用和优先级。
三、回答思路
1. 设备树的作用和来源
设备树是一种描述硬件资源的数据结构,来源于Open Firmware。在ARM Linux中引入设备树之前,内核里有大量板级描述文件,每个开发板都对应一份C代码,代码冗余且维护困难。引入设备树后,硬件描述从内核代码中分离出来,放在独立的设备树源文件中,同一份内核镜像可以通过不同的DTB文件适配不同的板子,驱动也可以更通用。
工作流程:DTS(设备树源文件)通过DTC工具编译成DTB(二进制设备树blob),bootloader启动时将DTB地址传给内核,内核启动时解析DTB并创建相应的设备节点。
2. 设备树基本语法
一个简单的设备树节点示例:
常见属性类型:
| 类型 | 示例 | 说明 |
|---|---|---|
| 字符串 | compatible = "vendor,device" | 用双引号包裹 |
| 32位整数 | reg = <0x1000 0x100> | 用尖括号,多个用空格分隔 |
| 字符串列表 | compatible = "a","b","c" | 多个字符串用逗号分隔 |
| 二进制数据 | mac-address = [00 11 22 33 44 55] | 用方括号 |
| 混合 | property = "string", <0x1234>, [ab cd] | 逗号连接不同类型 |
3. 常用特殊节点
/aliases:定义节点别名,方便通过别名引用节点,如serial0 = &uart0
/chosen:传递启动参数,如bootargs(内核命令行参数)
/memory:描述物理内存的起始地址和大小
/cpus:描述CPU核的信息,包括每个CPU的频率、兼容属性等
/soc下的各外设节点:描述寄存器基地址、中断、时钟、DMA等硬件资源
4. 驱动中解析设备树的方法
Linux内核提供了of_开头的函数族来访问设备树,常用的有:
| 函数 | 功能 |
|---|---|
| of_find_node_by_path | 按路径查找节点 |
| of_find_compatible_node | 按compatible属性查找节点 |
| of_property_read_u32 | 读取32位整数属性 |
| of_property_read_string | 读取字符串属性 |
| of_property_read_u32_array | 读取整数数组 |
| of_address_to_resource | 将reg属性转换为resource结构 |
| of_irq_get | 获取中断号 |
| devm_of_iomap | 映射寄存器地址空间(带devm自动释放) |
四、追问(4个)
追问1:status属性有哪些取值?各是什么含义?
status属性表示设备的状态,常用值有四个:okay表示设备正常可用;disabled表示设备被禁用(一般是引脚被其他功能复用了);fail表示设备不可用(硬件故障);fail-sss表示不可用且附带错误原因。驱动开发中常用of_device_is_available函数判断设备是否可用,状态为okay或为空(默认可用)时才进行初始化。
追问2:设备树中的reg属性怎么理解?和#address-cells的关系?
reg属性描述设备的地址空间,格式是(起始地址,长度)对。#address-cells决定地址用几个32位整数表示,#size-cells决定长度用几个32位整数表示。比如#address-cells = <1>,#size-cells = <1>时,reg = <0x40010000 0x1000>表示从地址0x40010000开始、长度为4KB的空间。64位地址系统中#address-cells会设为2,用两个32位数表示一个64位地址。
追问3:什么是设备树插件(Overlay)?有什么用?
设备树插件是一种运行时动态加载设备树片段的机制,可以在系统运行后动态添加或修改设备树节点,而不需要重新编译和烧写整个DTB。典型应用场景:支持可插拔的扩展板(如树莓派的HAT),插上扩展板后自动加载对应的设备树插件,驱动就可以识别新硬件。使用Overlay需要内核配置CONFIG_OF_OVERLAY=y,并且基本的DTB中要有对应的符号信息。
追问4:设备树中pinctrl子系统怎么配置引脚复用?
pinctrl子系统通过设备树配置引脚的复用功能、上下拉、驱动强度等。一般在pincontroller节点下定义各种pinmux配置组,每个外设节点通过pinctrl-names和pinctrl-0等属性引用对应的配置组。例如uart0节点中pinctrl-0 = <&uart0_pins_a>,引用pincontroller下定义好的uart0_pins_a配置。驱动探测时,pinctrl子系统会自动根据设备树配置设置引脚状态,驱动代码中不需要直接操作寄存器。
五、失分表达
"设备树就是把寄存器地址传给驱动"——理解太片面,设备树描述的是完整的硬件信息,远不止寄存器地址
"设备树是ARM特有的"——设备树起源于PowerPC,现在ARM、RISC-V、MIPS等架构都在使用
"compatible随便写不影响"——compatible是设备与驱动匹配的关键,写错了驱动根本不会执行probe
"设备树是给驱动传递参数的唯一方式"——module_param、sysfs等也是常用的参数传递方式
六、准备动作
掌握设备树基本语法:节点、属性、各数据类型的写法
熟悉常用特殊节点:memory、chosen、aliases、cpus、soc及其子节点
记住至少10个of_系列函数的功能和用法
理解platform_driver与设备树的匹配机制,能讲出compatible属性的作用
准备一个实际驱动开发案例,描述从设备树定义到驱动解析的完整流程
七、核心关键词
设备树 DTS/DTB compatible of函数族 platform_driver reg属性 pinctrl 设备树插件

扫码关注





























