自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux 內(nèi)核動(dòng)手編譯實(shí)用指南

系統(tǒng) Linux
一份讓你深入體驗(yàn)最新 Linux 內(nèi)核編譯過(guò)程的實(shí)操指南。

出于各種原因,自行編譯 Linux 內(nèi)核可能引起你的興趣。這些原因可能包括但不限于:

  • 測(cè)試一個(gè)比你目前的 Linux 發(fā)行版更新的內(nèi)核版本
  • 采用一組不同的配置選項(xiàng)、驅(qū)動(dòng)來(lái)構(gòu)建內(nèi)核
  • 學(xué)習(xí)者的好奇心 ??

此指南將一步步指導(dǎo)你如何親自編譯 Linux 內(nèi)核,包括你該運(yùn)行哪些命令,為什么運(yùn)行這些命令以及這些命令的執(zhí)行效果。本文篇幅較長(zhǎng),所以請(qǐng)做好準(zhǔn)備!

?? 諸如 Ubuntu 這樣的發(fā)行版提供了更簡(jiǎn)單地安裝主線 Linux 內(nèi)核的方式。但本教程目標(biāo)是從源碼手動(dòng)完成所有工作。此教程需要你付出時(shí)間、耐心以及豐富的 Linux 命令行使用經(jīng)驗(yàn)。本文更注重親身實(shí)踐的體驗(yàn)。不管怎么說(shuō),我仍建議你在虛擬機(jī)或備用系統(tǒng)中嘗試此冒險(xiǎn),而非在你的主系統(tǒng)上進(jìn)行。

前置準(zhǔn)備

在軟件領(lǐng)域,構(gòu)建任何事物都有兩個(gè)基本要求:

  1. 源代碼
  2. 構(gòu)建依賴

因此,作為預(yù)備環(huán)節(jié),我們需要下載 Linux 內(nèi)核的源碼壓縮包,并安裝一些能讓我們成功構(gòu)建 Linux 內(nèi)核的依賴項(xiàng)。

Linux 版本導(dǎo)覽

在任何時(shí)刻,Freax Linux 內(nèi)核都有四種“版本”。

Linux 的這些 “版本”,按照開(kāi)發(fā)流程的順序是:

  1. linux-next 樹(shù): 所有準(zhǔn)備合并到 Linux 代碼庫(kù)的代碼首先被合并到 linux-next 樹(shù)。它代表的是 Linux 內(nèi)核最新也是“最不穩(wěn)定”的狀態(tài)。大多數(shù) Linux 內(nèi)核開(kāi)發(fā)者和測(cè)試人員使用這個(gè)來(lái)提高代碼質(zhì)量,為 Linus Torvalds 的后續(xù)提取做準(zhǔn)備。請(qǐng)謹(jǐn)慎使用!
  2. 發(fā)布候選版(RC) / 主線版: Linus 從 linux-next 樹(shù)抽取代碼并創(chuàng)建一個(gè)初始發(fā)布版本。這個(gè)初始發(fā)布版本的測(cè)試版稱為 RC(發(fā)布候選Release Candidate)版本。一旦 RC 版本發(fā)布,Linus 只會(huì)接受對(duì)它的錯(cuò)誤修復(fù)和性能退化相關(guān)的補(bǔ)丁?;A(chǔ)這些反饋,Linus 會(huì)每周發(fā)布一個(gè) RC 內(nèi)核,直到他對(duì)代碼感到滿意。RC 發(fā)行版本的標(biāo)識(shí)是 -rc 后綴,后面跟一個(gè)數(shù)字。
  3. 穩(wěn)定版: 當(dāng) Linus 覺(jué)得最新的 RC 版本已穩(wěn)定時(shí),他會(huì)發(fā)布最終的“公開(kāi)”版本。穩(wěn)定發(fā)布版將會(huì)維護(hù)幾周時(shí)間。像 Arch Linux 和 Fedora Linux 這樣的前沿 Linux 發(fā)行版會(huì)使用此類版本。我建議你在試用 linux-next 或任何 RC 版本之前,先試一試此版本。
  4. LTS 版本: 每年最后一個(gè)穩(wěn)定版將會(huì)再維護(hù) 幾年。這通常是一個(gè)較舊的版本,但它會(huì) 會(huì)積極地維護(hù)并提供安全修復(fù)。Debian 的穩(wěn)定版本會(huì)使用 Linux 內(nèi)核的 LTS 版版本。

若想了解更多此方面的知識(shí),可參閱 官方文檔。

本文將以當(dāng)前可用的最新穩(wěn)定版為例,編寫此文時(shí)的 Linux 內(nèi)核版本是 6.5.5

系統(tǒng)準(zhǔn)備

由于 Linux 內(nèi)核使用 C 語(yǔ)言編寫,編譯 Linux 內(nèi)核至少需要一個(gè) C 編譯器。你的計(jì)算機(jī)上可能還需要其他一些依賴項(xiàng),現(xiàn)在是安裝它們的時(shí)候了。

?? 這個(gè)指南主要聚焦于使用 GNU C 編譯器(GCC)來(lái)編譯 Linux 內(nèi)核。但在未來(lái)的文章中(可能會(huì)深入介紹 Rust 的支持),我可能會(huì)介紹使用 LLVM 的 Clang 編譯器作為 GCC 的替代品。

不過(guò),請(qǐng)注意,MSVC 并不適用。盡管如此,我仍期待有微軟的員工為此發(fā)送修補(bǔ)程序集。我在瞎想啥?

對(duì)于 Arch Linux 以及其衍生版本的用戶,安裝命令如下:

