rfkill - RF 射频开关支持

介绍

rfkill 子系统为禁用系统中任何无线电发射器提供了一个通用接口。当发射器被阻止时,它不应辐射任何功率。

该子系统还提供了对按钮按下做出反应并禁用特定类型(或所有)发射器的能力。这适用于需要关闭发射器的情况,例如在飞机上。

rfkill 子系统具有“硬”阻止和“软”阻止的概念,它们在含义上几乎没有区别(阻止 == 关闭发射器),而是在它们是否可以更改方面存在差异

  • 硬阻止

    无法被软件覆盖的只读无线电阻止

  • 软阻止

    可写的无线电阻止(不必可读),由系统软件设置。

rfkill 子系统有两个参数,rfkill.default_state 和 rfkill.master_switch_mode,它们在 admin-guide/kernel-parameters.rst 中有文档说明。

实现细节

rfkill 子系统由三个主要组件组成

  • rfkill 核心,

  • 已弃用的 rfkill-input 模块(输入层处理程序,正被用户空间策略代码取代)和

  • rfkill 驱动程序。

rfkill 核心为内核驱动程序提供 API,以向内核注册其无线电发射器,提供打开和关闭发射器的方法,并让系统了解设备上可能实现的硬件禁用状态。

rfkill 核心代码还会通知用户空间状态更改,并提供用户空间查询当前状态的方法。请参阅下面的“用户空间支持”部分。

当设备被硬阻止时(通过调用 rfkill_set_hw_state() 或从 query_hw_block 获取),将调用 set_block() 进行额外的软件阻止,但驱动程序可以忽略该方法调用,因为它们可以使用函数 rfkill_set_hw_state() 的返回值来同步软件状态,而不是跟踪对 set_block() 的调用。事实上,驱动程序应该使用 rfkill_set_hw_state() 的返回值,除非硬件实际分别跟踪软阻止和硬阻止。

内核 API

无线电发射器的驱动程序通常会实现 rfkill 驱动程序。

如果 rfkill 按钮仅仅是一个按钮,则平台驱动程序可能会实现输入设备。如果该按钮影响硬件,则需要改为实现 rfkill 驱动程序。如果平台提供打开/关闭发射器的方式,则也适用。

对于某些平台,硬件状态可能会在挂起/休眠期间发生变化,在这种情况下,需要在恢复时使用当前状态更新 rfkill 核心。

要创建 rfkill 驱动程序,驱动程序的 Kconfig 需要具有

depends on RFKILL || !RFKILL

以确保当 rfkill 是模块化时,驱动程序不能被内置。!RFKILL 的情况允许在未配置 rfkill 时构建驱动程序,在这种情况下,仍然可以使用所有 rfkill API,但将由静态内联提供,这些内联编译为几乎什么都没有。

当发生状态更改时,从控制可以被硬阻止的设备的 rfkill 驱动程序中调用 rfkill_set_hw_state() 是必需的,除非它们还分配了 poll_hw_block() 回调(然后 rfkill 核心将轮询设备)。除非您无法以任何其他方式获取事件,否则请勿执行此操作。

rfkill 提供每个开关的 LED 触发器,可用于根据开关状态驱动 LED(阻止时为 LED_FULL,否则为 LED_OFF)。

用户空间支持

建议使用的用户空间接口是 /dev/rfkill,这是一个杂项字符设备,允许用户空间获取和设置 rfkill 设备和设备集的状态。它还会通知用户空间有关设备添加和删除的信息。该 API 是一个简单的读/写 API,在 linux/rfkill.h 中定义,其中一个 ioctl 允许在过渡期间关闭内核中已弃用的输入处理程序。

除了一个 ioctl 之外,与内核的通信是通过读取和写入“struct rfkill_event”的实例来完成的。在此结构中,软阻止和硬阻止被正确地分离(与 sysfs 不同,请参见下文),并且用户空间能够获得系统中所有 rfkill 设备的一致快照。此外,可以将所有 rfkill 驱动程序(或指定类型的所有驱动程序)切换到一种状态,该状态还会更新热插拔设备的默认状态。

应用程序打开 /dev/rfkill 后,它可以读取所有设备的当前状态。可以通过轮询描述符来获取热插拔或状态更改事件,或者通过侦听 rfkill 核心框架发出的 uevent 来获取更改。

此外,每个 rfkill 设备都会在 sysfs 中注册并发出 uevent。

rfkill 设备会发出 uevent(操作为“change”),并设置以下环境变量

RFKILL_NAME
RFKILL_STATE
RFKILL_TYPE

这些变量的内容对应于上面解释的“name”、“state”和“type”sysfs 文件。

有关更多详细信息,请查阅 Documentation/ABI/stable/sysfs-class-rfkill。