【Linux 设备树解析与驱动注册机制全景总结】

发布时间:2026/7/30 16:39:50
【Linux 设备树解析与驱动注册机制全景总结】 Linux 设备树解析与驱动注册机制全景总结并非所有设备树节点都由of_platform_populate()解析of_platform_populate()只是设备树解析过程中的“第一阶段”它有严格的适用范围。不同类型的设备如 I2C/SPI 从设备、杂项设备的解析与注册机制存在本质差别。1. of_platform_populate() 的作用范围of_platform_populate()的核心职责是将 CPU 能够直接通过内存映射Memory-Mapped寻址的硬件节点转化为 Platform 设备struct platform_device。它会解析设备树根节点/下的直接子节点带有compatible simple-bus,simple-mfd,amba-bus等属性的容器节点下的子节点它会跳过chosen、memory等特殊节点非平台总线控制器的子节点比如 I2C 控制器、SPI 控制器、PCIe 控制器下面的子节点关于递归深度的补充说明of_platform_populate()默认从根节点开始逐级向下遍历。对于标记为simple-bus、simple-mfd、amba-bus等容器节点会递归深入解析遇到 I2C/SPI 控制器等非平台总线节点时则停止递归。如果需要强制递归解析可以配合of_platform_bus_probe()或设置device_node标志。2. I2C 与 SPI 设备的解析流程I2C / SPI 的从设备节点of_platform_populate()不会主动去解析。解析流程是两段式的控制器阶段由 of_platform_populate() 触发of_platform_populate()遍历到 I2C/SPI 控制器节点如i2c40003000时只把控制器自身实例化为struct platform_device。此时控制器节点下的所有子设备如 EEPROM、传感器被完全忽略。从设备阶段由控制器驱动触发控制器驱动匹配成功并运行probe()函数控制器驱动调用核心层注册函数如i2c_add_adapter()或spi_register_controller()核心层函数会调用专门的 DT 解析函数如of_i2c_register_devices()/of_register_spi_devices()专门去遍历当前控制器节点下的子节点子节点被转换为struct i2c_client或struct spi_device并挂载到i2c_bus_type或spi_bus_type上形象比喻of_platform_populate()只负责造“总线桥/大楼”控制器而大楼里有哪些“房间/租户”从设备由大楼管家控制器驱动入住后自己去登记。3. PCIe 设备的解析方式PCIe 设备与 I2C/SPI 类似也是两段式解析of_platform_populate()只解析 PCIe 控制器本身生成 platform_devicePCIe 枚举机制非 DT 解析发现下游设备生成struct pci_dev4. 杂项设备Misc Device驱动解析概念澄清miscdevice杂项设备并不是一种设备树节点类型也不是一种总线类型Bus Type它只是内核对字符设备cdev的一种简单封装。在设备树层面上如果一个杂项设备是直接通过 CPU 内存映射或 GPIO 控制的例如一个普通的 GPIO LED 或蜂鸣器它的 DT 节点在根节点或 simple-bus 下。这个节点依然是由of_platform_populate()解析的并被生成为struct platform_device。在驱动层面上驱动编写者注册的是platform_driver。当 Platform 驱动匹配成功在驱动的probe()函数中开发者为了省去手动申请字符设备主/次设备号的繁琐步骤调用了misc_register()将其注册为杂项设备生成/dev/xxx设备节点。关于总线归属的关键说明设备树层面的 platform_device确实挂在platform_bus_type上但 misc_register() 注册的 miscdevice并不挂在任何总线上而是直接挂在misc_list链表上通过misc_class类来管理用户空间看到的/dev/dht11是通过misc_class类的devtmpfs创建的不经过任何总线匹配过程5. 补充场景MMIO 寄存器直接访问的从设备有些设备虽然挂在 I2C/SPI 控制器下但如果驱动直接通过 MMIO 寄存器间接控制比如某些 SoC 内部集成的传感器它们可能直接被映射为 platform_device不走 I2C/SPI 子系统。6. 全景对比总结表设备类型DTS 节点位置DT 转换为设备结构体的执行者生成的内核结构体归属的总线类型 (bus_type)内存映射外设(如 UART, GPIO 控制器)根节点或 simple-bus 下of_platform_populate()struct platform_deviceplatform_bus_typeI2C / SPI 控制器根节点或 simple-bus 下of_platform_populate()struct platform_deviceplatform_bus_typeI2C 从设备I2C 控制器节点内子节点控制器驱动中的of_i2c_register_devices()struct i2c_clienti2c_bus_typeSPI 从设备SPI 控制器节点内子节点控制器驱动中的of_register_spi_devices()struct spi_devicespi_bus_typePCIe 设备PCIe 控制器节点下PCIe 枚举机制非 DT 解析struct pci_devpci_bus_type杂项设备(Misc Device)通常在根节点或总线节点下DT 层面of_platform_populate()用户接口驱动内misc_register()struct platform_devicestruct miscdeviceDT 层面platform_bus_typemisc 层面无独立总线通过misc_class管理