Compiling

配置、編譯和安裝自定義 Linux 核心

  • April 30, 2019

我想嘗試使用我的發行版提供的核心以外的核心——要麼來自其他地方,要麼由我定制。這是困難還是危險?

我從哪裡開始?

建構自定義核心可能很耗時——主要是在配置中,因為現代電腦可以在幾分鐘內完成建構——但如果你保留目前的工作核心並確保離開它,這並不是特別危險作為通過引導載入程序的一個選項(參見下面的步驟#6)。這樣,如果您的新設備不起作用,您可以重新啟動舊設備。

在以下說明中,原始碼樹中的路徑採用 形式[src]/whatever,即[src]您將原始碼安裝到的目錄,例如/usr/src/linux-3.13.3. 您可能想要做這些事情su root,因為源樹在寫權限方面應該保持安全(它應該由 root 擁有)。

雖然其中一些步驟是可選的,但您還是應該閱讀它們,因為它們包含理解其餘過程所必需的資訊。

  1. 下載並解壓源壓縮包。

這些可從kernel.org獲得。最新版本在首頁上列出,但如果您查看/pub/目錄內部,您會發現一個存檔一直追溯到 1.0 版。除非您有特殊原因,否則最好選擇“最新穩定”。在撰寫本文時,這是一個 74 MB 的tar.xz文件。

下載 tarball 後,您需要將其解壓縮到某個地方。正常的地方是在/usr/src。將文件放在那裡,然後:

tar -xJf linux-X.X.X.tar.xz

請注意,個別發行版通常建議您使用他們的源包之一,而不是原版樹。 這包含發行版特定的更新檔,這可能對你來說很重要,也可能無關緊要。它還將匹配用於編譯某些使用者空間工具的核心包含標頭檔,儘管它們很可能是相同的。

在 15 多年建構自定義核心(主要在 Fedora/Debian/Ubuntu 上)的過程中,我從未遇到過使用 vanilla 1原始碼的問題。然而,這樣做並沒有太大的區別,除瞭如果你想要絕對最新的核心,你的發行版可能還沒有打包它。 所以最安全的方法仍然是使用發行包,它應該安裝到/usr/src. 我更喜歡最新的馬厩,這樣我就可以在它推出發行版之前充當豚鼠 :) 2. 從基本配置開始$$ optional $$.

您不必這樣做——您可以直接潛入並從頭開始創建配置。但是,如果您以前從未這樣做過,請期待大量的試驗和錯誤。這也意味著必須通讀大多數選項(有數百個)。更好的選擇是使用您現有的配置(如果可用)。如果您使用發行版源包,它可能已經包含一個[src]/.config文件,因此您可以使用它。否則,檢查一個/proc/config.gz. 這是 2.6 核心中添加的可選功能。如果存在,請將其複製到原始碼樹的頂層,然後gunzip -c config.gz > .config.

如果它不存在,可能是因為此選項被配置為模組。嘗試sudo modprobe configs,然後再次檢查/proc目錄config.gz

