4.1 上章分析出的參數
4.1.1 變量
- MAKECMDGOALS = xxx_defconfig
- KBUILD_EXTMOD =
- version_h := include/generated/version_autogenerated.h
- timestamp_h := include/generated/timestamp_autogenerated.h
- no-dot-config-targets := clean clobber mrproper distclean help %docs check% coccicheck ubootversion backup tests
- config-targets := 1
- mixed-targets := 0
- dot-config := 1
- KBUILD_SRC =
- build := -f ./scripts/Makefile.build obj
4.1.2 環境變量
- KBUILD_DEFCONFIG := sandbox_defconfig
- KBUILD_KCONFIG =
4.1.3 需要進行分析的地方
(1)scripts_basic 目標執行的命令
make -f ./scripts/Makefile.build obj=scripts/basic
(2)%config 目標執行的命令
make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
由以上分析可以知道,執行 make xxx_defconfig 需要執行 Makefile.build 腳本,第一次傳入的參數為 scripts/basic,第二次傳入的參數為 scripts/kconfig xxx_defconfig
4.2 Makefile.build 腳本分析
4.2.1 make -f ./scripts/Makefile.build obj=scripts/basic
make -f scripts/Makefile.build obj=scripts/basic 命令由於沒有指定目標,所以會在 script/Makefile.build 中處理默認目標__build:
114~119 行
1 # We keep a list of all modules in $(MODVERDIR) 2 3 __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \ 4 $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \ 5 $(subdir-ym) $(always) 6 @:
同時,在scripts/Makefile.build 中會包含進 scripts/basic 目錄下的 Kbuild/Makefile,所以該make命令的實際效果是去編譯出 scripts/basic 目錄下的三個 host program,也就是 fixdep docproc和hash。
56 到 59 行 包含
1 # The filename Kbuild has precedence over Makefile 2 kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) 3 kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) 4 include $(kbuild-file)
什么是host program?一般認為是和內核無關,但是要在編譯過程中使用的工具程序。關於這些程序的編譯,參考 scripts/Makefile.host 文件,以及 Documentation/kbuild/makefile.txt 文件中關於 host program 的這一節。
scripts/basic 文件中的 Makefile
1 hostprogs-y := fixdep 2 always := $(hostprogs-y) 3 4 # fixdep is needed to compile other host programs 5 $(addprefix $(obj)/,$(filter-out fixdep,$(always))): $(obj)/fixdep
4.2.2 make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
文件 scripts/Makefile.build 會包含obj變量所指代目錄內的 Makefile的,在這里就是 script/kconfig/Makefile。
所以這里得查看這個文件:120~125行
1 %_defconfig: $(obj)/conf 2 $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) 3 4 # Added for U-Boot (backward compatibility) 5 %_config: %_defconfig 6 @:
在這里,xxx_defconfig 需要依賴於同目錄下的conf程序。這其實就是 Linux 內核進行Kconfig操作的主程序之一了,類似的還有mconf,qconf和gconf等。他們其實都是 host program。關於它們是如何被編譯出來的,還請參見 scripts/kconfig/Makefile 文件,主要是借助於bison,flex和gperf三個工具來生成c源程序文件,之后再編譯出來的。這部分和我們Linux內核的構建主題關系不大.
看一下 kconfig 的定義,變量的賦值在 scripts\kconfig'Makefile 中
1 ifdef KBUILD_KCONFIG 2 Kconfig := $(KBUILD_KCONFIG) 3 else 4 Kconfig := Kconfig 5 endif
由於變量 KBUILD_KCONFIG 在arm架構Makefile中沒有被定義,所以 Kconfig 被定義成 arch/arm/kconfig,所以這個目標的規則就簡化成:
1 /* silent 是確定是否執行靜態編譯 */ 2 ifeq ($(quiet),silent_) 3 silent := -s 4 endif 5 6 $(obj)/conf -s --defconfig=arch/arm/configs/xxx_defconfig arch/arm/Kconfig
這個命令就是讀取並解析以 arch/arm/Kconfig 為首的內核功能選項配置文件,並將文件 arch/arm/configs/s3c2410_defconfig 所設置的默認值分配給對應的所有選項,最終生成隱藏配置文件 .config。
在 uboot 或內核開始真正編譯之前,構建系統會以 .config 文件為藍本生成 include/config/auto.conf 文件,這個文件的格式和 .config類似,這個文件會在頂層 以及 scripts/Makefile.build 文件中被直接包含進來,所以這些變量其實就成了 GNU Make 的變量。而uboot 或 內核各子目錄中的 Kbuild/Makefile 就可以使用這些變量的定義,來決定是否將該目錄下對應的代碼功能直接編譯到內核里面(這些變量取值為"y")、編譯成模塊(取值為"m")或者干脆不進行編譯(取值為"空")。可以想見,如果選擇不編譯,那出來的Linux內核就不會有對應的功能。
在 arch/arm/Kconfig 文件中,我們可以查看到添加一塊開發板需要大致更改的地方:
- arch/arm/cpu 目錄
- board/ 目錄
在配置的時候,配置工具首先會解析架構平台目錄下的 Kconfig,這就是所謂和平台相關的主Kconfig。主Kconfig文件會包含其他目錄的Kcofnig文件,而其他目錄的Kconfig又會包含其他各子目錄的 Kconfig。如此形成一個樹型結構。
4.3 小結
作為uboot 或 內核構建系統對 kconfig 的支持,到這步就算是結束了,其根本目標是產生 .config 隱藏文件,用以記錄我們所需要的配置結果。但是在uboot或Linux內核里面,僅僅把配置結果保存在像 .config 這樣一個文件中是不夠的。在后面的配置中,依然會用到