在 Linux 内核设备驱动模型中,struct device
是所有设备类型(如 platform_device
、i2c_client
、pci_dev
等)的通用基类,提供统一的设备抽象接口。以下是其核心概述:
1. 核心作用
- 统一抽象:为所有硬件设备(如 CPU、内存、外设)提供统一的表示,隐藏底层硬件差异。
- 层级管理:通过父设备(
parent
)和子设备(children
)构建设备树,反映硬件拓扑结构。 - 驱动绑定:通过
driver
字段与对应的驱动(struct device_driver
)关联,实现驱动与设备的自动匹配。 - 资源管理:提供访问设备资源(如寄存器、中断、时钟)的通用接口。
- sysfs 集成:通过
kobj
字段在/sys
文件系统中生成设备节点,供用户空间访问。
2. 结构体定义(简化版)
struct device {
struct device *parent; // 父设备(如总线、控制器)
const char *init_name; // 设备初始化名称(调试用)
const struct device_type *type; // 设备类型(如 CPU、内存)
struct bus_type *bus; // 所属总线类型(如 platform、i2c、pci)
struct device_driver *driver; // 关联的驱动(NULL 表示未绑定)
void *driver_data; // 驱动私有数据
struct device_node *of_node; // 设备树节点(若通过 DT 描述)
struct kobject kobj; // 嵌入的 kobject(用于 sysfs)
// ... 其他字段(如电源管理、热插拔、调试信息等)
};
3. 关键字段解析
-
parent
指向父设备(如platform_device
的父设备是总线控制器)。设备树通过parent
构建层级关系(例如:platform_bus
→soc
→i2c-controller
→i2c-device
)。 -
bus
指向设备所属的总线类型(如&platform_bus_type
)。总线类型定义了设备与驱动的匹配规则(如通过name
字段匹配)。 -
driver
指向关联的驱动(struct device_driver
)。当驱动通过device_driver_register()
注册时,内核会自动将其绑定到匹配的设备。 -
of_node
若设备通过设备树(Device Tree)描述,此字段指向对应的设备树节点(struct device_node
),驱动可通过of_
API 解析设备树属性。 -
kobj
嵌入的struct kobject
,用于在/sys
文件系统中生成设备目录(如/sys/devices/platform/my-device
)。用户空间可通过此目录访问设备属性。
4. 核心操作
-
注册设备
通过device_register()
将设备添加到内核设备模型,触发驱动匹配流程。 -
获取设备信息
dev_name(&dev); // 获取设备名称(如 "my-device") dev_driver_string(&dev); // 获取驱动名称(如 "my-driver") dev_get_drvdata(&dev); // 获取驱动私有数据(driver_data)
-
资源访问
通过devm_
前缀的 API(如devm_ioremap_resource()
)管理设备资源,确保资源自动释放。 -
电源管理
pm_runtime_get_sync(&dev); // 请求设备进入活跃状态 pm_runtime_put_sync(&dev); // 允许设备休眠
5. 使用场景
- 驱动开发:驱动通过
struct device
访问设备资源、注册回调函数(如probe
、remove
)。 - 设备树解析:通过
dev->of_node
解析设备树节点属性(如寄存器地址、中断号)。 - 调试与监控:通过
/sys/devices/...
目录查看设备状态、修改属性(如enable
)。
6. 示例:设备与驱动绑定
// 1. 定义设备(如 platform_device)
struct platform_device my_dev = {
.name = "my-device",
.id = 0,
};
// 2. 定义驱动
static struct platform_driver my_drv = {
.driver = {
.name = "my-device", // 必须与设备名称一致!
.owner = THIS_MODULE,
},
.probe = my_probe_func,
.remove = my_remove_func,
};
// 3. 注册设备与驱动
device_register(&my_dev.dev); // 注册设备
platform_driver_register(&my_drv); // 注册驱动
当设备注册后,内核会自动匹配名称相同的驱动,并调用 probe
函数初始化设备。
总结
struct device
是 Linux 设备模型的核心,通过统一的接口抽象硬件设备,支持驱动自动绑定、资源管理、电源控制等功能。驱动开发者通常通过子类(如 platform_device
)操作设备,但最终都依赖 struct device
提供的通用能力。