Product SiteDocumentation Site

8.10. 編譯核心

Debian 的核心儘量納入所有的功能,以及最多的驅動程式,以便涵蓋現在的硬體組態。所以,有些使用者寧願自行編譯祗包括所需的核心。這麼做有兩個理由。第一,記憶體用量較小,核心程式碼,即使未用到,也佔有記憶體的空間 (而且永遠不 “離開” 置換記憶體,因為它用到實際的 RAM),降低系統的整體效能。在地自行編譯的核心也限制了安全問題的範圍,因為祗編譯與執行部份核心碼。
使用祗在補丁內的功能 (不在標準的核心內) 時,就必須重新編譯核心。

8.10.1. 簡介和先決條件

Debian 以套件方式管理核心,與傳統的編譯安裝不同調。核心還是在套件系統的控制下,可以被完整移除,或布建在多個機器上。與該等套件有關的腳本自動與啟動程式和 initrd 產生器互動。
上游的 Linux 原始碼包括建置 Debian 核心套件所需的一切。但是仍可再安裝 build-essential 以確保擁有建立 Debian 套件所需的所有工具。而且,組態核心時需要 libncurses5-dev 套件。最後,fakeroot 套件將在不使用管理者權限的前提下,啟用新增 Debian 套件。

8.10.2. 取得原始碼

Like anything that can be useful on a Debian system, the Linux kernel sources are available in a package. To retrieve them, just install the linux-source-version package. The apt search ^linux-source command lists the various kernel versions packaged by Debian. The latest version is available in the Unstable distribution: you can retrieve them without much risk (especially if your APT is configured according to the instructions of 節 6.2.6, “在多個發行版工作”). Note that the source code contained in these packages does not correspond precisely with that published by Linus Torvalds and the kernel developers; like all distributions, Debian applies a number of patches, which might (or might not) find their way into the upstream version of Linux. These modifications include backports of fixes/features/drivers from newer kernel versions, new features not yet (entirely) merged in the upstream Linux tree, and sometimes even Debian specific changes.
The remainder of this section focuses on the 4.19 version of the Linux kernel, but the examples can, of course, be adapted to the particular version of the kernel that you want.
We assume the linux-source-4.19 package has been installed. It contains /usr/src/linux-source-4.19.tar.xz, a compressed archive of the kernel sources. You must extract these files in a new directory (not directly under /usr/src/, since there is no need for special permissions to compile a Linux kernel): ~/kernel/ is appropriate.
$ mkdir ~/kernel; cd ~/kernel
$ tar -xaf /usr/src/linux-source-4.19.tar.xz

8.10.3. 組態核心

