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 檔案。
有關更多詳細資訊,請參閱 ABI file stable/sysfs-class-rfkill。