
在Linux内核中,总线、设备和驱动三者构成了设备模型的核心,它们之间依靠匹配机制协同工作,实现了硬件资源的动态发现、管理和驱动加载。下面简单梳理它们的关系。
总线
- bus_type 定义:include/linux/device.h
struct bus_type {
const char *name;
const char *dev_name;
struct device *dev_root;
struct device_attribute *dev_attrs; /* use dev_groups instead */
const struct attribute_group **bus_groups;
const struct attribute_group **dev_groups;
const struct attribute_group **drv_groups;
int (*match)(struct device *dev, struct device_driver *drv);
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
void (*shutdown)(struct device *dev);
int (*online)(struct device *dev);
int (*offline)(struct device *dev);
int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev);
const struct dev_pm_ops *pm;
const struct iommu_ops *iommu_ops;
struct subsys_private *p;
struct lock_class_key lock_key;
};以下是针对 struct bus_type(总线类型结构体)的详细说明。该结构体在 Linux 设备模型中扮演核心角色,用于表示系统中的一个总线,如 PCI、USB、I2C 等。总线是处理器与其下挂载设备之间的通道,即使某些总线是内部的或虚拟的(如平台总线),也由其统一管理。
结构体字段详细说明
- name
类型:const char *
作用:总线的名称,如 “pci”、”usb”、”i2c” 等。这是总线的唯一标识,用于在系统中注册和识别总线类型。 - dev_name
类型:const char *
作用:用于子系统为设备生成名称的格式化字符串模板(如 “foo%u”,其中 %u 会被设备 ID 替换),便于在 /sys/bus/ 下统一命名设备节点。 - dev_root
类型:struct device *
作用:指向该总线的默认父设备。在设备注册时,若无显式指定父设备,则使用此设备作为父节点(通常在 sysfs 中体现为设备的上级目录)。 - dev_attrs(已弃用)
类型:struct device_attribute *
作用:总线上设备的默认属性数组(旧版接口),现推荐使用 dev_groups 替代。属性用于在 sysfs 中暴露设备信息(如设备号、状态等)。 - bus_groups
类型:const struct attribute_group **
作用:总线本身的属性组,用于在 sysfs 的总线目录(如 /sys/bus/pci/)下创建属性文件,例如总线的版本号、支持的功能等。 - dev_groups
类型:const struct attribute_group **
作用:总线上所有设备的默认属性组。当设备注册到该总线时,这些属性会自动添加到设备的 sysfs 目录中,无需每个设备驱动单独定义。 - drv_groups
类型:const struct attribute_group **
作用:总线上设备驱动的默认属性组。这些属性会添加到每个注册到该总线的驱动的 sysfs 目录中,用于展示或配置驱动相关参数。
关键方法(回调函数):
- match
函数签名:int (*match)(struct device *dev, struct device_driver *drv)
作用:当新设备或驱动添加到总线时调用,判断设备是否可由指定驱动处理。返回非零值表示匹配成功,触发后续的 probe 操作。 - uevent
函数签名:int (*uevent)(struct device *dev, struct kobj_uevent_env *env)
作用:在设备添加、移除或状态变更时调用,用于向用户空间发送 uevent 事件(如 udev 规则触发),并可添加自定义环境变量。 - probe
函数签名:int (*probe)(struct device *dev)
作用:当设备与驱动匹配成功后调用,负责初始化设备。通常会调用具体设备驱动的 probe 函数完成硬件检测和资源配置。 - remove
函数签名:int (*remove)(struct device *dev)
作用:当设备从总线移除时调用,用于清理资源、注销设备,防止内存泄漏或资源冲突。 - shutdown
函数签名:void (*shutdown)(struct device *dev)
作用:在系统关机时调用,确保设备安全进入静默状态,停止所有操作。
电源管理相关方法:
- online / offline
函数签名:int (*online)(struct device *dev) / int (*offline)(struct device *dev)
作用:用于设备的热插拔管理。online 将设备重新上线(如恢复电源),offline 则使设备离线(如准备热移除),执行失败会阻止操作。 - suspend / resume
函数签名:int (*suspend)(struct device *dev, pm_message_t state) / int (*resume)(struct device *dev)
作用:设备睡眠/唤醒回调。suspend 将设备置为低功耗状态,resume 恢复其正常运行。state 参数指定睡眠的深度(如待机、休眠)。 - pm
类型:const struct dev_pm_ops *
作用:指向电源管理操作集的结构体,包含更细粒度的 PM 回调(如 runtime_suspend、runtime_resume),委托给具体设备驱动的 PM 实现。
其他字段:
- iommu_ops
类型:const struct iommu_ops *
作用:IOMMU(输入输出内存管理单元)相关操作,用于总线级别的地址翻译和设备隔离,常用于虚拟化或安全场景。 - p
类型:struct subsys_private *
作用:驱动核心私有数据,仅由内核设备模型内部使用,包含设备链表、驱动链表、互斥锁等,对外不可见。 - lock_key
类型:struct lock_class_key
作用:锁验证器(lockdep)使用的锁分类键,用于调试内核中的锁依赖关系,防止死锁。
struct bus_type 是 Linux 设备模型的核心组件,通过统一的接口管理总线行为,包括设备枚举、驱动匹配、电源管理、sysfs 属性展示等。它使不同总线(如物理的 PCI 或虚拟的平台总线)能够以一致的方式集成到内核中,支持动态设备发现和热插拔。
驱动
- device_driver定义:include/linux/device.h
struct device_driver {
const char *name;
struct bus_type *bus;
struct module *owner;
const char *mod_name; /* used for built-in modules */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
enum probe_type probe_type;
const struct of_device_id *of_match_table;
const struct acpi_device_id *acpi_match_table;
int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
const struct attribute_group **groups;
const struct dev_pm_ops *pm;
struct driver_private *p;
};以下是针对 struct device_driver(设备驱动结构体)的详细说明。该结构体在 Linux 设备模型中用于表示一个设备驱动程序,负责管理特定类型的设备,并与总线协同工作来实现设备的初始化、操作和电源管理。
结构体字段详细说明
- name
类型:const char *
作用:驱动的名称,在系统中唯一标识该驱动。通常与驱动模块的名称一致(如 “e1000” 用于 Intel 网卡驱动)。在 /sys/bus/xxx/drivers/ 目录下会以其命名。 - bus
类型:struct bus_type *
作用:指向该驱动所属的总线类型(如 &pci_bus_type)。驱动必须注册到对应的总线,以便总线核心在设备枚举时调用驱动的 probe 函数。 - owner
类型:struct module *
作用:指向拥有该驱动的模块(通常使用 THIS_MODULE)。用于模块引用计数管理,防止驱动模块在设备仍在使用时被卸载。 - mod_name
类型:const char *
作用:内置模块(built-in)的名称。对于编译进内核的驱动,此字段指定模块名,用于调试或日志记录。 - suppress_bind_attrs
类型:bool
作用:若为 true,则禁止通过 sysfs 进行驱动的绑定(bind)和解绑(unbind)操作。常用于核心驱动,避免用户空间意外导致设备失效。 - probe_type
类型:enum probe_type
作用:指定驱动的探测类型,影响设备与驱动的匹配时机。可选值包括:
PROBE_FORCE_SYNCHRONOUS:强制同步探测。
PROBE_DEFAULT_STRATEGY:默认异步探测等。 - of_match_table
类型:const struct of_device_id *
作用:设备树(Device Tree)匹配表,用于描述驱动支持的设备树兼容性字符串(如 { .compatible = “vendor,device” })。在嵌入式系统中,设备树节点通过此表与驱动匹配。 - acpi_match_table
类型:const struct acpi_device_id *
作用:ACPI(高级配置与电源接口)设备匹配表,用于 ACPI 系统中的设备标识匹配。
关键操作回调函数:
- probe
函数签名:int (*probe)(struct device *dev)
作用:当设备与驱动通过总线匹配成功后调用。驱动在此函数中初始化设备、分配资源、注册中断等。返回 0 表示成功,负数表示错误。 - remove
函数签名:int (*remove)(struct device *dev)
作用:当设备断开或驱动卸载时调用,用于释放资源、注销中断、清理设备状态。 - shutdown
函数签名:void (*shutdown)(struct device *dev)
作用:系统关机时调用,确保设备安全停止操作(如关闭电源、保存状态)。 - suspend / resume
函数签名:int (*suspend)(struct device *dev, pm_message_t state) / int (*resume)(struct device *dev)
作用:设备电源管理回调。suspend 将设备置为低功耗状态,resume 恢复设备运行。state 参数指定休眠深度(如 PM_SUSPEND_TO_RAM)。
其他字段:
- groups
类型:const struct attribute_group **
作用:驱动的默认属性组,用于在 sysfs 的驱动目录(如 /sys/bus/pci/drivers/e1000/)下自动创建属性文件,暴露驱动信息或配置选项。 - pm
类型:const struct dev_pm_ops *
作用:指向电源管理操作集的指针,包含更细粒度的电源管理回调(如 runtime_suspend、runtime_resume),用于设备运行时电源控制。 - p
类型:struct driver_private *
作用:驱动核心的私有数据,由设备模型内部使用,包含驱动状态、设备链表、锁等,对外部透明。
struct device_driver 是 Linux 设备驱动框架的核心结构体,它定义了驱动与总线、设备的交互接口。通过实现其回调函数(如 probe、remove),驱动能够响应设备的生命周期事件。结合设备树或 ACPI 的匹配机制,它支持动态设备发现和自动加载,是实现硬件抽象和跨平台兼容性的关键。
设备
- device定义:include/linux/device.h
struct device {
struct device *parent;
struct device_private *p;
struct kobject kobj;
const char *init_name; /* initial name of the device */
const struct device_type *type;
struct mutex mutex; /* mutex to synchronize calls to
* its driver.
*/
struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */
void *platform_data; /* Platform specific data, device
core doesn't touch it */
void *driver_data; /* Driver data, set and get with
dev_set/get_drvdata */
struct dev_pm_info power;
struct dev_pm_domain *pm_domain;
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
struct irq_domain *msi_domain;
#endif
#ifdef CONFIG_PINCTRL
struct dev_pin_info *pins;
#endif
#ifdef CONFIG_GENERIC_MSI_IRQ
struct list_head msi_list;
#endif
#ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif
u64 *dma_mask; /* dma mask (if dma'able device) */
u64 coherent_dma_mask;/* Like dma_mask, but for
alloc_coherent mappings as
not all hardware supports
64 bit addresses for consistent
allocations such descriptors. */
unsigned long dma_pfn_offset;
struct device_dma_parameters *dma_parms;
struct list_head dma_pools; /* dma pools (if dma'ble) */
struct dma_coherent_mem *dma_mem; /* internal for coherent mem
override */
#ifdef CONFIG_DMA_CMA
struct cma *cma_area; /* contiguous memory area for dma
allocations */
#endif
/* arch specific additions */
struct dev_archdata archdata;
struct device_node *of_node; /* associated device tree node */
struct fwnode_handle *fwnode; /* firmware device node */
dev_t devt; /* dev_t, creates the sysfs "dev" */
u32 id; /* device instance */
spinlock_t devres_lock;
struct list_head devres_head;
struct klist_node knode_class;
struct class *class;
const struct attribute_group **groups; /* optional groups */
void (*release)(struct device *dev);
struct iommu_group *iommu_group;
bool offline_disabled:1;
bool offline:1;
};以下是 struct device(设备结构体)的详细说明。该结构体是Linux设备模型中最核心的数据结构之一,用于表示系统中的每个物理或逻辑设备,并管理设备的生命周期、资源、电源管理、与总线和驱动的关联等。
结构体字段详细说明
- parent
类型:struct device *
作用:指向父设备的指针,用于构建设备层次结构。在sysfs中表现为目录嵌套关系(如USB设备以USB控制器为父设备)。 - p
类型:struct device_private *
作用:设备核心的私有数据,仅由设备模型内部使用,包含设备状态、链表、锁等管理信息。 - kobj
类型:struct kobject
作用:内嵌的kobject核心对象,负责设备的sysfs表示、引用计数管理和热插拔事件(uevent)基础。 - init_name
类型:const char *
作用:设备的初始名称。如果未设置,内核在注册时会根据总线或设备ID自动生成名称。 - type
类型:const struct device_type *
作用:指向设备类型的指针,定义特定类型设备的通用属性和操作(如网络设备、块设备等特有行为)。 - mutex
类型:struct mutex
作用:互斥锁,用于同步对设备的操作(如probe、remove),防止并发访问导致竞态条件。 - bus
类型:struct bus_type *
作用:设备所属的总线类型(如&pci_bus_type)。总线核心通过此字段管理设备的匹配与探测流程。 - driver
类型:struct device_driver *
作用:指向当前绑定到该设备的驱动。在总线匹配成功后由设备模型设置,用于驱动与设备的关联。 - platform_data
类型:void *
作用:平台相关的私有数据,由板级代码或固件传递,驱动可读取但设备核心不修改(如硬件配置参数)。 - driver_data
类型:void *
作用:驱动的私有数据,通过dev_set_drvdata()/dev_get_drvdata()访问,用于存储驱动实例的上下文信息。 - power
类型:struct dev_pm_info
作用:设备的电源管理状态信息,包括当前电源状态、唤醒能力等。 - pm_domain
类型:struct dev_pm_domain *
作用:指向电源管理域的指针,用于对一组设备进行统一的电源状态控制(如SoC子系统的电源管理)。 - msi_domain(条件编译)
类型:struct irq_domain *
作用:MSI(消息信号中断)中断域,用于管理设备的高级中断功能(需开启CONFIG_GENERIC_MSI_IRQ_DOMAIN)。 - pins(条件编译)
类型:struct dev_pin_info *
作用:设备引脚控制信息,用于管理引脚复用、配置状态(需开启CONFIG_PINCTRL)。 - msi_list(条件编译)
类型:struct list_head
作用:MSI中断描述符链表,维护设备使用的MSI中断列表(需开启CONFIG_GENERIC_MSI_IRQ)。 - numa_node(条件编译)
类型:int
作用:设备所在的NUMA节点编号,用于优化内存分配(使内存接近设备,需开启CONFIG_NUMA)。 - dma_mask
类型:u64 *
作用:DMA地址掩码,限制设备DMA可访问的内存地址范围(如32位设备设置为0xFFFFFFFF)。 - coherent_dma_mask
类型:u64
作用:一致性DMA掩码,用于分配设备与CPU共享缓存的一致性内存映射。 - dma_pfn_offset
类型:unsigned long
作用:物理地址与DMA地址的页框号偏移,用于处理IOMMU或特殊内存布局的平台。 - dma_parms
类型:struct device_dma_parameters *
作用:DMA参数配置,包括最大段大小、段数量等,用于优化DMA映射操作。 - dma_pools
类型:struct list_head
作用:DMA内存池链表,用于管理小对象DMA内存的分配与释放。 - dma_mem
类型:struct dma_coherent_mem *
作用:指向设备的一致性DMA内存区域,用于覆盖默认的DMA分配器。 - cma_area(条件编译)
类型:struct cma *
作用:连续内存分配器(CMA)区域,用于DMA内存的预留管理(需开启CONFIG_DMA_CMA)。 - archdata
类型:struct dev_archdata
作用:架构相关的私有数据,由各CPU平台自行定义和使用。 - of_node
类型:struct device_node *
作用:指向设备树(Device Tree)中对应节点的指针,用于从设备树获取配置信息(如寄存器地址、中断号)。 - fwnode
类型:struct fwnode_handle *
作用:通用固件节点句柄,支持设备树、ACPI等多种固件接口。 - devt
类型:dev_t
作用:设备号,用于在/dev目录下创建设备文件节点。 - id
类型:u32
作用:设备实例ID,用于区分同类型的多个设备(如多个网卡序号)。 - devres_lock
类型:spinlock_t
作用:设备资源(devres)管理的自旋锁,保护资源链表的并发访问。 - devres_head
类型:struct list_head
作用:设备资源链表头,用于自动管理驱动分配的资源(避免资源泄漏)。 - knode_class
类型:struct klist_node
作用:链表节点,用于将设备链接到所属的设备类(如class)中。 - class
类型:struct class *
作用:设备所属的类别(如”input”、”block”),用于在/sys/class/下分类管理设备。 - groups
类型:const struct attribute_group **
作用:设备的默认属性组,在sysfs中自动创建属性文件(如设备信息、状态等)。 - release
类型:void (*release)(struct device *dev)
作用:设备引用计数归零时调用的回调函数,负责释放设备占用的资源。每个设备必须实现此函数。 - iommu_group
类型:struct iommu_group *
作用:IOMMU组指针,用于管理共享IOMMU域的设备(如PCIe设备透传)。 - offline_disabled
类型:bool
作用:如果为true,则禁止设备离线(如关键设备不允许热插拔)。 - offline
类型:bool
作用:标识设备当前是否处于离线状态(如热插拔移除后)。
struct device 是Linux设备模型的核心结构体,它抽象了系统中所有物理或逻辑设备的通用属性和行为。通过层次化结构(parent)、总线关联(bus)、驱动绑定(driver)和资源管理(DMA、电源、中断等),实现了设备的统一管理。其设计支持动态设备发现、热插拔、跨平台兼容性,是驱动开发者和内核管理硬件的基础框架。
核心关系概述
总线作为平台,设备作为硬件实体,驱动作为软件控制者,三者形成”总线承载设备,驱动控制设备”的协作模式。

No responses yet