貢獻 Linux Kernel 前,需先弄懂 Kbuild (Kernel build),Kbuild 中三個重要元素: makefile , kconfig 與 .config > 用餐廳做比喻。[譬喻來源](https://www.cnblogs.com/standardzero/p/12551179.html) Kconfig: 核心提供的配置菜單 .config: 你點的菜。此記錄你在選單中選的配置,核心會依據此配置做編譯 Makefile:是菜的做法,說明編譯的方法 ### 編譯流程大致如下: 1. 撰寫或修改 .config (可用 `make menuconfig` 幫助設定,以下說明)。 2. 使用 make 開始編譯核心。 Kbuild 會根據 Makefile 與 .config 的設定,決定要編譯哪些檔案、以什麼方式編譯。 ### Kconfig 而 Kconfig 扮演的角色是,說明各個 CONFIG 的說明,會說明各 CONFIG 的說明,還有不同 CONFIG 的相依關係。 詳細內容看 [Kconfig 的 document](https://docs.kernel.org/kbuild/kconfig-language.html#kconfig-syntax) ## 編譯 以下是一些可能會用到的命令 - `make clean` 只是清除先前編譯的可執行檔及設定檔 - `make distclean`要清除所有產生的檔案,連 .config 都會不見,因此需要以下命令 `make ARCH=x86_64 defconfig`: 使用預設 x86_64 的 default config 當你使用 virtme-ng (基於 qemu 的模擬環境,能編譯 kernel source code 並執行) - `vng -b` : 產生最小 config 並 build kernel - `vng --build -s`: 採用當前 config 編譯不重新產生 config ## Kbuild Makefile > 參考 > 1. https://lwn.net/Articles/21835/ > 2. [Linux Kernel Makefiles](https://www.kernel.org/doc/html/v5.6/kbuild/makefiles.html) Kbuild 是 Linux Kernel 提供的編譯機制,加強 Makefile 的功能,讓使用者能簡單修改 Makefile 就能完成編譯核心或是編譯 Module。 貢獻要做編譯時,就需要去看在你修改的程式碼同層或上幾層會有 Makefile,以下說明 Makefile 的語法: ### y: 直接編譯進核心 `obj-y += xxx.o` 表示由 xxx.c 或 xxx.s 編譯得到 xxx.o 被直接編進核心 ### m: 模块編譯 `obj-m +=xxx.o` 表示 `xxx` 為模塊編譯,即執行`make modules` 時才會被編譯 ### 條件編譯 核心只要知道 y 與 m 就能知道以哪種方式得知你的程式碼,然後核心 Makefile 沒寫這麼簡單,會寫成 CONFIG_XX。 例如: ```c obj-$(CONFIG_FOO) += foo.o ``` 因此在 .config 會看到如下 `CONFIG_FOO=y` 表 foo.o 會編譯進核心內 `CONFIG_FOO=m` foo 當作 kernel module 被開啟 那我想要將 foo.o 編譯進核心,那麼就要使 CONFIG_FOO 成為 y。 最暴力的方式是到 linux 根目錄修改手動修改 .config。 然而,最保險的方式是為先找到在同個資料夾內或是在上一層的資料夾中 Kconfig 確定 CONFIG 內容,接著用 `make menuconfig`,開啟一個圖形化設定介面,設定值從去改變 .config 的內容,這樣避免有 dependency 沒有考慮到。 而此具體步驟是,`make menuconfig` 後進到介面後按 `/` 能做搜尋 `FOO`,系統會告訴你找到該 CONFIG 的路徑,那就逐步找到 CONFIG 後選擇按 `y` 並 `save` 接著 `exit`。都設好後,那你在 .config 及能看到該 CONFIG_FOO=y 具體來看,我修改了 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c 在同個資料夾下看到 rtw89/Makefile 能看到 ```Makefile obj-$(CONFIG_RTW89_8852B) += rtw89_8852b.o rtw89_8852b-objs := rtw8852b.o \ rtw8852b_table.o \ rtw8852b_rfk.o \ rtw8852b_rfk_table.o ``` 表示如果 `CONFIG_RTW89_8852BT` = y 或 m,就會編譯並連結 `rtw89_8852bt.o`,而rtw89_8852bt.o 是由 rtw8852bt.o, rtw8852bt_rfk.o, rtw8852bt_rfk_table.o 等各自編譯後再組合而成。 再去看同資料夾下的 rtw89/Kconfig ``` menuconfig RTW89 tristate "Realtek 802.11ax wireless chips support" depends on MAC80211 help if RTW89 config RTW89_8852BT tristate ``` 這裡的 menuconfig 是一種 Kconfig keyword,它的作用是定義一個 config 選項(這裡是 RTW89),就像 config RTW89 一樣,當 RTW89 如果被選為 y 或 m,會顯示出它下面內縮的子選項 因此當 `make menuconfig` 時: 你會看到一個大項目:`[*] Realtek 802.11ax wireless chips support` 當你把它選成 Y 或 M,下面會展開子選項 比如 `[*] Support Realtek 8852BT chipset` 如果你沒選 RTW89,那 RTW89_8852BT 也不會出現
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up