sudo pacman -S base-devel bc coreutils cpio gettext initramfs kmod libelf ncurses pahole perl python rsync tar xz

對(duì)于 Debian 以及其衍生版本的用戶,安裝命令如下:

sudo apt install bc binutils bison dwarves flex gcc git gnupg2 gzip libelf-dev libncurses5-dev libssl-dev make openssl pahole perl-base rsync tar xz-utils

對(duì)于 Fedora 以及其衍生版本的用戶,安裝命令如下:

sudo dnf install binutils ncurses-devel \
    /usr/include/{libelf.h,openssl/pkcs7.h} \
    /usr/bin/{bc,bison,flex,gcc,git,gpg2,gzip,make,openssl,pahole,perl,rsync,tar,xz,zstd}

下載 Linux 內(nèi)核源碼

請(qǐng)?jiān)L問(wèn) kernel.org,在頁(yè)面中尋找第一個(gè) 穩(wěn)定Stable

點(diǎn)擊訪問(wèn) kernel.org

通過(guò)點(diǎn)擊黃色的方框,你就可以下載 Tar 文件。同時(shí),也別忘了下載相匹配的 PGP 簽名文件,稍后我們需要用到它來(lái)驗(yàn)證 Tar 文件。它的擴(kuò)展名為 .tar.sign。

校驗(yàn) Tar 文件的完整性

你如何知道剛下載的 Tar 文件是否被損壞?對(duì)于個(gè)人來(lái)說(shuō),一個(gè)損壞的 Tar 文件只會(huì)浪費(fèi)你的寶貴時(shí)間,如果你是在為一個(gè)組織工作,那么可能會(huì)危及到組織的安全(這時(shí)你可能還有更大的問(wèn)題需要擔(dān)憂,但我們并不想讓所有人都產(chǎn)生創(chuàng)傷后應(yīng)激障礙?。?/p>

為了驗(yàn)證我們的 Tar 文件的完整性,我們需要先解壓它。目前,它是使用 XZ 壓縮算法壓縮的。因此,我將使用 unxz 工具(其實(shí)就是 xz --decompress 的別名)來(lái)解壓 .tar.xz 格式的壓縮文件。

unxz --keep linux-*.tar.xz

解壓完成后,我們需要獲取 Linus Torvalds 和 Greg KH 使用的 GPG 公開(kāi)密鑰。這些密鑰用于對(duì) Tar 文件進(jìn)行簽名。

gpg2 --locate-keys torvalds@kernel.org gregkh@kernel.org

你應(yīng)該可以得到一個(gè)與我在我的電腦上看到的類似的結(jié)果:

$ gpg2 --locate-keys torvalds@kernel.org gregkh@kernel.org
gpg: /home/pratham/.gnupg/trustdb.gpg: trustdb created
gpg: key 38DBBDC86092693E: public key "Greg Kroah-Hartman <gregkh@kernel.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg: key 79BE3E4300411886: public key "Linus Torvalds <torvalds@kernel.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1
pub   rsa4096 2011-09-23 [SC]
      647F28654894E3BD457199BE38DBBDC86092693E
uid           [ unknown] Greg Kroah-Hartman <gregkh@kernel.org>
sub   rsa4096 2011-09-23 [E]
pub   rsa2048 2011-09-20 [SC]
      ABAF11C65A2970B130ABE3C479BE3E4300411886
uid           [ unknown] Linus Torvalds <torvalds@kernel.org>
sub   rsa2048 2011-09-20 [E]

在導(dǎo)入 Greg 和 Linus 的密鑰后,我們可以使用 --verify 標(biāo)志來(lái)驗(yàn)證 Tar 的完整性,操作如下:

gpg2 --verify linux-*.tar.sign

如果驗(yàn)證成功,你應(yīng)該會(huì)看到如下的輸出信息:

$ gpg2 --verify linux-*.tar.sign
gpg: assuming signed data in 'linux-6.5.5.tar'
gpg: Signature made Saturday 23 September 2023 02:46:13 PM IST
gpg:                using RSA key 647F28654894E3BD457199BE38DBBDC86092693E
gpg: Good signature from "Greg Kroah-Hartman <gregkh@kernel.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 647F 2865 4894 E3BD 4571  99BE 38DB BDC8 6092 693E

務(wù)必查看是否存在 gpg: Good signature 的提示,然后再繼續(xù)!

?? 你可以忽略以下警告:WARNING: This key is not certified with a trusted signature! There is no indication that the signature belongs to the owner.

我們已根據(jù) Linus 和 Greg 的郵件地址獲取了公開(kāi)密鑰,并無(wú)需對(duì)此警告感到擔(dān)憂。

解壓 Tar 文件

如果你順利的進(jìn)行到這里,意味著你的 Tar 文件完整性檢查已經(jīng)成功完成。接下來(lái),我們將從 Tar 文件中解壓出 Linux 內(nèi)核的源碼。

The "TAR" xkcd comic: https://xkcd.com/1168/The "TAR" xkcd comic: https://xkcd.com/1168/

The "TAR" xkcd comic: https://xkcd.com/1168/

這個(gè)步驟十分簡(jiǎn)單,只需對(duì) Tar 文件執(zhí)行 tar -xf 命令,如下:

tar -xf linux-*.tar

在這里,-x 選項(xiàng)表示解壓,-f 選項(xiàng)則用來(lái)告訴 Tar 文件的文件名。

這個(gè)解壓過(guò)程可能需要幾分鐘時(shí)間,你可以先放松,耐心等待一下。

配置 Linux 內(nèi)核

Linux 內(nèi)核的構(gòu)建過(guò)程會(huì)查找 .config 文件。顧名思義,這是一個(gè)配置文件,用于指定 Linux 內(nèi)核的所有可能的配置選項(xiàng)。這是必需的文件。

獲取 Linux 內(nèi)核的 .config 文件有兩種方式:

  1. 使用你的 Linux 發(fā)行版的配置作為基礎(chǔ)(推薦做法
  2. 使用默認(rèn)的,通用的配置

?? 也有第三種方法,也就是從零開(kāi)始,手動(dòng)配置每一個(gè)選項(xiàng),但注意,這需要配置超過(guò) 12,000 個(gè)選項(xiàng)。并不推薦這種方式,因?yàn)槭謩?dòng)配置所有選項(xiàng)將花費(fèi)大量的時(shí)間,并且你還需要理解每個(gè)啟用和禁用選項(xiàng)的含義。