下個步驟是根據需要組態核心。確切的程序視需要而訂。
重新編譯較新版本的核心 (可能連同其補丁) 時,應儘量採用 Debian 建議的組態。在此情況下,與其從最基本開始重新編譯,不妨複製 /boot/config-version 檔案 (核心正在使用的版本,可以 uname -r 命令查看) 進入核心原始所在資料夾內的 .config 檔案。
$ cp /boot/config-4.19.0-5-amd64 ~/kernel/linux-source-4.19/.config
需要改變組態的話,就跳至 節 8.10.4, “編譯與建立套件”。或者從基本開始重新組態,就需花時間組態核心。在核心原始碼的資料夾內有很多專屬介面,供呼叫 make target 命令,讓 target 是下列的其中一個值。
make menuconfig 編譯並執行文字模式介面 (即 libncurses5-dev 套件必備) 以階層結構瀏覽可用的選項。按 空格 鍵改變選定的值,並按螢幕下方的 Enter 鈕;Select 送回選定的次選單;Exit 關閉當前的螢幕並回到上個階層;Help 顯示選項的詳細資訊。箭頭鍵在選項及按鈕清單內動。按主選單的 Exit 鈕,就可離開組態程式。此程式可儲存改變的組態;接受改變後的組態。
其他的介面也有類似的功能,但在現代化的圖形介面運作;諸如 make xconfig 使用 Qt 圖形介面,而 make gconfig 使手 GTK+。前者用到 libqt4-dev,後者依賴 libglade2-devlibgtk2.0-dev
使用這些組態介面時,建議從合理的預設組態開始。提供該等組態的核心在 arch/arch/configs/*_defconfig,然後可將選定的組態置於像 make x86_64_defconfig (64 位元電腦) 或 make i386_defconfig (32 位元電腦) 這樣的命令。

8.10.4. 編譯與建立套件

核心組態完成後,make deb-pkg 命令可產生至多 5 個 Debian 套件:linux-image-version 包括核心映像與相關的模組,linux-headers-version 包括建立外部模組所需的標頭檔案,linux-firmware-image-version 包括某些驅動程式所需的韌體 (由 Debian 提供的核心原始檔建立時,可能沒有該套件),linux-image-version-dbg 包括供套件映像及其模組的除錯符號,以及linux-libc-dev 包括 GNU glibc 之類與使用者程式庫相關的標頭。
version 由並列的上游版本決定 (如同變數 VERSIONPATCHLEVELSUBLEVELEXTRAVERSIONMakefile 內所定)、並列的 LOCALVERSION 組態參數、以及並列的 LOCALVERSION 環境變數。套件版本使用同版本字串以及新增的附加版本 (並儲存在 .version),除非以 KDEB_PKGVERSION 環境變數覆寫它們。
$ make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1
[...]
$ ls ../*.deb
../linux-headers-4.19.37-falcot_4.19.37-1_amd64.deb
../linux-image-4.19.37-falcot_4.19.37-1_amd64.deb
../linux-libc-dev_4.19.37-1_amd64.deb

8.10.5. 編譯外部模組

Some modules are maintained outside of the official Linux kernel. To use them, they must be compiled alongside the matching kernel. A number of common third party modules are provided by Debian in dedicated packages, such as vpb-driver-source (extra modules for Voicetronix telefony hardware) or leds-alix-source (driver of PCEngines ALIX 2/3 boards).
These packages are many and varied, apt-cache rdepends module-assistant$ can show the list provided by Debian. However, a complete list isn't particularly useful since there is no particular reason for compiling external modules except when you know you need it. In such cases, the device's documentation will typically detail the specific module(s) it needs to function under Linux.
For example, let's look at the dahdi-source package: after installation, a .tar.bz2 of the module's sources is stored in /usr/src/. While we could manually extract the tarball and build the module, in practice we prefer to automate all this using DKMS. Most modules offer the required DKMS integration in a package ending with a -dkms suffix. In our case, installing dahdi-dkms is all that is needed to compile the kernel module for the current kernel provided that we have the linux-headers-* package matching the installed kernel. For instance, if you use linux-image-amd64, you would also install linux-headers-amd64.
$ sudo apt install dahdi-dkms

[...]
Setting up xtables-addons-dkms (2.12-0.1) ...
Loading new xtables-addons-2.12 DKMS files...
Building for 4.19.0-5-amd64
Building initial module for 4.19.0-5-amd64
Done.

dahdi_dummy.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/4.19.0-5-amd64/updates/dkms/
[...]
DKMS: install completed.
$ sudo dkms status
dahdi, DEB_VERSION, 4.19.0-5-amd64, x86_64: installed
$ sudo modinfo dahdi_dummy
filename:       /lib/modules/4.19.0-5-amd64/updates/dkms/dahdi_dummy.ko
license:        GPL v2
author:         Robert Pleh <robert.pleh@hermes.si>
description:    Timing-Only Driver
[...]

8.10.6. 使用核心補丁

因為不夠成熟或核心維護者意見不一致,很多功能未列入標準的核心。這種功能就以補丁的型式發行,任何人都可以自由地把它維入核心原始碼。
Debian sometimes provides some of these patches in linux-patch-* packages, but they often don't make it into stable releases (sometimes for the very same reasons that they are not merged into the official upstream kernel). These packages install files in the /usr/src/kernel-patches/ directory.
在原始檔資料夾內,以 patch 命令編譯核心,就能夠納入前述安裝的補丁。
$ cd ~/kernel/linux-source-4.9
$ make clean
$ zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-3.1-4.9.11-201702181444.patch.gz | patch -p1
有些補丁不見得適用於每個核心版本;以 patch 可能無法應用於核心原始碼。將出現錯誤訊息且提示錯誤的原因;在此情況下,參照 Debian 補丁套件的文件 (位於 /usr/share/doc/linux-patch-*/ 資料夾)。大部份的情況下,維護者會指出其補丁適用的核心版本。