Kernel-Modules

編譯沒有 Module.symvers 的 Linux 核心模組

  • August 23, 2019

我有這個嵌入式 Linux 設備。我想向它添加核心級功能,但非常希望不編譯我自己的核心來這樣做。(如果核心沒有載入並進入使用者空間,設備就會變磚;我無法訪問引導載入程序來恢復它。目前的核心沒有 kexec 支持,所以我不能用它來測試核心映像我自己的。)

設備的核心支持模組,但我沒有相應的 Module.symvers 文件的副本。

我的問題:如果我沒有 Linux 核心的 Module.symvers 文件,但確實有核心映像和為其編譯的模組,我是否可以編譯更多可以插入該核心的模組,也許是通過生成缺少的模組。 symvers 文件?

該設備執行 Linux 核心版本 3.10。

核心映像(在其 uImage 容器中) : https

://www.olio.watch/olio-firmware-1.10.220/olio-firmware/uImage配置(由於 CONFIG_IKCONFIG 從上圖中提取):https://www.olio .watch/3.10.0-g2ae2f33-config

我擁有的一個與該核心匹配的核心模組:https ://www.olio.watch/olio-firmware-1.10.220/olio-firmware/drv2605.ko

首先,為了回答您的問題“我可以在沒有 Module.symvers 的情況下編譯 Linux 核心模組嗎”,我們需要了解以下內容的目的是什麼Module.symvers

Module.symvers有兩個主要目的:

  1. 它列出了從 vmlinux 和所有模組導出的所有符號。

CONFIG_MODVERSIONS2) 如果啟用,它會列出 CRC 。如果不CONFIG_MODVERSIONS啟用,CRC 將讀取 0x00000000。

Module.symvers將在核心建構期間生成,它包含從核心和編譯模組導出的所有符號。對於每個符號,還儲存相應的 CRC 值。Module.symvers 文件的語法是:

   <CRC>       <Symbol>           <module>

例如:

   0x2d036834  scsi_remove_host   drivers/scsi/scsi_mod

話雖如此,如果我們有Module.symvers那麼我們可以建構任何模組,因為它包含所有必要的符號。

如果Module.symvers 不可用,我們仍然可以通過建構此文件或從另一個模組借用它來建構外部模組。

通常,在建構外部模組時,建構系統需要訪問核心中的符號以檢查是否定義了所有外部符號。這是在一個名為MODPOST. Module.symvers此步驟通過從核心原始碼樹中讀取來獲取符號。

如果Module.symvers正在建構外部模組的目錄中存在文件,則該文件也將被讀取。在該MODPOST步驟中,Module.symvers將寫入一個新文件,其中包含所有未在核心中定義的導出符號。

如果 Module.symvers文件不存在,則外部模組可能正在使用從另一個外部模組導出的符號,kbuild需要完全了解所有符號以避免吐出有關未定義符號的警告。

對於這種情況,有三種解決方案:

  1. 使用頂級kbuild文件:如果您有兩個模組,foo.ko並且bar.ko需要foo.ko來自 的符號bar.ko,您可以使用一個通用的頂級kbuild文件,以便在同一個建構中編譯兩個模組。考慮以下目錄佈局:
   ./foo/ <= contains foo.ko
   ./bar/ <= contains bar.ko

   The top-level kbuild file would then look like:

   #./Kbuild (or ./Makefile):
       obj-y := foo/ bar/

   And executing

       $ make -C $KDIR M=$PWD

   will then do the expected and compile both modules with
   full knowledge of symbols from either module.
  1. 使用額外Module.symvers文件:當建構外部模組時,Module.symvers會生成一個文件,其中包含所有未在核心中定義的導出符號。要從 中訪問符號bar.ko,請將 Module.symvers 文件從 bar.ko 的編譯中復製到建構 foo.ko 的目錄中。在模組建構期間,kbuild將讀取Module.symvers外部模組目錄中的文件,當建構完成時,將Module.symvers創建一個新文件,其中包含所有已定義符號的總和,而不是核心的一部分。

3)使用“make”變數KBUILD_EXTRA_SYMBOLS:如果從另一個模組複製不切實際,您可以在建構文件中Module.symvers分配一個以空格分隔的文件列表。KBUILD_EXTRA_SYMBOLS這些文件將modpost在其符號表初始化期間載入。

更多詳情1

引用自:https://unix.stackexchange.com/questions/473749