內核/Arch 構建系統
參閱內核。
利用 Arch 編譯系統,可以基於官方的 linux包 包編譯自定義內核。這種編譯方法可以自動化整個過程,並且是基於一個已經經過詳細測試過的內核包。你可以編輯 PKGBUILD 來使用一個自定義內核配置或者添加附加的補丁。
獲取所需內容[編輯 | 編輯原始碼]
因為要使用到 makepkg, 請先了解 makepkg 的使用方法和最佳實踐建議。例如不要用 root/sudo 運行 makepkg.
首先建立一個編譯目錄 build
:
$ mkdir ~/build/ $ cd ~/build/
安裝軟件包 devtools包 和 base-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 ...
/usr/share/doc/systemd/README
中查看。在編譯前應先行檢查是否已經滿足要求。另外,隨着其版本更迭,這些要求可能會改變,arch不會對這些改變進行公吿。為了確保你的定製內核滿足systemd的要求,在更新systemd之前應檢視其發行註記。生成新校驗和[編輯 | 編輯原始碼]
#修改 prepare()步驟意味着你已經修改了$_srcname/.config
文件。需要生成新的校驗和(需安裝pacman-contrib包):
$ updpkgsums
編譯[編輯 | 編輯原始碼]
現在可以用makepkg
命令編譯內核了,如果配置時選擇了交互編譯(例如 menuconfig),編譯時需要進行配置。
$ makepkg -s
選項 -s
會在編譯時下載需要的依賴關係,比如 xml 和 docs.
- 內核代碼是 PGP 簽名, makepkg 會嘗試進行校驗,詳情請參考 makepkg#Signature checking.
- 編譯時間可能長達數小時,取決於你的硬件性能。並行編譯可以在多核系統上顯著減少編譯時間。
- 可以用
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
參閱[編輯 | 編輯原始碼]
- https://docs.kernel.org/kbuild/kconfig.html and the parent directory