發行版配置不是很理想,因為它包含幾乎所有可能的硬體驅動程序。這對核心的功能無關緊要,因為它們是模組,其中大多數永遠不會被使用,但它大大增加了建構所需的時間。這也很尷尬,因為它需要一個 initramfs 來包含某些核心模組(參見下面的步驟 #4)。但是,它可能是比預設設置更好的起點。

請注意,配置選項會從一個核心版本轉換和更改為下一個核心版本,當您執行以下make config程序之一時,您.config將首先被解析和更新以匹配新版本。如果配置來自一個非常舊的版本,這可能會導致奇怪的結果,所以在配置時要注意。AFAIK 它根本無法正常工作(使用較新版本的配置)。

  1. 創建一個.config持續時間。

[src]/.config是用於配置核心的文本文件。 不要直接編輯這個文件。更改選項通常不是將 a 替換為 等的簡單Y問題N;通常有一組相互依賴和分支的可能性。相反,您想使用核心 makefile 中的配置目標之一(意思是,make _____從頂級源目錄在命令行輸入):

  • make config是最基本的,但可能不符合大多數人的口味。這是一連串的問題——很多問題——如果你改變主意,你就必須重新開始。
  • make oldconfig就像make config除了,如果你已經有一個.config來自以前的版本,將跳過問題,除了那些與新選項有關的問題。仍然可能有很多,其中大多數與你無關,所以我不推薦它。
  • make menuconfig是我(我認為大多數其他人的)首選方法。它建構並執行一個 TUI 界面(將在終端上工作的彩色菜單)。這需要您-dev安裝 ncurses 軟體包。/除了可以通過;訪問的 seach 之外,它是相當不言自明的。F1“幫助”提供了對目前選項的解釋。還有一個替代版本,make nconfig具有一些額外的功能,其中 F2“syminfo”相當於 menuconfig 的 F1。
  • make xconfig是一個完整的 GUI 界面。這需要安裝 Qtqmake-dev軟體包,同樣,它是一個編譯和建構的程序。如果您以前沒有使用過這些,則可能需要大量下載。我更喜歡menuconfigGUI 版本的原因是選項層次結構在前者中使用連續螢幕呈現,而在後者中則像手風琴一樣開放。您應該(但不必)做的第一件事是添加一個“本地版本”字元串(在General Setup下)。其原因在下面的#5 中提到。

“迷宮”是描述選項層次結構的好方法,深入了解它遠遠超出了像這樣的問答的範圍。如果您想坐下來經歷所有事情,請留出幾個小時。Greg Kroah-Hartman(Linux 核心的長期領導開發者)有一本關於核心的免費線上書籍(參見下面的參考資料),其中包含關於配置的一章,儘管它是在 2006 年編寫的。我的建議是從一個合理的基礎開始從您目前的發行版核心(根據#2),然後通過它並取消選中所有您知道不需要的東西。您可能還想將一些“模組”選項更改為“內置”,這將我們帶到我的下一點…… 4. 關於initramfs $$ optional $$

“initramfs”是內置在核心中和/或在引導時載入的壓縮文件系統。/lib/modules它的主要目的是包含核心在訪問根文件系統上的模組之前需要的模組——例如,包含該文件系統的設備的驅動程序。發行版總是部分使用這些驅動程序,因為驅動程序相互不兼容,因此不能全部內置到核心中。而是從initramfs.

這很好用,並不代表任何缺點,但在建構自己的核心時可能是不必要的複雜性。2 問題是,如果您不使用 initramfs,則需要確保根文件系統(及其所在設備)的驅動程序已內置到核心中。 在中,這是(= 模組)選項和(= 內置)選項menuconfig之間的區別。如果您沒有做到這一點,系統將在啟動過程的早期出現故障。因此,例如,如果你有一個 SATA 硬碟和一個 ext4 根文件系統,你需要那些內置的驅動程序。M``*

$$ If anyone can think of anything else that’s a must-have, leave a comment and I’ll incorporate that here $$. 如果您確實想使用initramfs,則必須在General Setup中選擇適當的選項。有一個框架指南可以在 中創建一個內置到核心[src]/Documentation/filesystems/ramfs-rootfs-initramfs.txt,但請注意發行版不這樣做;他們使用外部 gzip 壓縮的 cpio 文件。但是,該文件確實包含對應該包含的內容的討論initramfs(請參閱“initramfs 的內容”)。 5. 建構並安裝核心。

下一步很容易。要製作核心,只需make[src]目錄中執行即可。如果您在多核系統上,您可以添加-j N以加快速度,N您想要專用的核心數量 + 1。沒有testor check。完成後,您可以make modules. 在一個快速的盒子上,所有這些都應該花費不到 10 分鐘。

如果一切順利,make INSTALL_MOD_STRIP=1 modules_install. 這將創建一個/lib/modules與核心版本號相匹配的目錄以及步驟 3 中提到的“本地版本”字元串(如果有)。如果您沒有使用“本地版本”字元串,如果您已經擁有與您所依賴的相同版本的核心,請小心,因為這些模組將替換那些模組。3 INSTALL_MOD_STRIP=1是可選的,意義見這裡

然後,您可以make install將核心安裝到預設位置。不過,我的建議是自己做,以確保不會覆蓋現有文件。查找[src]/arch/[ARCH]/boot一個名為bzImage4的文件,[ARCH]如果x86您在 x86 或 x86-64 機器上(如果您在其他機器上,則在哪裡)。將其複制/boot並重命名為更具體和資訊更豐富的內容(沒關係)。對 做同樣的事情[src]/System.map,但根據以下方案重命名它:

System.map-[VERSION]

此處,與[VERSION]創建的目錄名稱完全相同**,其中將包含“本地版本”字元串,例如./lib/modules``make modules_installSystem.map-3.13.3-mykernel 6. 配置 GRUB 2 引導載入程序。

如果您不使用grub(大多數 linux 桌面使用者都在使用),這顯然不適用於您。你應該有一個/etc/grub.d/40_custom文件不多。如果不是,則創建它由 root 擁有並且chmod 755(它必須是可執行的)。對此添加:

menuentry 'My new kernel, or whatever' {
   set root='hd0,1'
   linux /boot/[name-of-kernel] root=/dev/sda1 [other kernel options]
}

如果您使用的是 initramfs,您還應該有最後一行initrd /path/to/initramfs。小心set root=線路。該範例假定 grub 安裝在第一個硬碟驅動器 (hd0,1) 的第一個分區上。如果您有多個驅動器,您可能希望使用分區 UUID 並將該行替換為:

   search --no-floppy --fs-uuid --set=root [the UUID of the partition]

除非 grub 不在您的根文件系統上,否則這也應該與root=該行上的指令相對應,該指令linux指示您的根文件系統(帶有/sbin/init和的那個/lib/modules)。它的 UUID 版本是root=UUID=[the UUID].

您可以查看現有/boot/grub2/grub.cfg的設備名稱以獲取有關設備名稱的線索。這是grub 2 下的簡要指南。一旦你滿意,執行grub2-mkconfig -o /boot/grub2/grub.cfg(但首先備份你目前的grub.cfg)。然後,您可能想要編輯該文件並將您的條目移到頂部。它仍應包含舊(正在執行的)核心的列表,並且您的發行版可能具有自動複製新核心條目的機制(因為它是在/boot; Fedora 中找到的,因此,使用帶有menuentryis a的不同標題好主意)。如果一切順利,您可以稍後將其刪除。

您也可以直接將其menuentry插入grub.cfg,但某些發行版會在其核心更新時覆蓋它(而 using/etc/grub.d/將保持它的合併)。

就是這樣。您現在需要做的就是重新啟動。如果它不起作用,請嘗試從螢幕輸出中推斷問題,重新啟動選擇舊核心,然後返回第 3 步(除了使用.config您已經擁有的並對其進行調整)。在嘗試之間進行make clean(或)可能是個好主意,但請確保**先複製到某個備份,因為這將被刪除。 這有助於確保建構過程中使用的對像不會過時。make mrproper[src]/.config 7. 關於核心標頭檔等。人。

您可能應該做的一件事是符號連結 ( ln -s -i)/lib/modules/X.X.X/source和源樹所在/lib/modules/X.X.X/build的目錄(保留它)。/usr/src這是必要的,以便某些使用者空間工具(和第三方驅動程序安裝程序)可以訪問正在執行的核心的原始碼。

與此相關的一個問題是 等中的.h文件/usr/include。這些變化非常緩慢,並且向後兼容。你有兩個選擇:

  • 保留發行版使用的那些。如果您定期更新整個系統,發行版無論如何都會定期安裝新系統,因此這是“最省事”的選項。
  • 使用make headers_install.由於它們是向後兼容的(意味著“使用舊核心標頭檔針對 C 庫建構的程序應該在新核心上執行”),因此您不必對此過於挑剔。唯一的潛在問題是,如果您建構自定義核心並保留一段時間,在此期間,發行版會將“kernel-headers”包更新到比建構核心時*更新的版本**,*結果發現有一些不兼容(僅適用於隨後從原始碼編譯的軟體)。

參考

以下是一些資源:

  • [src]/README包括建構和安裝的簡要指南。
  • [src]/Documentation目錄包含許多可能有助於配置的資訊。
  • Greg KH 的《Linux Kernel in a Nutshell 》一書(以 PDF 格式免費提供)的大部分內容都圍繞建構核心展開。
  • Grub 2 有一個線上手冊

  1. “Vanilla”是指可在 kernel.org 找到的原始、純粹的官方來源。大多數發行版都採用這個原版源並添加一些小的自定義。

  2. 請注意,有些情況需要 initramfs,因為需要一些使用者空間才能掛載根文件系統——例如,如果它是加密的,或者分佈在復雜的 RAID 陣列中。

  3. 如果您沒有建構它們,它不會刪除已經存在的模組,但是,這意味著您可以稍後通過簡單地修改配置並make modules_install再次執行來添加模組。請注意,建構某些模組可能需要更改核心本身,在這種情況下,您還必須更換核心。modprobe當您嘗試使用插入模組時,您將能夠分辨出來。

  4. 如果您使用非標準壓縮選項,此文件的名稱可能會有所不同。我不確定所有的可能性是什麼。

引用自:https://unix.stackexchange.com/questions/115620