使用發(fā)行版提供的配置

使用你的 Linux 發(fā)行版提供的配置是一個(gè)安全的選擇。 如果你只是跟隨這個(gè)指南測(cè)試一個(gè)不是你的發(fā)行版提供的新內(nèi)核,那么這就是推薦的方式。

你的 Linux 發(fā)行版的 Linux 內(nèi)核配置文件會(huì)在以下兩個(gè)位置之一:

  • 大多數(shù) Linux 發(fā)行版,如 Debian 和 Fedora 及其衍生版,將會(huì)把它存在 /boot/config-$(uname -r)
  • 一些 Linux 發(fā)行版,比如 Arch Linux 將它整合在了 Linux 內(nèi)核中。所以,可以在 /proc/config.gz 找到。

?? 如果兩者都有,建議使用 /proc/config.gz。這是因?yàn)樗谥蛔x文件系統(tǒng)中,所以是未被篡改的。

進(jìn)入含有已經(jīng)解壓出的 Tar 文件的目錄。

cd linux-*/

接著,復(fù)制你的 Linux 發(fā)行版的配置文件:

### Debian 和 Fedora 及其衍生版:
$ cp /boot/config-"$(uname -r)" .config
### Arch Linux 及其衍生版:
$ zcat /proc/config.gz > .config
更新配置文件

一旦完成這些步驟,接下來(lái)就需要“更新”配置文件了。因?yàn)槟愕陌l(fā)行版提供的配置很可能比你正在構(gòu)建的 Linux 內(nèi)核版本要舊。

?? 這同樣適用于像 Arch Linux 和 Fedora 這樣前沿的 Linux 發(fā)行版。 它們并不會(huì)因?yàn)橛行掳姹究捎镁土⒖贪l(fā)布更新。他們會(huì)進(jìn)行一些質(zhì)量控制工作,這必然會(huì)花費(fèi)些時(shí)間。因此,即便是你的發(fā)行版提供的最新內(nèi)核,相較于你在 kernel.org 上獲取的版本也會(huì)滯后幾個(gè)小版本。

要更新一個(gè)已有的 .config 文件,我們使用 make 命令搭配 olddefconfig 參數(shù)。簡(jiǎn)單解釋一下,這個(gè)命令的意思是使用 舊的、默認(rèn)的、配置。

這將使用“舊的配置文件”(當(dāng)前保存為 .config,這是你發(fā)行版配置的一份直接副本),并檢查從上一版本以來(lái) Linux 代碼庫(kù)中新加的任何配置選項(xiàng)。如果找到任何新的、未配置 的選項(xiàng),該選項(xiàng)的默認(rèn)配置值會(huì)被使用,并會(huì)對(duì) .config 文件進(jìn)行更新。

原來(lái)的 .config 文件將被重命名為 .config.old 進(jìn)行備份,并將新的更改寫入至 .config 文件。

make olddefconfig

以下是我機(jī)器上的輸出:

$ file .config
.config: Linux make config build file, ASCII text
$ make olddefconfig
    HOSTCC  scripts/basic/fixdep
    HOSTCC  scripts/kconfig/conf.o
    HOSTCC  scripts/kconfig/confdata.o
    HOSTCC  scripts/kconfig/expr.o
    LEX     scripts/kconfig/lexer.lex.c
    YACC    scripts/kconfig/parser.tab.[ch]
    HOSTCC  scripts/kconfig/lexer.lex.o
    HOSTCC  scripts/kconfig/menu.o
    HOSTCC  scripts/kconfig/parser.tab.o
    HOSTCC  scripts/kconfig/preprocess.o
    HOSTCC  scripts/kconfig/symbol.o
    HOSTCC  scripts/kconfig/util.o
    HOSTLD  scripts/kconfig/conf
.config:8593:warning: symbol value 'm' invalid for USB_FOTG210_HCD
.config:8859:warning: symbol value 'm' invalid for USB_FOTG210_UDC
#
# configuration written to .config
#
針對(duì) Debian 及其衍生版用戶

Debian 及其衍生版為內(nèi)核模塊使用一個(gè)簽名證書。默認(rèn)情況下,你的計(jì)算機(jī)并不包含這個(gè)證書。

我推薦關(guān)閉啟用模塊簽名的選項(xiàng)。具體如下所示:

./scripts/config --file .config --set-str SYSTEM_TRUSTED_KEYS ''
./scripts/config --file .config --set-str SYSTEM_REVOCATION_KEYS ''

如果你不這么做,在后面你進(jìn)行 Linux 內(nèi)核構(gòu)建時(shí),可能會(huì)導(dǎo)致構(gòu)建失敗。要注意這點(diǎn)。

使用自定義配置

