內核/Arch 構建系統

出自 Arch Linux 中文维基

參閱內核

利用 Arch 編譯系統,可以基於官方的 linux 包編譯自定義內核。這種編譯方法可以自動化整個過程,並且是基於一個已經經過詳細測試過的內核包。你可以編輯 PKGBUILD 來使用一個自定義內核配置或者添加附加的補丁。

獲取所需內容[編輯 | 編輯原始碼]

因為要使用到 makepkg, 請先了解 makepkg 的使用方法和最佳實踐建議。例如不要用 root/sudo 運行 makepkg.

首先建立一個編譯目錄 build

$ mkdir ~/build/
$ cd ~/build/

安裝軟件包 devtoolsbase-devel包組.

首先需要一個原始內核作為自定義的基礎,從Git獲取PKGBUILD等文件,放到編譯目錄:

$ pkgctl repo clone --protocol=https linux

此時,目錄樹應該看起來像這樣:

~/build/linux/-+
               +--config
               \__PKGBUILD

然後從相應的來源獲取其他需要的文件 (例如自定義配置文件、補丁等)。

修改 PKGBUILD[編輯 | 編輯原始碼]

編輯 PKGBUILD,找到 pkgbase 修改為自定義軟件包的名稱:

PKGBUILD
pkgbase=linux-custom
警吿: 切勿linux添加到provides數組中,因為你的定製內核和為原linux包編譯的內核模塊不兼容,不滿足provides所需的依賴關係。同樣,也不要把linux-headers添加到頭文件包的provides數組。

避免創建文檔[編輯 | 編輯原始碼]

編譯內核的冗長過程中,很大一部分時間被用於編譯文檔。2022年8月25日之後,可以應用以下補丁到PKGBUILD中,來避免生成文檔:

63c63
<   make htmldocs all
---
>   make all
195c195
< pkgname=("$pkgbase" "$pkgbase-headers" "$pkgbase-docs")
---
> pkgname=("$pkgbase" "$pkgbase-headers")

這一補丁刪除了#63行,更改了#195行。如果補丁沒法直接應用,那就需要手動進行修改。

修改 prepare()[編輯 | 編輯原始碼]

可以在prepare()打上需要的補丁,或修改內核配置文件。

若要修改配置選項,可以直接編輯源文件。

亦可改用 GUI 工具調整編譯選項。從 PKGBUILD 的 prepare() 函數中取消註釋make olddefconfig,然後添加你所需的工具:

PKGBUILD
...
  msg2 "Setting config..."
  cp ../config .config
  #make olddefconfig

  make nconfig     # new CLI menu for configuration
  #make menuconfig # CLI menu for configuration
  #make xconfig    # X-based configuration
  #make oldconfig  # using old config from previous kernel version
  # ... or manually edit .config
  make prepare
...
警吿: systemd對內核配置有一些要求,無論是一般使用、特定使用條件(比如UEFI)還是某個功能(比如bootchart),不滿足這些要求可能導致不穩定或者性能下降。systemd推薦的配置列表可在/usr/share/doc/systemd/README中查看。在編譯前應先行檢查是否已經滿足要求。另外,隨着其版本更迭,這些要求可能會改變,arch不會對這些改變進行公吿。為了確保你的定製內核滿足systemd的要求,在更新systemd之前應檢視其發行註記。

生成新校驗和[編輯 | 編輯原始碼]

#修改 prepare()步驟意味着你已經修改了$_srcname/.config文件。需要生成新的校驗和(需安裝pacman-contrib):

$ updpkgsums

編譯[編輯 | 編輯原始碼]

現在可以用makepkg命令編譯內核了,如果配置時選擇了交互編譯(例如 menuconfig),編譯時需要進行配置。

 $ makepkg -s

選項 -s 會在編譯時下載需要的依賴關係,比如 xml 和 docs.

注意:
  • 編譯時間可能長達數小時,取決於你的硬件性能。並行編譯可以在多核系統上顯著減少編譯時間。
  • 可以用time makepkg來知道這次生成在你的系統上佔用了多長時間。

