根據 Android 8.0 所引進的模組核心需求條件。 晶片系統 (SoC) 核心必須支援可載入的核心模組。
核心設定選項
為了支援可載入的核心模組 所有常見核心中的 android-base.config 包含 下列核心設定選項 (或核心版本對等項目):
CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y
所有裝置核心都必須啟用這些選項。核心模組也應 都支援卸載及重新載入功能
模組簽署
GKI 供應商模組不支援模組簽署。使用的裝置必須符合下列條件:
支援驗證開機程序,Android 要求核心模組必須位於分區
已啟用 dm-verity 的服務如此一來
提供真實性的模組
Android 13 導入了 GKI 模組的概念。GKI 模組使用核心的建構時間
簽署基礎架構,以在執行階段中區分 GKI 和其他模組。
未簽署的模組只要只使用許可清單上的符號,就可以載入
或由其他未簽署的模組提供
如要協助使用核心的建構時間金鑰組在 GKI 建構期間簽署 GKI 模組,
GKI 核心設定已啟用 CONFIG_MODULE_SIG_ALL=y
。
為避免在裝置核心建構期間簽署非 GKI 模組,您必須將
將 # CONFIG_MODULE_SIG_ALL is not set
做為核心設定的一部分
片段。
檔案位置
雖然 Android 7.x 以下版本並未強制要求核心模組 (且
支援 insmod
和 rmmod
)、Android 8.x 和
則更適合在生態系統中使用核心模組。下列
表格列出
Android 啟動模式。
啟動模式 | 儲存空間 | 螢幕 | 撥號鍵盤 | 電池 | PMIC | 觸控螢幕 | NFC、Wi-Fi、 藍牙 |
感應器 | 相機 |
---|---|---|---|---|---|---|---|---|---|
搶球 | |||||||||
充電器 | |||||||||
Android |
除了 Android 啟動模式的可用性外,核心模組也可能 依擁有者 (SoC 供應商或 ODM) 加以分類。如果核心模組 而對於其在檔案系統中的刊登位置規定, 如下:
- 所有核心應內建啟動和掛接支援功能 多個分區
- 核心模組必須從唯讀分區載入。
- 如果裝置需要驗證開機程序,核心模組應 從已驗證的分區載入。
- 核心模組不得位於
/system
。 - 從下列來源載入裝置所需的 GKI 模組:
/system/lib/modules
是以下項目的符號連結:/system_dlkm/lib/modules
。 - 提供完整 Android 或最終 Android 版本所需的 SoC 供應商核心模組
充電器模式應位於
/vendor/lib/modules
。 - 如果有 ODM 分區,則所需的 ODM 核心模組
如要查看完整 Android 或充電器模式,位於
/odm/lib/modules
。否則,這些模組應位於/vendor/lib/modules
。 - 復原所需的 SoC 供應商和 ODM 的核心模組
模式的應該位於復原
ramfs
。/lib/modules
。 - 復原模式和完整 Android 都需要核心模組,或是
充電模式
rootfs
和/vendor
或/odm
分區 (如 )。 - 復原模式中使用的核心模組不應依附於模組
僅位於
/vendor
或/odm
,因為這些分區不是 於復原模式下掛接。 - SoC 供應商核心模組不應依附於 ODM 核心模組。
在 Android 7.x 以下版本中,/vendor
和 /odm
分區不會提前掛接。在 Android 8.x 以上版本中
以便從這些分區載入模組,
及早為
非 A/B 和 A/B 裝置。這也
確保分區在 Android 和充電器模式下均已掛接。
Android 建構系統支援
在 BoardConfig.mk
中,Android 版本定義了
提供完整清單的 BOARD_VENDOR_KERNEL_MODULES
變數
決定要用於供應商映像檔的核心模組。
這個變數已複製到位於 /lib/modules/
的供應商映像檔中。
在 Android 中掛接後,會顯示於
/vendor/lib/modules
(根據上述規定)。
供應商核心模組的設定範例:
vendor_lkm_dir := device/$(vendor)/lkm-4.x BOARD_VENDOR_KERNEL_MODULES := \ $(vendor_lkm_dir)/vendor_module_a.ko \ $(vendor_lkm_dir)/vendor_module_b.ko \ $(vendor_lkm_dir)/vendor_module_c.ko
在這個範例中,廠商核心模組預先建構的存放區會對應至 上述位置的 Android 版本。
復原映像檔可能包含供應商模組的子集。Android
會定義 BOARD_RECOVERY_KERNEL_MODULES
的
在這些模組中範例如下:
vendor_lkm_dir := device/$(vendor)/lkm-4.x BOARD_RECOVERY_KERNEL_MODULES := \ $(vendor_lkm_dir)/vendor_module_a.ko \ $(vendor_lkm_dir)/vendor_module_b.ko
Android 版本會負責執行 depmod
,以便產生
「/vendor/lib/modules
」中需要 modules.dep
個檔案
和 /lib/modules
(recovery ramfs
)。
模組載入和版本管理
透過叫用,從 init.rc*
的一個傳遞中載入所有核心模組
modprobe -a
。這可避免重複初始化的負擔
modprobe
二進位檔的 C 執行階段環境。
early-init
事件可修改為叫用 modprobe
:
on early-init exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \ /vendor/lib/modules module_a module_b module_c ...
通常,核心模組必須使用模組
搭配使用 (否則核心會拒絕載入模組)。
CONFIG_MODVERSIONS
可偵測故障情形,提供解決方法
應用程式二進位檔介面 (ABI) 中執行。此功能會計算
針對事件中各匯出符號的原型,使用備援檢查 (CRC) 值
並將值儲存為核心的一部分;代表
則這些值也會儲存在核心模組中。當
系統會在載入模組後比較各個模組使用的符號值
與核心中的原始碼相對應如果值相符,系統就會載入模組;
否則載入失敗
如要啟用與廠商映像檔分開更新核心映像檔的功能,
啟用CONFIG_MODVERSIONS
。這麼一來,即可對容器進行小幅更新
核心 (例如 LTS 的錯誤修正) 而要維持相容性
與供應商映像檔中現有的核心模組搭配使用。不過
CONFIG_MODVERSIONS
不會自行修正 ABI 中斷的問題。如果
核心變更中匯出符號的原型,可能的原因包括
或是核心設定有所變更,因此這會導致
破壞與使用該符號的核心模組的相容性。此時
就必須重新編譯核心模組。
例如,核心中的 task_struct
結構 (定義於
include/linux/sched.h
) 包含許多欄位 (有條件)
所具備的叢集會因核心設定而異sched_info
只有在 CONFIG_SCHED_INFO
啟用時 (
會發生在CONFIG_SCHEDSTATS
或
CONFIG_TASK_DELAY_ACCT
已啟用)。如果這些設定
選項變更狀態,task_struct
結構的版面配置
以及從使用
task_struct
經過修改 (例如
位於「kernel/sched/core.c
」的「set_cpus_allowed_ptr
」)。
與先前編譯的核心模組的相容性
介面無法運作,必須使用新核心重新建構這些模組
此外還會從 0 自動調整資源配置
您完全不必調整資源調度設定
如要進一步瞭解 CONFIG_MODVERSIONS
,請參閱
說明文件,位於
Documentation/kbuild/modules.rst
。