platform 驱动分两部分:驱动代码(platform_driver 结构,probe/remove)和设备树(dts 描述硬件资源);设备树里 compatible 字符串匹配驱动,probe 里做初始化;新内核几乎都用设备树代替静态 board 文件。
本文概述
platform 驱动是 Linux 设备模型核心,面试常考:设备树是什么、compatible 怎么匹配、probe 什么时候调、resource 怎么获取。回答要讲清驱动和设备分离。
核心要点
platform 驱动把驱动代码和设备信息分离:驱动 .c,设备描述在 dts
设备树 dts 描述地址、中断、时钟、GPIO,compatible 字符串匹配驱动
probe() 在设备和驱动匹配成功时调用,做初始化
platform_get_resource() 获取寄存器地址和中断号
新内核(3.x 后)都用设备树,不再写 static board device

面试官考察点
面试官看你是否写过 platform 驱动、是否理解设备树。重点听:compatible 匹配、probe、resource。
回答思路
先讲设备树为什么出现,再讲驱动结构,最后给代码骨架。
参考回答
为什么用设备树。早期内核把硬件信息写在 board 文件(.c),每款板都要改内核代码。设备树把硬件描述从内核代码分离:
同一份内核支持多款板;
硬件改动改 dts 就行,不用改驱动代码;
ARM 新平台几乎都用设备树。
设备树怎么描述。在 .dts 文件里:
mydevice@10000000 {
compatible = "fanyi,mydevice-v1";
reg = <0x10000000 0x1000>;
interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_uart>;
};
驱动怎么匹配。驱动里 of_match_table 列 compatible 字符串,和 dts 匹配上就调 probe:
static const struct of_device_id my_of_match[] = {
{ .compatible = "fanyi,mydevice-v1" },
{}
};
static struct platform_driver my_driver = {
.probe = my_probe,
.remove = my_remove,
.driver = {
.name = "mydevice",
.of_match_table = my_of_match,
},
};
module_platform_driver(my_driver);
probe 里做什么。
platform_get_resource() 获取寄存器地址和中断;
devm_ioremap_resource() 映射寄存器;
devm_request_irq() 注册中断;
init 字符设备/proc/sysfs;
初始化硬件。
probe 调用时机。内核启动时解析 dts,设备和驱动匹配成功就调 probe。先看 dts 里 compatible 和驱动里 of_match_table 对不对。
三种驱动模型对比。
| 模型 | 适用 | 设备信息 |
|---|---|---|
| platform | 内存映射设备、SOC 外设 | dts 描述寄存器/中断 |
| i2c_client | I2C 设备 | i2c_board_info 或 dts |
| spi_driver | SPI 设备 | dts 描述片选和速率 |
常见问题。
probe 没调:compatible 拼写错、dts 没编进 dtb、驱动没加载;
用 devm_ 函数:自动释放资源,不用手动 cleanup;
alias 和 status:dts 里 status = "okay" 才启用。

扫码关注




























