一、Platform 设备的本质:总线之外的「板载硬连接」
Platform 设备(平台设备)是直接焊接在主板上、不依赖 PCIe/USB 等动态总线的片上外设,典型如:
- 片上 UART 控制器(如 STM32 的 USART)
- SoC 集成的 GPIO 控制器
- 板载 RTC、PMU、SPI 控制器
- x86 平台的 LPC 总线上的 Super I/O 芯片
特别地, 集成-DC
、集成-GPU
也都是直接挂载在系统总线上的片上外设.
- 在 Linux 驱动中叫 platform 设备;
- 设备寄存器空间、显存、中断等都是由
ACPI 表
或设备树
完成静态资源描述;
核心特点(对比 PCIe 设备):
特性 | PCIe 设备(动态枚举) | Platform 设备(静态声明) |
---|---|---|
连接方式 | 插卡 / 动态枚举 | 直接焊接 / 硬连线 |
资源分配 | 总线驱动动态分配(如 BAR) | ACPI / 设备树静态指定 |
枚举方式 | PnP 扫描(如 PCIe 枚举) | 解析 ACPI 表或设备树节点 |
驱动绑定 | 依赖 ID 匹配(vendor/device) | 依赖设备名称(如 “gpio@1234”) |
二、Platform 设备的「出生地」:ACPI 表 vs 设备树
- x86 平台:ACPI 表(AML 语言)静态描述
// ACPI DSDT片段:描述板载GPIO控制器
Device (GPI0) {
// 设备类型标识
Name (_HID, "PNP0C09") // GPIO控制器硬件ID
// 静态资源声明
Name (_CRS, ResourceTemplate() {
Memory32Fixed (ReadWrite, // 固定内存映射
0x01C20000, // 基地址
0x00001000 // 大小4KB
)
IRQNoFlags (8) // 中断号8
})
// 驱动匹配标识
Name (_DSM, Package() {
"linux,compatible", // Linux兼容标识
Package() {"acpi-gpio"} // 驱动匹配字符串
})
}
关键逻辑:
- 通过
_HID
/_DSM
声明设备类型和驱动匹配规则 _CRS
直接写死内存地址、中断等资源- 内核通过 ACPI 解析生成 platform_device(无需动态枚举)
- 嵌入式平台:设备树(DTS)声明
// 树莓派4设备树片段:板载UART
serial {
compatible = "brcm,bcm2835-uart"; // 驱动匹配字符串
reg = <0x0 0x7e201000 0x0 0x400>; // 基地址+大小
interrupts = <0x0 80 IRQ_TYPE_LEVEL_HIGH>; // 中断号
clocks = <&clk 13>; // 时钟引用
};
关键逻辑:
compatible
字段替代 ACPI 的_DSM
reg
直接指定寄存器地址范围- 内核解析 DTS 生成 platform_device(编译时确定)
三、Platform 设备的「生命周期」:从声明到驱动绑定
- 内核启动阶段:
- x86:解析 ACPI 表,调用
acpi_create_platform_device()
生成设备; - 嵌入式:解析 DTS,调用
of_platform_bus_create()
生成设备;
- x86:解析 ACPI 表,调用
- 资源映射:
// 驱动获取静态资源(示例)
// 从平台设备空间中获取指定资源例如:IORESOURCE_MEM为内存资源
struct resource res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
// 将设备的内存资源映射到内核的虚拟地址空间,并返回映射后的虚拟地址。
void __iomem *base = devm_ioremap_resource(&pdev->dev, &res);
- 驱动绑定:
// platform_driver匹配逻辑
static const struct of_device_id gpio_of_match[] = {
{ .compatible = "acpi-gpio" },
{}
};
MODULE_DEVICE_TABLE(of, gpio_of_match);
static struct platform_driver gpio_driver = {
.probe = gpio_probe,
.driver = {
.name = "acpi-gpio",
.of_match_table = gpio_of_match,
},
};
四、为什么不用 PnP 动态枚举?
- 硬件特性:板载设备无热插拔需求,资源固定;
- 性能优化:避免枚举扫描(如 PCIe 的 256BAR 探测),减少启动时间;
- 设计约束:部分片上外设不支持 BAR 探测(如仅有固定寄存器地址);
五、典型应用场景
场景 | 设备示例 | 声明方式 |
---|---|---|
x86 主板 GPIO | Intel PCH GPIO | ACPI DSDT |
手机 PMU | 高通 PM8998 电源管理芯片 | 设备树 DTS |
工业控制板 ADC | 集成的 16 位模数转换器 | 设备树 DTS |
路由器 NAND 控制器 | SoC 内置的 NAND 控制器 | 设备树 DTS |
总结:Platform 设备是「焊在主板上的静态资源集合」
- 与 PCIe 的本质区别:非总线枚举,资源静态声明
- ACPI / 设备树的作用:替代动态枚举,告诉内核「我是谁,资源在哪」
- 驱动开发要点:关注
compatible
匹配和静态资源解析(而非 BAR 探测)
理解 Platform 设备,本质是理解「嵌入式系统 / 主板级设备的静态配置哲学」—— 这与 PCIe 的「即插即用」动态哲学形成鲜明对比,却共同构成了现代计算机的设备管理体系。