如果你出于學(xué)習(xí)內(nèi)核開(kāi)發(fā)的目的學(xué)習(xí)如何構(gòu)建 Linux 內(nèi)核,那你應(yīng)該這樣做。

?? 請(qǐng)注意,偏離你的 Linux 發(fā)行版的配置可能無(wú)法在實(shí)體硬件上“正?!惫ぷ?。問(wèn)題可能是特定硬件無(wú)法工作、Linux 內(nèi)核無(wú)法啟動(dòng)等。

因此,我們只建議在虛擬機(jī)中使用。

你可以通過(guò)查看 make help 的輸出 來(lái)查看 所有 可用的選項(xiàng),但我們主要關(guān)注三個(gè) make 目標(biāo):

  • defconfig: 默認(rèn)配置。
  • allmodconfig: 根據(jù)當(dāng)前系統(tǒng)狀態(tài),盡可能地把項(xiàng)目構(gòu)建為可加載模塊(而非內(nèi)建)。
  • tinyconfig: 極簡(jiǎn)的 Linux 內(nèi)核。

由于 tinyconfig 目標(biāo)只會(huì)構(gòu)建少數(shù)項(xiàng)目,構(gòu)建時(shí)間將會(huì)縮短。我個(gè)人選擇它的原因主要有:

  1. 檢查我在代碼/工具鏈中做的修改是否正確,以及代碼是否可以編譯。
  2. 在虛擬機(jī)中只進(jìn)行少數(shù)選項(xiàng)的測(cè)試。

?? 在為 ARM 或 RISC-V 機(jī)器構(gòu)建 Linux 內(nèi)核時(shí),你可能需要 DTB(設(shè)備樹(shù)的二進(jìn)制文件)。使用 tinyconfig 目標(biāo)將不會(huì)啟用構(gòu)建 DTB 的選項(xiàng),你的內(nèi)核很可能無(wú)法啟動(dòng)。

當(dāng)然,你可以用 QEMU 在沒(méi)有任何 DTB 的情況下啟動(dòng) Linux 內(nèi)核。但這篇文章并不會(huì)聚焦在此?;蛟S你可以通過(guò)評(píng)論,讓我在之后的時(shí)間里覆蓋這個(gè)話題 ??

除非你確切地知道自己在做什么,否則你應(yīng)當(dāng)使用 defconfig 目標(biāo)。 以下是我在我的電腦上運(yùn)行的效果:

$ make defconfig
    HOSTCC  scripts/basic/fixdep
    HOSTCC  scripts/kconfig/conf.o
    HOSTCC  scripts/kconfig/confdata.o
    HOSTCC  scripts/kconfig/expr.o
    LEX     scripts/kconfig/lexer.lex.c
    YACC    scripts/kconfig/parser.tab.[ch]
    HOSTCC  scripts/kconfig/lexer.lex.o
    HOSTCC  scripts/kconfig/menu.o
    HOSTCC  scripts/kconfig/parser.tab.o
    HOSTCC  scripts/kconfig/preprocess.o
    HOSTCC  scripts/kconfig/symbol.o
    HOSTCC  scripts/kconfig/util.o
    HOSTLD  scripts/kconfig/conf
*** Default configuration is based on 'defconfig'
#
# configuration written to .config
#

修改配置

無(wú)論你是使用 Linux 發(fā)行版的配置并更新它,還是使用 defconfig 目標(biāo)創(chuàng)建新的 .config 文件,你都可能希望熟悉如何修改這個(gè)配置文件。最可靠的修改方式是使用 menuconfig 或 nconfig 目標(biāo)。

這兩個(gè)目標(biāo)的功能是相同的,只不過(guò)提供給你的界面有所不同。這是這兩者間唯一的區(qū)別。我個(gè)人更偏向于使用 menuconfig 目標(biāo),但近來(lái)我發(fā)現(xiàn) nconfig 在搜索選項(xiàng)時(shí)似乎更具直觀性,所以我逐漸轉(zhuǎn)向使用它。

首先,帶著 menuconfig 目標(biāo)運(yùn)行 make 命令:

$ make menuconfig
    HOSTCC  scripts/kconfig/mconf.o
    HOSTCC  scripts/kconfig/lxdialog/checklist.o
    HOSTCC  scripts/kconfig/lxdialog/inputbox.o
    HOSTCC  scripts/kconfig/lxdialog/menubox.o
    HOSTCC  scripts/kconfig/lxdialog/textbox.o
    HOSTCC  scripts/kconfig/lxdialog/util.o
    HOSTCC  scripts/kconfig/lxdialog/yesno.o
    HOSTLD  scripts/kconfig/mconf

在此界面,你可以根據(jù)各選項(xiàng)的類型來(lái)進(jìn)行切換操作。

有兩類可切換選項(xiàng):

  • 布爾狀態(tài)選項(xiàng):這類選項(xiàng)只能關(guān)閉([ ])或作為內(nèi)建組件開(kāi)啟([*])。
  • 三態(tài)選項(xiàng):這類選項(xiàng)可以關(guān)閉(< >)、內(nèi)建(<*>),或作為可加載模塊(<M>)進(jìn)行構(gòu)建。

想要了解更多關(guān)于某個(gè)選項(xiàng)的信息,使用上/下箭頭鍵導(dǎo)航至該選項(xiàng),然后按 <TAB> 鍵,直至底部的 < Help > 選項(xiàng)被選中,然后按回車鍵進(jìn)行選擇。此時(shí)就會(huì)顯示關(guān)于該配置選項(xiàng)的幫助信息。

