[TOC]
drivers/base/faux.c 虚拟设备总线(Faux Bus) 简化虚拟设备驱动的创建
历史与背景
这项技术是为了解决什么特定问题而诞生的?
drivers/base/faux.c
文件所实现的 “Faux Bus”(虚拟总线)是一项较新的内核技术,在 Linux 6.14 内核中被合并。它的诞生主要是为了解决一个长期存在的内核开发“滥用”问题:将平台总线(Platform Bus)用于不属于平台设备(Platform Device)的场景。
内核维护者 Greg Kroah-Hartman 指出,多年来,许多开发者为了利用设备模型的便利性(如自动的驱动-设备绑定、probe/remove回调机制),会将一些纯粹的虚拟设备或简单的逻辑设备注册为“平台设备”。 这种做法在功能上可行,但从设计哲学上看是不正确的,因为平台设备本意是指那些在SoC(片上系统)上,无法通过正常总线(如PCI, USB)枚举发现的、有固定内存地址或硬件资源的设备。将纯虚拟设备(例如一个用于测试的dummy regulator)注册为平台设备,是一种概念上的滥用,并给代码带来了不必要的复杂性。
Faux Bus 的目的就是提供一个极其简单的、专为这类虚拟或“假”设备设计的总线,从而清理代码,让平台总线的用途回归其本意。
它的发展经历了哪些重要的里程碑或版本迭代?
- 2025年2月:由内核核心维护者 Greg Kroah-Hartman 提出 “Faux Bus” 的概念和初始补丁集,并征求社区意见。
- Linux 6.14内核:该技术被正式合并进入主线内核。一个显著的特点是,它在被引入的同时,就提供了C语言和Rust语言的API绑定,这在内核新接口的开发中较为少见,也体现了对新兴内核开发语言的支持。
- Linux 6.15及以后:社区开始将内核中原先滥用平台总线的驱动,逐步转换到使用 Faux Bus。
目前该技术的社区活跃度和主流应用情况如何?
作为一个新兴的内核API,Faux Bus 正处于被逐步推广和应用的阶段。内核社区正在积极地识别那些适合转换的驱动程序,并提交补丁。它的主要应用场景是内核内部的虚拟设备、测试驱动和一些简单的逻辑抽象设备,例如:
- Dummy regulator 驱动
- USB PHY (physical layer) 的一些辅助代码
核心原理与设计
它的核心工作原理是什么?
drivers/base/faux.c
的核心原理是提供一个极简的API,将“创建设备”和“创建并绑定驱动”这两个动作合二为一。
- 定义一个新总线:代码内部定义了一个名为 “faux” 的
bus_type
。这是一个非常简单的总线,没有复杂的匹配逻辑。 - 统一的创建函数:它对外暴露的核心API是
faux_device_create_with_groups()
。当一个内核模块调用这个函数时,它会执行以下一系列操作:- 动态地创建一个
struct device_driver
实例。这个驱动被设置为属于 “faux” 总线。 - 动态地创建一个
struct device
实例,并将其总线也设置为 “faux”。 - 自动绑定:由于设备和驱动被创建时就明确了对应关系,内核会立即将它们绑定在一起。这个绑定操作会触发调用调用者提供的
.probe
回调函数。
- 动态地创建一个
- 生命周期管理:
faux_device_create_with_groups()
函数会返回一个指向新创建的faux_device
的指针。这个设备的生命周期由调用者管理。当不再需要该设备时,调用者只需调用faux_device_destroy()
,该函数会自动处理驱动的.remove
回调、设备和驱动的注销以及内存的释放。
它的主要优势体现在哪些方面?
- API极其简单:相比平台设备的注册,Faux Bus 的API更简单,只需要两个核心函数(创建和销毁)。
- 概念清晰:为虚拟设备和逻辑设备提供了一个专属的、名正言顺的“家”,避免了对平台总线的滥用,使内核代码的意图更清晰。
- 代码更简洁:在一些转换案例中,使用 Faux Bus 相比原先使用平台总线的代码,行数有所减少,逻辑也更直接。
- 自动绑定:创建设备的同时就隐式创建并绑定了驱动,开发者无需关心匹配逻辑。
它存在哪些已知的劣势、局限性或在特定场景下的不适用性?
- 功能极简:Faux Bus 被设计为只处理最简单的情况。它没有设备树(Device Tree)或ACPI支持,不适用于需要从固件获取信息的设备。
- 无匹配逻辑:它不支持一个驱动匹配多个设备,或者一个设备在多个驱动间选择。设备和驱动是一对一的、在创建时就锁定的关系。
- 不适用于真实硬件:它的设计目标是纯软件的、虚拟的设备。任何与真实物理总线或硬件资源相关的设备都不应该使用 Faux Bus。
使用场景
在哪些具体的业务或技术场景下,它是首选解决方案?请举例说明。
Faux Bus 是为那些纯软件模拟的、生命周期由其他内核模块动态管理的逻辑设备提供的首选解决方案。
- 场景一:Dummy Regulator
内核的regulator/dummy.c
驱动可以创建一个虚拟的稳压器(regulator),用于测试或满足那些在软件上需要一个regulator句柄但实际上没有硬件对应的场景。在过去,它通过注册一个platform_device
和platform_driver
来实现。现在,它可以直接使用faux_device_create()
来创建这个虚拟稳压器,代码更简洁且概念上更正确。 - 场景二:USB PHY 辅助逻辑
某些USB控制器驱动需要在内部管理一个抽象的PHY层,这个PHY层可能没有独立的物理设备与之对应。使用 Faux Bus 可以为此创建一个逻辑上的设备和驱动,以便利用设备模型的probe/remove机制来管理其初始化和清理过程,而无需污染平台总线。
是否有不推荐使用该技术的场景?为什么?
- 所有与物理硬件相关的设备:如果一个设备是通过PCIe、USB、I2C、SPI等物理总线连接的,或者是在设备树/ACPI中描述的SoC内部设备,绝对不能使用 Faux Bus。这些设备必须使用其对应的真实总线类型(
pci_driver
,usb_driver
,platform_driver
等)。 - 需要驱动与设备分离的场景:如果希望一个驱动能支持多种设备,或者一个设备能由多个驱动中的一个来处理(例如一个通用驱动和一个厂商特定驱动),则不应使用 Faux Bus,因为它不支持这种分离的匹配逻辑。
对比分析
请将其 与 其他相似技术 进行详细对比。
Faux Bus 的主要对比对象就是被它取代的“滥用”方案——平台总线(Platform Bus),以及另一个虚拟总线——虚拟总线(Virtual Bus)。
特性 | Faux Bus (faux.c ) |
Platform Bus (platform.c ) |
Virtual Bus (subsys_virtual_register ) |
---|---|---|---|
设计用途 | 用于纯粹的、简单的、与硬件无关的虚拟/逻辑设备,以取代对平台总线的滥用。 | 用于SoC上那些无法被硬件自动枚举的、通常在设备树或ACPI中描述的真实硬件设备。 | 用于表示一类虚拟设备,这些设备通常出现在 /sys/devices/virtual/ 下,如网络设备(net)或输入设备(input)。 |
API复杂度 | 极低。核心API只有创建和销毁,设备和驱动在创建时自动绑定。 | 中等。需要分别定义platform_device 和platform_driver ,并通过匹配机制(如设备树的compatible 字符串或设备名)进行绑定。 |
低。提供注册总线的API,但设备和驱动的注册仍需分开处理。 |
设备-驱动关系 | 一对一,创建时锁定。一个faux_device_create 调用就唯一对应一个驱动实例。 |
多对多,运行时匹配。一个驱动可以支持多种设备,一个设备也可以匹配多个潜在的驱动。 | 灵活,由子系统自身决定。 |
硬件/固件支持 | 无。完全不处理设备树或ACPI。 | 核心特性。平台总线的核心任务就是处理通过固件描述的硬件设备。 | 无。 |
Sysfs路径 | /sys/bus/faux/devices/ |
/sys/bus/platform/devices/ |
/sys/devices/virtual/<subsys_name>/ |
典型例子 | Dummy regulator, USB PHY 逻辑。 | I2C控制器、SPI控制器、SoC内部的DMA引擎。 | 网络接口(eth0)、TTY设备、输入设备(event0)。 |
faux_bus_init: 初始化并注册一个虚拟总线
此代码片段的作用是定义并注册一个完整的、自包含的 “faux” (虚拟) 总线系统。这个过程是 Linux 设备模型中建立新总线的基础, 它包括三个核心步骤:
- 注册一个根设备 (
faux_bus_root
): 这个设备在sysfs
中作为虚拟总线层次结构的顶层目录, 通常位于/sys/devices/faux
。 - 注册一个总线类型 (
faux_bus_type
): 这定义了总线的名称、行为以及最重要的——设备与驱动的匹配规则 (match
函数) 和探测/移除逻辑 (probe
/remove
函数)。 - 注册一个驱动程序 (
faux_driver
): 这是挂载在此总线上的一个驱动实例。
1 | /* |
faux_device_create_with_groups / faux_device_create: 创建并注册一个虚拟设备
这两个函数共同提供了一个接口, 用于在内核中创建和注册一个虚拟的 (faux) 设备。虚拟设备是纯粹由软件定义的实体, 它们不直接对应任何物理硬件, 但能被无缝地集成到Linux的设备驱动模型中。这使得它们可以拥有自己的驱动程序(通过回调函数实现)、出现在sysfs
文件系统中, 并与其他真实设备进行交互。faux_device_create_with_groups
是核心实现, 它允许在创建设备的同时为其定义一组sysfs
属性文件。faux_device_create
则是一个简化的便利性封装, 用于创建一个不带任何额外sysfs
属性的虚拟设备。
faux_device_create_with_groups
: 创建带sysfs
属性的虚拟设备 (核心实现)
1 | /* |