Kconfig 描述建置 Linux 核心設定時所做的選擇。核心開發者編輯 Kconfig 檔案來定義符號與其關係;使用者透過 make menuconfig、make nconfig、make xconfig 等前端,或 olddefconfig 等非互動目標選取值。
產生的 .config 是 Kbuild 的輸入,而不是完整的建置指令碼。設定同步會產生由 Make 與 C 消費的檔案,包括 include/config/auto.conf 與 include/generated/autoconf.h。
從根檔案到單一設定 #
解析從頂層 Kconfig 開始。它的 source 陳述式會包含子系統檔案,而架構選擇會引入 arch/$(SRCARCH)/Kconfig。其他包含形式為:
rsource,其路徑相對於包含檔案;osource,忽略遺失的檔案;orsource,結合相對與選用行為。
mainmenu 設定前端標題。menu/endmenu、if/endif、choice/endchoice、comment、config 與 menuconfig 建立項目結構。
同一符號可以在多個包含檔案中定義。Kconfig 會組合符號的屬性,不會建立架構本機變數。定義必須使用一致型別,依賴子句會累積,而預設值順序仍然重要。因此,共用檔案可以宣告不可見功能,而架構定義會選取它。
# lib/Kconfig
config HAVE_FAST_CHECKSUM
bool
config FAST_CHECKSUM
bool "Use the generic fast checksum implementation"
depends on HAVE_FAST_CHECKSUM
# arch/example/Kconfig
config EXAMPLE
bool
select HAVE_FAST_CHECKSUMHAVE_* 符號表達實作能力。接著,使用者可見功能依賴該能力,避免使用 select 繞過功能的實際相依性。
巨集與前處理器層 #
Kconfig 會在選單項目語言處理一行之前執行文字展開。其變數語法類似 Make:
immediate := $(ARCH)
deferred = $(ARCH)
message = architecture $(1), compiler $(2)
$(info,configuring $(immediate))
label := $(message,$(ARCH),$(CC))
:=會立即展開右側。=儲存遞迴展開的值。+=依變數現有的展開風格附加內容。$(name)展開變數。$(name,arg1,arg2)展開參數化變數,其中$(1)、$(2)等是位置引數。
與 Make 不同,參數化 Kconfig 變數會直接呼叫;沒有 $(call ...)。逗號分隔函式引數。內建函式包括 shell、info、warning-if、error-if、filename 與 lineno。核心透過 Kconfig 函式機制加入編譯器選項探測等函式。
巨集展開是文字性的,因此引號與空白對接收結果的語言仍然重要。使用前處理來處理小型重複運算式與功能探測,而不是產生大型、難以稽核的選單片段。
符號、型別與提示 #
config NAME 定義名為 NAME 的符號;.config 與 C 將它暴露為 CONFIG_NAME。menuconfig 定義相同種類的符號,但會告訴相容前端該項目預期包含子選單。
可用的符號型別有五種:
| 型別 | .config 中的範例 | 產生的 C 形式 |
|---|---|---|
bool | CONFIG_FOO=y 或 # CONFIG_FOO is not set | #define CONFIG_FOO 1 或不存在 |
tristate | CONFIG_FOO=y、CONFIG_FOO=m 或未設定 | CONFIG_FOO、CONFIG_FOO_MODULE 或兩者皆無 |
string | CONFIG_FOO="value" | 加引號的字串巨集 |
int | CONFIG_FOO=42 | 整數巨集 |
hex | CONFIG_FOO=0x2a | 十六進位整數巨集 |
bool "Enable foo" 與 tristate "Build foo" 將型別與 prompt 結合。沒有可見提示的符號無法在設定前端編輯,但預設值、select 或其他運算式仍可為它提供值。
config FOO
tristate "Foo transport"
depends on NET
default m if MODULES
help
Build support for the Foo transport.def_bool EXPR 與 def_tristate EXPR 是型別加上 default EXPR 的縮寫。當選用條件為真時,range MIN MAX 會限制 int 或 hex 符號。
Tristate 運算式 #
邏輯 Kconfig 運算式使用有序值 n = 0、m = 1 與 y = 2。因此:
A && B是兩個值的最小值;A || B是最大值;!A是2 - A。
比較會產生 tristate 結果。括號控制分組,而加引號的常值表示字串值。bool 不能保留 m;模組相關運算式會依符號型別與是否啟用模組而折疊。
直接相依性會施加上限:
config USB_WIDGET
tristate "USB widget"
depends on USB && HAS_IOMEM若 USB=m,USB_WIDGET 不能成為 y。提示上的選用條件會影響提示是否可見,而符號的直接相依性無論前端如何呈現都會限制其值。
預設值、反向相依性與可見性 #
屬性解決不同問題:
default VALUE if CONDITION只在使用者尚未設定時提供值。若多個預設值可見,第一個可見預設值勝出。預設值不會覆寫現有.config中保留的值。depends on EXPR限制符號最大值與提示可見性。select TARGET if CONDITION建立反向相依性,並將TARGET提升到至少選取運算式的值。它不會遵守TARGET自己的直接相依性,因此只應選取前置條件已確定滿足的簡單不可見符號。imply TARGET if CONDITION是弱反向相依性。它提供仍可被可見使用者選擇降低的下限,而目標的直接相依性仍會限制結果。visible if EXPR限制menu區塊的可見性,但不改變其中符號的值。
例如:
config DRIVER_FOO
tristate "Foo device"
depends on PCI
select CRC32
imply FW_LOADERCRC32 應該是沒有未滿足相依性的內部輔助工具。FW_LOADER 只是受到鼓勵,因為驅動程式沒有它也能運作。加入 select 來修復相依性循環是不正確的,因為 Kconfig 會拒絕遞迴相依性,且不使用 SAT solver 推導偏好解。
選單位置不是相依性圖 #
來源順序與明確容器決定大部分顯示位置:
menu "Network drivers"
visible if NET
config NET_VENDOR_EXAMPLE
bool "Example devices"
if NET_VENDOR_EXAMPLE
source "drivers/net/ethernet/example/Kconfig"
endif
endmenu當後續項目強烈依賴前一項,使子項目只有在父項目可見時才能可見,前端也會推導隱含子選單。語言文件描述精確的提示相依規則。
除此之外,相依性不會重新定位項目。符號可以依賴顯示於不同區段的另一個符號,而 select 不會使目標出現在選取器下方。因此,選單配置傳達導覽,而相依性運算式傳達有效值。將前者視為後者的渲染結果,會產生令人困惑的 Kconfig 檔案。
產生的設定構件 #
前端寫入 .config 後,Kbuild 會同步產生的輸入。重要表示如下:
.config
include/config/auto.conf
include/generated/autoconf.h.config 是持久且面向使用者的指派檔案。auto.conf 將指派呈現給 Make,讓規則可以使用以下運算式:
obj-$(CONFIG_USB_WIDGET) += usb-widget.o
autoconf.h 將啟用的符號呈現給 C 前處理。核心 C 程式碼應包含一般核心標頭,而不是直接包含 autoconf.h。IS_ENABLED(CONFIG_FOO) 等輔助工具能處理內建與模組形式,而不必自行撰寫每種前處理組合。
設定更新可以加入較新樹引入的符號。make oldconfig 會詢問新的選擇,而 make olddefconfig 接受它們的預設值。make savedefconfig 會相對於預設值寫入最小 defconfig;它不能與封存完整 .config 互換。
評論
在 GitHub 上閱讀或評論(發表評論需要登入)