在修改選項(xiàng)時(shí)請(qǐng)務(wù)必謹(jǐn)慎。

當(dāng)你滿意配置后,按 <TAB> 鍵直到底部的 < Save > 選項(xiàng)被選中。然后按回車鍵進(jìn)行選擇。然后再次按回車鍵(記住,此時(shí)不要更改文件名),就能將更新后的配置保存到 .config 文件中。

構(gòu)建 Linux 內(nèi)核

構(gòu)建 Linux 內(nèi)核實(shí)際上十分簡(jiǎn)單。然而,在開(kāi)始構(gòu)建之前,讓我們?yōu)樽远x內(nèi)核構(gòu)建添加一個(gè)標(biāo)簽。我將使用字符串 -pratham 作為標(biāo)簽,并利用 LOCALVERSION 變量來(lái)實(shí)施。你可以使用以下命令實(shí)現(xiàn)配置:

./scripts/config --file .config --set-str LOCALVERSION "-pratham"

這一命令將 .config 文件中的 CONFIG_LOCALVERSION 配置選項(xiàng)設(shè)為我在結(jié)尾指定的字符串,即 -pratham。當(dāng)然,你也不必非得使用我所用的名字哦 ??

LOCALVERSION 選項(xiàng)可用于設(shè)置一個(gè)“本地”版本,它會(huì)被附加到通常的 x.y.z 版本方案之后,并在你運(yùn)行 uname -r 命令時(shí)一并顯示。

由于我正在構(gòu)建的是 6.5.5 版本內(nèi)核,而 LOCALVERSION 字符串被設(shè)為 -pratham,因此,對(duì)我來(lái)說(shuō),最后的版本名將會(huì)是 6.5.5-pratham。這么做的目的是確保我所構(gòu)建的自定義內(nèi)核不會(huì)與發(fā)行版所提供的內(nèi)核產(chǎn)生沖突。

接下來(lái),我們來(lái)真正地構(gòu)建內(nèi)核??梢杂靡韵碌拿钔瓿纱瞬襟E:

make -j$(nproc) 2>&1 | tee log

這對(duì)大部分(99%)用戶來(lái)說(shuō)已經(jīng)足夠了。

其中的 -j 選項(xiàng)用于指定并行編譯任務(wù)的數(shù)量。而 nproc 命令用于返回可用處理單位(包括線程)的數(shù)量。因此,-j$(nproc) 其實(shí)意味著“使用我擁有的 CPU 線程數(shù)相同數(shù)量的并行編譯任務(wù)”。

2>&1 會(huì)將 STDOUT 和 STDIN 重定向到相同的文件描述符,并通過(guò)管道傳輸給 tee 命令,這會(huì)將輸出存儲(chǔ)在一個(gè)名為 log 的文件,并且在控制臺(tái)打印出完全相同的文本。如果你在構(gòu)建時(shí)遇到錯(cuò)誤,并希望回顧日志來(lái)檢查出了什么問(wèn)題,這將會(huì)十分有用。遇到那種情況,你只需要簡(jiǎn)單執(zhí)行 grep Error log 命令就能找到線索。

自定義 make 目標(biāo)

在 Linux 內(nèi)核的源文件夾中,make 命令有一些自定義的目標(biāo)可供執(zhí)行各種操作。這些主要作為開(kāi)發(fā)者的參考。如果你的唯一目標(biāo)是安裝一個(gè)比你當(dāng)前發(fā)行版更新的 Linux 內(nèi)核,那么你完全可以跳過(guò)這部分內(nèi)容 ??

構(gòu)建目標(biāo)

作為一名開(kāi)發(fā)者,你可能只想構(gòu)建 Linux 內(nèi)核,或者只想構(gòu)建模塊,或者只想構(gòu)建設(shè)備樹(shù)二進(jìn)制(DTB)。在這種情況下,你可以指定一個(gè)構(gòu)建目標(biāo),然后 make 命令只會(huì)構(gòu)建指定的項(xiàng)目,而不會(huì)構(gòu)建其他的。

以下是一些構(gòu)建目標(biāo):

  • vmlinux:純粹的 Linux 內(nèi)核。
  • modules:可加載模塊。
  • dtbs:設(shè)備樹(shù)二進(jìn)制文件(主要用于 ARM 和 RISC-V 架構(gòu))。
  • all:構(gòu)建所有被標(biāo)記了星號(hào) * 的項(xiàng)目(從 make help 的輸出中可以查看)。

通常情況下,你并不需要指定構(gòu)建目標(biāo),因?yàn)樗鼈兌家呀?jīng)在構(gòu)建列表中。所列出的目標(biāo)是在你只想要測(cè)試某一個(gè)構(gòu)建目標(biāo),而不是其他目標(biāo)時(shí)的情況。

依據(jù)你的 計(jì)算機(jī)架構(gòu),構(gòu)建完成的 Linux 內(nèi)核鏡像(存放在 /boot 目錄)的名稱會(huì)有所不同。

對(duì)于 x86_64,Linux 內(nèi)核的默認(rèn)鏡像名稱是 bzImage。因此,如果你只需要構(gòu)建引導(dǎo)所需的 Linux 內(nèi)核,你可以像下面這樣設(shè)定 bzImage 為目標(biāo):

### 對(duì)于 x86_64
$ make bzImage

“那么如何在我的架構(gòu)上找到用來(lái)調(diào)用 make 的目標(biāo)名稱呢?”

有兩種方法。要么你可以執(zhí)行 make help 之后查找在 Architecture specific targets 下,第一個(gè)前面帶有星號(hào) * 的選項(xiàng)。

