Linux

知道我的 linux 核心自啟動以來載入了哪些韌體

  • August 15, 2021

在例行更新我的 Debian 系統時,我從來沒有花時間選擇我真正需要的韌體包。基本上我都安裝了它們,並且總是最新的。

我一直想知道如何才能選擇我真正需要的那些。我正在考慮使用我係統中的所有設備(即使是我很少使用的設備,如藍牙、乙太網、相機、觸摸板、多媒體鍵等),並查看載入的韌體列表。

有沒有一種簡單的方法可以找出目前載入的韌體,或者自上次核心啟動以來載入的韌體?

如果您的核心是使用動態調試支持 (CONFIG_DYNAMIC_DEBUG) 建構的,則可以使用引導參數來啟用韌體載入程序的調試消息。它應該擷取所有韌體載入,除非特定驅動程序做了一些奇怪的事情並且由於某種原因不使用核心的韌體載入 API。

將以下內容添加到您的引導參數中:

對於核心 2.6 - 4.16:dyndbg="file drivers/base/firmware_class.c +fmp"

對於核心 4.17 及更高版本:dyndbg="file drivers/base/firmware_loader/main.c +fmp"

(作為參考,意思是“對於核心源文件file blah/foo.c +fmp中的所有調試呼叫,啟用動態調試列印,並使消息顯示文件****名和模組名稱”。有關更多詳細資訊,請參閱核心文件。) blah/foo.c

啟動後,執行dmesg | grep firmware_class. 特別感興趣的是帶有 的行firmware_class:fw_get_filesystem_firmware,它應該夾在對 和 的呼叫__allocate_fw_priv之間__free_fw_priv

在您重新啟動或禁用動態調試之前,將記錄所有韌體載入。


背景資料:

您不能查詢“目前載入的”韌體,因為韌體不一定保留在系統記憶體中。它通常被上傳到系統外部某些設備中的某個晶片上。驅動程序通常將韌體文件載入到核心緩衝區中,使用該緩衝區對設備進行程式,然後丟棄緩衝區而不保留文件的任何記錄。並且標準核心韌體 API 預設不保留日誌。一些驅動程序確實將其韌體載入記錄到核心日誌中,但它不是通用的。

我的第一個想法是“進入”核心和負責抓取韌體文件的任何使用者空間程序,以便我可以添加一些調試消息。但事實證明這並不總是可能的:核心本身能夠直接從文件系統獲取韌體,不涉及使用者空間機制。(事實上,核心更喜歡在可能的情況下直接從 /lib/firmware/ 直接載入。)

我的下一個想法是使用 kprobe 或其他一些跟踪系統來跟踪韌體載入中涉及的核心函式呼叫。但事實證明我不必走那麼遠:韌體載入器方便地包含一些調試消息——一旦啟用——足以查看所有正在載入的文件。以上dyndbg利用了這些。


其他資訊:

核心的韌體載入 API 通常通過呼叫 request_firmware() 或 request_firmware_nowait() 來訪問。驅動程序使用它想要的韌體文件的名稱呼叫這些函式之一,核心嘗試使用以下過程載入它:

  • 檢查核心映像中的韌體,如果找到則從那裡載入。

  • 檢查文件系統上的韌體,如果找到則從那裡載入。

  • $$ If kernel is configured for it $$使用 sysfs “fallback”: create /sys/firmware/<xxx>/loading,等待某些程序向其寫入韌體。

    • $$ If kernel is configured for it $$創建一個 uevent 來通知 udev 或正在收聽的任何人“如果您可以寫入此文件,那就太好了”。
    • 如果時間過長(特別是 /sys/firmware/timeout 中的時間長度),請放棄錯誤。

引用自:https://serverfault.com/questions/1026598