安裝[編輯 | 編輯原始碼]

編譯完成後,build/linux文件夾中應有兩個包,分別是內核和內核的頭文件。命名類似:

linux-custom-5.8.12-x86_64.pkg.tar.zst
linux-custom-headers-5.8.12-x86_64.pkg.tar.zst

最好同時安裝這兩個包,因為他們可能相互依賴(比如DKMS):

# pacman -U linux-custom-5.8.12-x86_64.pkg.tar.zst linux-custom-headers-5.8.12-x86_64.pkg.tar.zst

(需要執行的命令是你實際的包名)

引導加載程序[編輯 | 編輯原始碼]

如果你的定製內核和默認內核共存(修改pkgbase),為了開機時能夠引導你的內核,安裝完成後需更新引導加載程序的配置文件,為新的內核和initramfs映像添加新的引導菜單項。

如果使用grub,可以執行以下命令自動生成新的配置文件(假設配置文件是/boot/grub/grub.cfg):

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

更新[編輯 | 編輯原始碼]

假設已有arch內核的源碼,要對其進行更新,一種方法是使用https://github.com/archlinux/linux。本節以下內容假設內核源碼樹根目錄位於~/build/linux/

一般而言,放置內核源碼需要使用兩個本地git倉庫,一個本地裸git倉庫位於archlinux-linux,指向 https://github.com/archlinux/linux.git。另一個拉取自裸倉庫,位於src/archlinux-linux/。本地的補丁、構建很可能位於src/archlinux-linux/

在本例中,本地位於archlinux-linux/的裸倉庫的HEAD指向

$ cd ~/build/linux/archlinux-linux/
$ git log --oneline --max-count 1 HEAD
4010b622f1d2 Merge branch 'dax-fix-5.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm

可以看到,這個HEAD的指向位於 v5.2.5-arch1 和 v5.2.6-arch1 之間的某個版本。

$ git fetch --verbose

執行後可以看到它獲取了v5.2.7-arch(編寫wiki時最新的archlinux版本)。若沒有獲取到新的版本,則説明已是最新。

此時可把源碼更新到進行編譯的位置。

$ cd ~/build/linux/src/archlinux-linux/
$ git checkout master
$ git pull
$ git fetch --tags --verbose
$ git branch --verbose 5.2.7-arch1 v5.2.7-arch1
$ git checkout 5.2.7-arch1

可進行檢查

$ git log --oneline 5.2.7-arch1 --max-count=7
13193bfc03d4 Arch Linux kernel v5.2.7-arch1
9475c6772d05 netfilter: nf_tabf676926c7f60les: fix module autoload for redir
498d650048f6 iwlwifi: Add support for SAR South Korea limitation
bb7293abdbc7 iwlwifi: mvm: disable TX-AMSDU on older NICs
f676926c7f60 ZEN: Add CONFIG for unprivileged_userns_clone
5e4e503f4f28 add sysctl to disallow unprivileged CLONE_NEWUSER by default
5697a9d3d55f Linux 5.2.7

上述信息顯示了一些在Arch Linux kernel v5.2.7-arch1 and Linux 5.2.7之間的archlinux補丁。

使用下列命令拉取最新的PKGBUILD和內核配置文件:

$ cd ~/build/linux/
$ git pull

然後應將~/build/linux/linux/*合併~/build/linux/中。合併可以手動完成,也可以使用合併工具。參照#修改 prepare()一節進行所需的修改。

此時應可成功執行makepkg --verifysource

然後可進行#編譯,確保執行makepkg時添加--noextract選項。它應該能成功構建,因為原始碼是makepkg --nobuild解壓出的。編譯完成後,可進行#安裝

清理[編輯 | 編輯原始碼]

合併之後可以刪除~/build/linux/linux/。另外,隨着更新,~/build/linux/src/archlinux會積累很多分支(形如5.2.7-arch1)。這些可以使用下列命令清理掉:

$ cd ~/build/linux/src/archlinux
$ git branch --delete --force --verbose 5.2.7-arch1

參閱[編輯 | 編輯原始碼]