或者,如果你希望自動(dòng)完成,你可以利用 image_name 目標(biāo)得到鏡像的完全路徑(相對(duì)路徑),選擇性地添加 -s 標(biāo)志來(lái)獲得有用的輸出。

以下是我擁有的三臺(tái)電腦的輸出,一臺(tái)是 x86_64,另一臺(tái)是 AArch64,還有一臺(tái)是 riscv :

### x86_64
$ make -s image_name
arch/x86/boot/bzImage
### AArch64
$ make -s image_name
arch/arm64/boot/Image.gz
### RISC-V
$ make -s image_name
arch/riscv/boot/Image.gz

現(xiàn)在,要只構(gòu)建 Linux 內(nèi)核鏡像,你可以這樣進(jìn)行:

make $(make -s image_name | awk -F '/' '{print $4}')
清理目標(biāo)

如果你需要清理構(gòu)建產(chǎn)生的文件,你可以用以下的目標(biāo)來(lái)實(shí)現(xiàn)你的需求:

  • clean:除了 .config 文件外,刪除幾乎所有其他內(nèi)容。
  • mrproper:執(zhí)行了 make clean 的所有操作外,還會(huì)刪除 .config 文件。
  • distclean:除了執(zhí)行 make mrproper 的所有操作外,還會(huì)清理任何補(bǔ)丁文件。

安裝

一旦成功編譯了 Linux 內(nèi)核,接下來(lái)就是啟動(dòng)安裝一些東西的時(shí)候了。“一些

?? 雖然我將告訴你不同的安裝方式,尤其是關(guān)于如何改變默認(rèn)安裝路徑的方法,但如果你不確定自己在做什么,那么我不建議你這么做! 請(qǐng)慎重考慮,如果你決定走自定義的路線,那你需要自己負(fù)責(zé)后果。默認(rèn)設(shè)置之所以存在,是因?yàn)樗鼈冇衅涮厥獾脑???

安裝內(nèi)核模塊

Linux 內(nèi)核有部分在系統(tǒng)啟動(dòng)時(shí)并非必需的。這些部分被構(gòu)建為可加載模塊,即在需要時(shí)才進(jìn)行加載和卸載。

所以,首先需要安裝這些模塊。這可以通過(guò) modules_install 目標(biāo)完成。必須使用 sudo,因?yàn)槟K會(huì)被安裝在 /lib/modules/<kernel_release>-<localversion> 這個(gè)需要 root 權(quán)限的路徑下。

這個(gè)過(guò)程不僅會(huì)安裝內(nèi)核模塊,還會(huì)對(duì)其進(jìn)行簽名,所以可能需要一些時(shí)間。好消息是你可以通過(guò)之前提到的 -j$(nproc) 選項(xiàng)來(lái)并行執(zhí)行安裝任務(wù),這樣會(huì)快一些。??

sudo make modules_install -j$(nproc)

給開(kāi)發(fā)者的提示: 你可以通過(guò)設(shè)定 INSTALL_MOD_PATH 變量來(lái)指定一個(gè)不同的路徑存放 Linux 模塊,而不用默認(rèn)的 /lib/modules/<kernel_release>-<localversion>,具體如下:

sudo make modules_install INSTALL_MOD_PATH=<path>

另一個(gè)給開(kāi)發(fā)者的提示: 你可以使用 INSTALL_MOD_STRIP 變量來(lái)決定是否需要?jiǎng)冸x模塊的調(diào)試符號(hào)。如果未設(shè)定該變量,調(diào)試符號(hào)不會(huì)被剝離。當(dāng)設(shè)為 1 時(shí),符號(hào)信息將會(huì)被使用 --strip-debug 選項(xiàng)剝離,隨后該選項(xiàng)會(huì)傳遞給 strip(或者在使用 Clang 的時(shí)候傳遞給 llvm-strip)工具。

(可選)安裝 Linux 內(nèi)核頭文件

如果你打算使用這個(gè)內(nèi)核來(lái)支持樹(shù)外模塊,比如 ZFS 或英偉達(dá) DKMS,或者打算嘗試自行編寫模塊,你可能會(huì)需要 Linux 內(nèi)核提供的頭文件。

可以通過(guò)以下方式使用 headers_install 目標(biāo)來(lái)安裝 Linux 內(nèi)核頭文件:

sudo make headers_install

應(yīng)使用 sudo 命令,因?yàn)檫@些頭文件會(huì)被安裝到 /usr 目錄。同時(shí)還會(huì)在 /usr 目錄內(nèi)創(chuàng)建子目錄 include/linux,然后將頭文件安裝到 /usr/include/linux 內(nèi)。

給開(kāi)發(fā)者的提示: 通過(guò)設(shè)定 INSTALL_HDR_PATH 變量,你可以修改 Linux 內(nèi)核頭文件的安裝路徑。

安裝 DTB(只針對(duì) ARM 和 RISC-V)

如果你使用的是 x86_64 架構(gòu),那么你可以跳過(guò)此步驟!

如果你針對(duì) ARM 或者 RISC-V 構(gòu)建了內(nèi)核,那么在運(yùn)行 make 的過(guò)程中,設(shè)備樹(shù)的二進(jìn)制文件可能已經(jīng)被編譯出來(lái)了。你可以通過(guò)在 arch/<machine_architecture>/boot/dts 目錄查找 .dtb 文件來(lái)確認(rèn)這一點(diǎn)。

這里提供了一個(gè)快速檢查的技巧:

