U-Boot 设备树与 Driver Model
现代 U-Boot 大量使用 Device Tree 和 Driver Model。对初 学者来说,你可以先把它们理解为两件事:Device Tree 描述硬件,Driver Model 把硬件描述绑定到驱动和设备实例。
如果说设备树是一份硬件清单,那么 Driver Model 就是 U-Boot 根据这份清单创建、管理、初始化设备的机制。设备树里有节点,不代表设备一定已经可用;驱动存在,也不代表它一定会绑定到你的设备。
1. U-Boot 为什么也需要设备树
Linux 需要 DTB 描述硬件,U-Boot 也需要知道串口、网卡、存储控制器等设备在哪里。否则它无法输出日志、加载文件或通过网络下载镜像。
U-Boot 使用的设备树常被称为 control FDT。它可能来自:
- 编译进 U-Boot 的 DTB。
- 固件传入的 DTB。
- QEMU 动态生成并传入的 DTB。
不要简单认为“U-Boot 用的 DTB”和“传给 Linux 的 DTB”永远是同一份。
2. control FDT 与 Linux DTB
U-Boot 至少可能接触两类 FDT:
- control FDT:U-Boot 自己用来初始化设备。
- OS FDT:U-Boot 启动 Linux 时传给 Linux 的 DTB。
在简单实验中,它们可能来自同一份数据;在真实产品中,它们可能不同。比如 U-Boot control FDT 只保留启动阶段需要的设备,而 Linux DTB 描述完整硬件。
你可以在 U-Boot 中查看当前 FDT 相关信息:
# [U-Boot]
fdt addr
fdt header
如果你手动加载了 Linux DTB 并执行 fdt addr ${fdt_addr_r},当前 fdt 命令操作的地址会切换到这份 DTB。调试时要知道自己正在看哪一份 FDT。
3. Driver Model 的基本概念
Driver Model 中常见对象包括:
uclass:设备类别,例如 serial、eth、mmc。driver:驱动实现。udevice:运行时设备实例。plat/priv:平台数据和驱动私有数据。
你在 U-Boot 命令行中可以观察:
# [U-Boot]
dm tree
dm uclass
dm tree 能帮助你判断设备是否被绑定、探测到了哪一步。
dm tree 的输出通常会按树形结构列出设备。你可以重点观察:
- 设备属于哪个 uclass。
- 设备是否已经 probed。
- 设备名称是否符合预期。
- 设备树节点是否对应到运行时设备。
如果一个设备没有出现在 dm tree 中,说明它可能还没有绑定;如果出现了但使用失败,可能是 probe、资源、驱动或硬件初始化问题。
4. 从设备树到驱动
一个设备节点通常包含 compatible 字符串。驱动通过匹配 compatible 绑定设备。例如某个串口节点声明自己兼容某种 UART,U-Boot 中对应串口驱动就可以接管它。
排查设备不可用时,按顺序检查:
- 设备树中是否有节点。
- 节点状态是否为
okay。 - U-Boot 是否启用了对应驱动配置。
dm tree中是否出现该设备。- probe 是否报错。
你可以在源码中搜索 compatible:
# [Host]
rg "compatible" drivers/serial drivers/net drivers/virtio
也可以搜索某个驱动的 U_BOOT_DRIVER:
# [Host]
rg "U_BOOT_DRIVER" drivers/virtio drivers/serial
U_BOOT_DRIVER 宏通常描述驱动名称、所属 uclass、匹配表和 probe/remove 等函数。看到它,你就找到了 Driver Model 驱动注册的重要入口。
5. uclass 是什么
uclass 是一类设备的抽象。例如所有串口设备都属于 serial uclass,所有以太网设备属于 eth uclass。这样上层代码不用关心具体是 PL011、16550 还是某个厂商 UART,也能以统一方式访问“一个串口设备”。
在 U-Boot 命令行中查看:
# [U-Boot]
dm uclass
你会看到当前系统中有哪些设备类别,以及每类下有哪些设备。
6. bind、probe 和“可用”的区别
Driver Model 中有几个状态容易混淆:
- bind:根据设备树或平台数据创建了设备对象。
- probe:驱动真正初始化设备,申请资源、映射寄存器、准备使用。
- remove:释放设备。
一个设备被 bind 后,还不一定已经 probe;一个设备在 dm tree 中出现,也不代表硬件一定正常工作。真实排障时,要结合日志、命令输出和驱动 probe 返回值判断。