內核/Arch 構建系統 - Arch Linux 中文维基

跳至內容

# 內核/Arch 構建系統

出自 Arch Linux 中文维基
< 内核
翻譯狀態：

- 本文（或部分內容）譯自 Kernel/Arch Build System，最近一次同步於 2023-7-29，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

參閱內核。

利用 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
    ...

警告：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.

注意：

- 內核代碼是 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

分類：​

- 內核

內核/Arch 構建系統
新增話題