### 對(duì)于 AArch32
$ find arch/arm/boot/dts -name "*.dtb" -type f | head -n 1 > /dev/null && echo "DTBs for ARM32 were built"
### 對(duì)于 AArch64
$ find arch/arm64/boot/dts -name "*.dtb" -type f | head -n 1 > /dev/null && echo "DTBs for ARM64 were built"
### 對(duì)于 RISC-V
$ find arch/riscv/boot/dts -name "*.dtb" -type f | head -n 1 > /dev/null && echo "DTBs for RISC-V were built"

如果你看到出現(xiàn) DTBs for <arch> were built 的消息,那么你可以開(kāi)始安裝 DTB。這可以通過(guò) dtbs_install 目標(biāo)來(lái)實(shí)現(xiàn)。

需要使用 sudo,因?yàn)樗鼈儠?huì)被安裝在 /boot/dtb-<kernel_release>-<localversion> 中,而這個(gè)目錄是由 root 所擁有的。

sudo make dtbs_install

給開(kāi)發(fā)者的提示: 就像安裝模塊一樣,你可以使用 INSTALL_DTBS_PATH 變量指定一個(gè)自定義的路徑來(lái)安裝設(shè)備樹(shù)二進(jìn)制文件。

安裝 Linux 內(nèi)核

最后,我們來(lái)安裝 Linux 內(nèi)核本身!這可以通過(guò) install 目標(biāo)來(lái)完成,就像這樣:

sudo make install

在這里必須使用 sudo,因?yàn)?Linux 內(nèi)核將被安裝在 /boot 目錄,而這個(gè)目錄不允許普通用戶寫入。

?? 一般來(lái)講,install 目標(biāo)也會(huì)更新引導(dǎo)加載程序,但是如果它沒(méi)有成功,那可能是不支持你使用的引導(dǎo)加載程序。如果你沒(méi)有使用 GRUB 作為你的引導(dǎo)加載程序,請(qǐng)一定要閱讀你引導(dǎo)加載程序的使用手冊(cè) ??

給開(kāi)發(fā)者的提示: 并不奇怪,INSTALL_PATH 變量被用來(lái)設(shè)定 Linux 內(nèi)核的安裝位置,而非默認(rèn)的 /boot 目錄。

針對(duì) Arch Linux 用戶的說(shuō)明

如果你嘗試執(zhí)行了 make install 命令,可能已經(jīng)注意到產(chǎn)生了錯(cuò)誤。錯(cuò)誤如下:

$ sudo make install
    INSTALL /boot
Cannot find LILO.

要在 Arch Linux 上實(shí)際完成 Linux 內(nèi)核的安裝,我們需要手動(dòng)復(fù)制 Linux 內(nèi)核鏡像文件。別擔(dān)心,如果你使用的是 Arch Linux,手動(dòng)操作應(yīng)該是家常便飯了。( ?° ?? ?°)

可以使用以下命令完成這個(gè)步驟:

sudo install -Dm644 "$(make -s image_name)" /boot/vmlinuz-<kernel_release>-<localversion>

因?yàn)槲揖幾g的是 6.5.5 版本的內(nèi)核,所以我將會(huì)執(zhí)行下面這條命令,你可以根據(jù)你的實(shí)際情況進(jìn)行適當(dāng)調(diào)整:

sudo install -Dm644 "$(make -s image_name)" /boot/vmlinuz-6.5.5-pratham

雖然不是必須的,但最好復(fù)制一份名為 System.map 的文件。既然你已經(jīng)在操作了,一并也復(fù)制了 .config 文件吧 ??

sudo cp -vf System.map /boot/System.map-<kernel_release>-<localversion>
sudo cp -vf .config /boot/config-<kernel_release>-<localversion>
生成初始 RAM 磁盤

當(dāng)你安裝 Arch Linux 時(shí),可能已經(jīng)了解過(guò) mkinitcpio 這個(gè)工具?,F(xiàn)在,我們將使用它來(lái)創(chuàng)建初始的 RAM 磁盤。

首先,我們需要?jiǎng)?chuàng)建一個(gè)預(yù)設(shè)文件。向 /etc/mkinitcpio.d/linux-<localversion>.preset 文件中添加以下內(nèi)容,根據(jù)實(shí)際需要來(lái)替換 <kernel_release> 和 <localversion>。

ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-<kernel_release>-<localversion>"
PRESETS=('default' 'fallback')
default_image="/boot/initramfs-<kernel_release>-<localversion>.img"
fallback_options="-S autodetect"

配置完成后,執(zhí)行下面的命令來(lái)生成初始 RAM 磁盤:

sudo mkinitcpio -p linux-<localversion>

我自己的電腦上得到的輸出如下,你的結(jié)果應(yīng)該會(huì)類似!

$ sudo mkinitcpio -p linux-pratham
==> Building image from preset: /etc/mkinitcpio.d/linux-pratham.preset: 'default'
==> Using configuration file: '/etc/mkinitcpio.conf'
    -> -k /boot/vmlinuz-6.5.5-pratham -c /etc/mkinitcpio.conf -g /boot/initramfs-6.5.5-pratham.img
==> Starting build: '6.5.5-pratham'
    -> Running build hook: [base]
    -> Running build hook: [udev]
    -> Running build hook: [autodetect]
    -> Running build hook: [modconf]
    -> Running build hook: [kms]
    -> Running build hook: [keyboard]
==> WARNING: Possibly missing firmware for module: 'xhci_pci'
    -> Running build hook: [keymap]
    -> Running build hook: [consolefont]
==> WARNING: consolefont: no font found in configuration
    -> Running build hook: [block]
    -> Running build hook: [filesystems]
    -> Running build hook: [fsck]
