1. 平台子系统与设备树绑定概述
在嵌入式Linux开发中,平台子系统和设备树的绑定过程是内核初始化的关键环节。这套机制让ARM架构的Linux系统能够在不重新编译内核的情况下,通过修改设备树文件来支持不同的硬件配置。我从事ARM-Linux开发多年,发现这是最容易被初学者忽视但又至关重要的技术点之一。
设备树绑定的本质是将硬件描述(设备树)转换为内核可识别的软件对象(platform_device)。整个过程涉及总线初始化、设备树解析、资源分配和驱动匹配四个核心阶段。以常见的i.MX6ULL处理器为例,当内核启动时,会依次完成以下工作:
- 初始化platform总线(虚拟总线)
- 解析.dtb文件中的设备节点
- 为每个兼容节点创建platform_device
- 将设备注册到总线
- 与platform_driver进行匹配
关键提示:设备树绑定过程发生在内核启动的早期阶段,具体在do_basic_setup()中的driver_init()之后。这个时机选择非常重要,因为后续驱动初始化需要依赖已注册的平台设备。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 设备树绑定核心流程解析
2.1 平台总线初始化
平台总线(platform_bus_type)是Linux内核中的一条虚拟总线,专门用于管理那些没有物理总线的SoC外设。它的初始化由platform_bus_init()函数完成:
c复制// drivers/base/platform.c
int __init platform_bus_init(void)
{
int error;
// 清理早期平台设备
early_platform_cleanup();
// 注册平台总线设备
error = device_register(&platform_bus);
if (error) {
put_device(&platform_bus);
return error;
}
// 注册平台总线类型
error = bus_register(&platform_bus_type);
if (error)
device_unregister(&platform_bus);
// 注册设备树重配置通知器
of_platform_register_reconfig_notifier();
return error;
}
这个函数主要完成三项工作:
- 注册platform_bus设备(/sys/devices/platform)
- 注册platform_bus_type总线(/sys/bus/platform)
- 设置设备树动态重配置通知
在实际项目中,我曾遇到过platform_bus_init失败导致后续设备无法注册的情况。通过dmesg可以看到类似"platform bus: failed to register"的错误信息。这类问题通常是由于内存不足或早期平台设备冲突导致的。
2.2 设备树解析与设备创建
设备树解析的入口函数是of_platform_populate(),它会遍历设备树的根节点及其子节点:
c复制// drivers/of/platform.c
int of_platform_populate(struct device_node *root,
const struct of_device_id *matches,
const struct of_dev_auxdata *lookup,
struct device *parent)
{
struct device_node *child;
int rc = 0;
root = root ? o
