探索Linux內(nèi)核Kconfig / kbuild的秘密

      網(wǎng)友投稿 849 2022-05-30

      探索linux內(nèi)核:Kconfig / kbuild的秘密

      文章目錄

      探索Linux內(nèi)核:Kconfig / kbuild的秘密

      深入了解Linux配置/構(gòu)建系統(tǒng)的工作原理

      Kconfig

      kbuild的

      了解vmlinux與bzImage

      依賴性跟蹤

      展望未來

      深入了解Linux配置/構(gòu)建系統(tǒng)的工作原理

      自從Linux內(nèi)核代碼遷移到Git以來,Linux內(nèi)核配置/構(gòu)建系統(tǒng)(也稱為Kconfig / kbuild)已存在很長(zhǎng)時(shí)間了。然而,作為支持基礎(chǔ)設(shè)施,它很少成為人們關(guān)注的焦點(diǎn); 甚至在日常工作中使用它的內(nèi)核開發(fā)人員也從未真正考慮過它。

      為了探索如何編譯Linux內(nèi)核,本文將深入介紹Kconfig / kbuild內(nèi)部進(jìn)程,解釋如何生成.config文件和vmlinux / bzImage文件,并介紹依賴性跟蹤的智能技巧。

      Kconfig

      構(gòu)建內(nèi)核的第一步始終是配置。Kconfig有助于使Linux內(nèi)核高度模塊化和可定制。Kconfig為用戶提供了許多配置目標(biāo):

      我認(rèn)為menuconfig是這些目標(biāo)中最受歡迎的。目標(biāo)由不同的主程序處理,這些程序由內(nèi)核提供并在內(nèi)核構(gòu)建期間構(gòu)建。一些目標(biāo)有一個(gè)GUI(為了方便用戶),而大多數(shù)沒有。與Kconfig相關(guān)的工具和源代碼主要位于內(nèi)核源代碼中的scripts / kconfig /下。從scripts / kconfig / Makefile可以看出,有幾個(gè)主機(jī)程序,包括conf,mconf和nconf。除了conf之外,它們中的每一個(gè)都負(fù)責(zé)基于GUI的配置目標(biāo)之一,因此,conf處理其中的大多數(shù)。

      從邏輯上講,Kconfig的基礎(chǔ)結(jié)構(gòu)有兩部分:一部分實(shí)現(xiàn)一種新語言來定義配置項(xiàng)(參見內(nèi)核源代碼下的Kconfig文件),另一部分解析Kconfig語言并處理配置操作。

      大多數(shù)配置目標(biāo)具有大致相同的內(nèi)部過程(如下所示):

      請(qǐng)注意,所有配置項(xiàng)都具有默認(rèn)值。

      第一步讀取源根目錄下的Kconfig文件,構(gòu)建初始配置數(shù)據(jù)庫(kù); 然后它根據(jù)此優(yōu)先級(jí)讀取現(xiàn)有配置文件來更新初始數(shù)據(jù)庫(kù):

      .config

      / lib / modules / $(shell,uname -r)/ .config /

      etc / kernel-config

      / boot / config - $(shell,uname -r)

      ARCH_DEFCONFIG

      arch / $(ARCH)/ defconfig

      如果您通過menuconfig進(jìn)行基于GUI的配置或通過oldconfig進(jìn)行基于命令行的配置,則會(huì)根據(jù)您的自定義更新數(shù)據(jù)庫(kù)。最后,配置數(shù)據(jù)庫(kù)被轉(zhuǎn)儲(chǔ)到.config文件中。

      但.config文件不是內(nèi)核構(gòu)建的最終素材; 這就是syncconfig目標(biāo)存在的原因。syncconfig曾經(jīng)是一個(gè)名為silentoldconfig的配置目標(biāo),但它不會(huì)執(zhí)行舊名稱所說的內(nèi)容,因此它已重命名。此外,因?yàn)樗枪﹥?nèi)部使用(不適用于用戶),所以它已從列表中刪除。

      以下是syncconfig的作用:

      syncconfig將.config作為輸入并輸出許多其他文件,這些文件分為三類:

      auto.conf和tristate.conf

      用于makefile文本處理。例如,您可以在組件的makefile中看到這樣的語句:

      obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o

      1

      autoconf.h用于C語言源文件。

      **include / config /**下的空頭文件用于kbuild期間的配置依賴性跟蹤,如下所述。

      配置完成后,我們將知道哪些文件和代碼片段未編譯。

      kbuild的

      組件式構(gòu)建(稱為遞歸make)是GNU make管理大型項(xiàng)目的常用方法。Kbuild是遞歸make的一個(gè)很好的例子。通過將源文件劃分為不同的模塊/組件,每個(gè)組件都由其自己的makefile管理。當(dāng)您開始構(gòu)建時(shí),頂級(jí)makefile以正確的順序調(diào)用每個(gè)組件的makefile,構(gòu)建組件,并將它們收集到最終的執(zhí)行程序中。

      Kbuild指的是不同類型的makefile:

      探索Linux內(nèi)核:Kconfig / kbuild的秘密

      Makefile是源根目錄中的頂級(jí)makefile。

      .config是內(nèi)核配置文件。

      arch / $(ARCH)/ Makefile是arch makefile,它是top makefile的補(bǔ)充。

      **scripts / Makefile。***描述了所有kbuild makefile的通用規(guī)則。

      最后,大約有500個(gè)kbuild makefile。

      top makefile包含arch makefile,讀取.config文件,下載到子目錄,在scripts / Makefile。*中定義的例程的幫助下,在每個(gè)組件的makefile上調(diào)用make,構(gòu)建每個(gè)中間對(duì)象,并將所有中間對(duì)象鏈接到vmlinux中。內(nèi)核文檔Documentation / kbuild / makefiles.txt描述了這些makefile的所有方面。

      作為一個(gè)例子,讓我們看看如何在x86-64上生成vmlinux:

      進(jìn)入vmlinux的所有**.o文件首先進(jìn)入他們自己的內(nèi)置.a**,通過變量 KBUILD_VMLINUX_INIT,KBUILD_VMLINUX_MAIN,KBUILD_VMLINUX_LIBS指示,然后收集到vmlinux文件中。

      在簡(jiǎn)化的makefile代碼的幫助下,了解如何在Linux內(nèi)核中實(shí)現(xiàn)遞歸make:

      # In top Makefile vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) +$(call if_changed,link-vmlinux) # Variable assignments vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN) $(KBUILD_VMLINUX_LIBS) export KBUILD_VMLINUX_INIT := $(head-y) $(init-y) export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y2) $(drivers-y) $(net-y) $(virt-y) export KBUILD_VMLINUX_LIBS := $(libs-y1) export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds init-y := init/ drivers-y := drivers/ sound/ firmware/ net-y := net/ libs-y := lib/ core-y := usr/ virt-y := virt/ # Transform to corresponding built-in.a init-y := $(patsubst %/, %/built-in.a, $(init-y)) core-y := $(patsubst %/, %/built-in.a, $(core-y)) drivers-y := $(patsubst %/, %/built-in.a, $(drivers-y)) net-y := $(patsubst %/, %/built-in.a, $(net-y)) libs-y1 := $(patsubst %/, %/lib.a, $(libs-y)) libs-y2 := $(patsubst %/, %/built-in.a, $(filter-out %.a, $(libs-y))) virt-y := $(patsubst %/, %/built-in.a, $(virt-y)) # Setup the dependency. vmlinux-deps are all intermediate objects, vmlinux-dirs # are phony targets, so every time comes to this rule, the recipe of vmlinux-dirs # will be executed. Refer "4.6 Phony Targets" of `info make` $(sort $(vmlinux-deps)): $(vmlinux-dirs) ; # Variable vmlinux-dirs is the directory part of each built-in.a vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ $(net-y) $(net-m) $(libs-y) $(libs-m) $(virt-y))) # The entry of recursive make $(vmlinux-dirs): $(Q)$(MAKE) $(build)=$@ need-builtin=1

      1

      遞歸制作配方已擴(kuò)展,例如:

      make -f scripts/Makefile.build obj=init need-builtin=1

      1

      這意味著make將進(jìn)入scripts / Makefile.build繼續(xù)構(gòu)建每個(gè)內(nèi)置的工作.a。在scripts / link-vmlinux.sh的幫助下,vmlinux文件最終位于源根目錄下。

      了解vmlinux與bzImage

      許多Linux內(nèi)核開發(fā)人員可能不清楚vmlinux和bzImage之間的關(guān)系。例如,這是他們?cè)趚86-64中的關(guān)系:

      源根vmlinux被剝離,壓縮,放入piggy.S,然后與其他對(duì)等對(duì)象鏈接到arch / x86 / boot / compressed / vmlinux。同時(shí),在arch / x86 / boot下生成一個(gè)名為setup.bin的文件。可能有一個(gè)可選的第三個(gè)文件具有重定位信息,具體取決于CONFIG_X86_NEED_RELOCS的配置 。

      由內(nèi)核提供的稱為build的宿主程序?qū)⑦@兩個(gè)(或三個(gè))部分構(gòu)建到最終的bzImage文件中。

      依賴性跟蹤

      Kbuild跟蹤三種依賴關(guān)系:

      所有必備文件(* .c和* .h)

      所有必備文件中使用的**CONFIG_**選項(xiàng)

      用于編譯目標(biāo)的命令行依賴項(xiàng)

      第一個(gè)很容易理解,但第二個(gè)和第三個(gè)呢??jī)?nèi)核開發(fā)人員經(jīng)常會(huì)看到如下代碼:

      #ifdef CONFIG_SMP __boot_cpu_id = cpu; #endif

      1

      當(dāng)CONFIG_SMP更改時(shí),應(yīng)重新編譯這段代碼。編譯源文件的命令行也很重要,因?yàn)椴煌拿钚锌赡軙?huì)導(dǎo)致不同的目標(biāo)文件。

      當(dāng)**.c文件通過#include**指令使用頭文件時(shí),您需要編寫如下規(guī)則:

      main.o: defs.h recipe...

      1

      管理大型項(xiàng)目時(shí),需要大量的這些規(guī)則; 把它們?nèi)繉懴聛頃?huì)很乏味和乏味。幸運(yùn)的是,大多數(shù)現(xiàn)代C編譯器都可以通過查看源文件中的**#include行來為您編寫這些規(guī)則。對(duì)于GNU編譯器集合(GCC),只需添加命令行參數(shù):-MD depfile**

      # In scripts/Makefile.lib c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ -include $(srctree)/include/linux/compiler_types.h \ $(__c_flags) $(modkern_cflags) \ $(basename_flags) $(modname_flags)

      1

      這將生成一個(gè)**.d**文件,內(nèi)容如下:

      init_task.o: init/init_task.c include/linux/kconfig.h \ include/generated/autoconf.h include/linux/init_task.h \ include/linux/rcupdate.h include/linux/types.h \ ...

      1

      然后主機(jī)程序fixdep通過將depfile和命令行作為輸入來處理其他兩個(gè)依賴項(xiàng),然后以makefile語法輸出**。 .cmd**文件,該文件記錄命令行和所有先決條件(包括配置)為目標(biāo)。它看起來像這樣:

      # The command line used to compile the target cmd_init/init_task.o := gcc -Wp,-MD,init/.init_task.o.d -nostdinc ... ... # The dependency files deps_init/init_task.o := \ $(wildcard include/config/posix/timers.h) \ $(wildcard include/config/arch/task/struct/on/stack.h) \ $(wildcard include/config/thread/info/in/task.h) \ ... include/uapi/linux/types.h \ arch/x86/include/uapi/asm/types.h \ include/uapi/asm-generic/types.h \ ...

      1

      在遞歸make期間將包含一個(gè)**。 .cmd**文件,提供所有依賴關(guān)系信息并幫助決定是否重建目標(biāo)。

      這背后的秘密是fixdep將解析depfile(.d文件),然后解析內(nèi)部的所有依賴文件,搜索所有CONFIG_字符串的文本,將它們轉(zhuǎn)換為相應(yīng)的空頭文件,并將它們添加到目標(biāo)的先決條件。每次配置更改時(shí),相應(yīng)的空頭文件也將更新,因此kbuild可以檢測(cè)到該更改并重建依賴于它的目標(biāo)。因?yàn)檫€記錄了命令行,所以很容易比較最后和當(dāng)前的編譯參數(shù)。

      展望未來

      Kconfig / kbuild在很長(zhǎng)一段時(shí)間內(nèi)保持不變,直到新的維護(hù)者M(jìn)asahiro Yamada于2017年初加入,現(xiàn)在kbuild再次正在積極開發(fā)。如果您很快就會(huì)看到與本文中的內(nèi)容不同的內(nèi)容,請(qǐng)不要感到驚訝。

      轉(zhuǎn)自:https://opensource.com/article/18/10/kbuild-and-kconfig

      Linux 數(shù)據(jù)庫(kù)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:excel表格設(shè)置打印A4大小的方法步驟
      下一篇:怎么才能學(xué)好Java?月薪35K阿里P9程序員給出了這樣的建議!
      相關(guān)文章
      激情内射亚洲一区二区三区| 久久亚洲精品成人综合| 亚洲日韩精品射精日| 亚洲最大天堂无码精品区| 亚洲综合在线观看视频| 亚洲最大AV网站在线观看| 亚洲精品成人片在线观看| 国产精品亚洲综合网站| 国产91成人精品亚洲精品| 亚洲A∨午夜成人片精品网站| 亚洲一区二区三区乱码在线欧洲| 亚洲an日韩专区在线| 亚洲香蕉在线观看| 伊人久久亚洲综合影院首页| 亚洲精品无码日韩国产不卡av| 亚洲AV无码资源在线观看| 亚洲av无码兔费综合| 99亚洲精品卡2卡三卡4卡2卡| 亚洲丁香婷婷综合久久| 亚洲AV无码专区在线观看成人| 亚洲成AV人影片在线观看| 国产成人精品亚洲| 国产精品亚洲精品日韩动图| 亚洲va中文字幕无码| 中文字幕不卡亚洲 | 亚洲色最新高清av网站| 亚洲国产日韩精品| 亚洲精品无码人妻无码| 亚洲AV无码不卡在线观看下载| 亚洲爽爽一区二区三区| 国产精品亚洲成在人线| 亚洲情a成黄在线观看动漫尤物| 久久亚洲日韩精品一区二区三区| 亚洲视频在线观看视频| 亚洲最大成人网色香蕉| 亚洲国产精品无码观看久久| 亚洲福利精品一区二区三区| 青青草原亚洲视频| 亚洲人成在线播放网站岛国| 亚洲免费视频播放| 亚洲AV无码之国产精品|