==> Generating module dependencies
==> Creating zstd-compressed initcpio image: '/boot/initramfs-6.5.5-pratham.img'
==> Image generation successful
==> Building image from preset: /etc/mkinitcpio.d/linux-pratham.preset: 'fallback'
==> Using configuration file: '/etc/mkinitcpio.conf'
==> WARNING: No image or UKI specified. Skipping image 'fallback'

初始 RAM 磁盤已成功生成,現(xiàn)在我們可以進(jìn)入下一步,更新引導(dǎo)加載器!

更新 GRUB

一旦所有必要的文件已成功復(fù)制到其對(duì)應(yīng)的位置,接下來(lái),我們將進(jìn)行 GRUB 的更新。

使用以下命令對(duì) GRUB 引導(dǎo)加載器進(jìn)行更新:

sudo grub-mkconfig -o /boot/grub/grub.cfg

?? 如果你使用的引導(dǎo)加載器不是 GRUB,請(qǐng)參看 Arch Wiki 中相關(guān)的引導(dǎo)加載器文檔。

注意,更新 GRUB 并不會(huì)直接使新的內(nèi)核版本設(shè)為默認(rèn)啟動(dòng)選項(xiàng)。在引導(dǎo)時(shí),請(qǐng)?jiān)趩?dòng)菜單中手動(dòng)選擇新的內(nèi)核版本。

你可以通過(guò)選擇 Advanced options for Arch Linux 菜單,并在隨后的菜單中選擇 Arch Linux, with Linux <kernel_release>-<localversion> 來(lái)啟用新版的 Linux 內(nèi)核。

重啟電腦

恭喜你!你已經(jīng)完成了獲取 Linux 內(nèi)核源代碼、進(jìn)行配置、構(gòu)建以及安裝等所有步驟。現(xiàn)在只需要通過(guò)重啟電腦并進(jìn)入新構(gòu)建和安裝的 Linux 內(nèi)核,就可以開(kāi)始享受你的努力成果了。

啟動(dòng)時(shí),請(qǐng)確保從引導(dǎo)加載器中選擇正確的 Linux 內(nèi)核版本。系統(tǒng)啟動(dòng)后,運(yùn)行 uname -r 命令來(lái)確認(rèn)你正在使用預(yù)期的 Linux 內(nèi)核。

以下是我自己的電腦輸出的內(nèi)容:

$ uname -r
6.5.5-pratham

是時(shí)候開(kāi)始慶祝了! ??

卸載操作

?? 提示:在刪除當(dāng)前正在使用的內(nèi)核版本之前,你應(yīng)該首先切換至較舊的內(nèi)核版本。

可能你的 Linux 發(fā)行版所使用的 Linux 內(nèi)核版本就是你手動(dòng)編譯的版本,或者你自行編譯了新的內(nèi)核并注意到應(yīng)卸載舊的內(nèi)核以節(jié)省空間,于是你開(kāi)始想如何才能卸載。當(dāng)然,雖然我們無(wú)法簡(jiǎn)單地運(yùn)行 make uninstall 命令,但這并不代表沒(méi)有其他的方法!

我們清楚各個(gè)文件的安裝位置,因此刪除它們相對(duì)簡(jiǎn)單。

### 刪除內(nèi)核模塊
$ rm -rf /lib/modules/<kernel_release>-<localversion>
### 刪除設(shè)備樹(shù)二進(jìn)制文件
$ rm -rf /boot/dtb-<kernel_release>-<localversion>
### 刪除 Linux 內(nèi)核本身
$ rm -vf /boot/{config,System,vmlinuz}-<kernel_release>-<localversion>

總結(jié)

這個(gè)過(guò)程不是一次簡(jiǎn)單的旅程,是吧?但是現(xiàn)在,我們終于抵達(dá)了終點(diǎn)。我們一起學(xué)習(xí)了手動(dòng)編譯 Linux 內(nèi)核的全過(guò)程,包括安裝依賴、獲取和驗(yàn)證源碼、解壓源碼、配置 Linux 內(nèi)核、構(gòu)建內(nèi)核以及安裝內(nèi)核。

如果你喜歡這個(gè)詳細(xì)的步驟指南,請(qǐng)給我留言反饋。如果在操作過(guò)程中遇到問(wèn)題,也歡迎提出,讓我知道!

責(zé)任編輯:龐桂玉 來(lái)源: Linux中國(guó)
相關(guān)推薦

2011-01-11 13:45:06

2010-03-24 10:10:21

2010-09-26 10:10:10

Linux內(nèi)核

2017-03-27 18:05:49

Linux內(nèi)核編譯與開(kāi)發(fā)

2010-03-02 16:13:56

Linux升級(jí)

2009-12-17 15:18:47

2009-10-16 09:45:41

Linux內(nèi)核操作系統(tǒng)

2011-01-04 17:00:32

Linux內(nèi)核編譯

2021-05-26 07:53:58

Linux運(yùn)維Linux系統(tǒng)

2010-02-26 10:17:15

Linux uClin

2010-04-20 10:12:05

2009-10-23 16:35:44

linux Debia

2010-02-02 13:26:53

Linux內(nèi)核

2023-05-08 08:05:42

內(nèi)核模塊Linux

2024-10-14 16:53:06

2023-07-25 15:17:38

Linux操作系統(tǒng)開(kāi)發(fā)

2009-09-07 08:58:23

VMWare編譯lin

2009-12-01 12:59:50

編譯Suse Linu

2010-05-13 09:45:26

Linux地址空間

2010-03-02 15:47:39

Linux內(nèi)核系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)