FlossDoc: 请协力 GPLv3 的中文翻译工作。

編譯 Linux 核心成為 dpkg 套件(*.deb)

FlossDoc,自由中文開源知識庫

Jump to: navigation, search

標準文章
作者: Roy Chan
協力: AnthonyWongTroySacre
校對: -
級別: 初階
分享本文:

本文主要討論如何編譯 Linux 核心成 DPKG 套件(*.deb)。如果想把 Linux 編譯成 RPM 套件用原始工具編譯,可以參看相關文章。

目录

為何要編譯核心

  • 支援新的硬體設備
  • 支援新的功能
  • 修正舊版本的一些問題或安全漏洞
  • 優化核心,降低系統資源需求

Linux 核心 dpkg 套件(*.deb)

如果您的系統是使用 dpkg 套件管理系統(包括 DebianUbuntuXandros 等),那麼您值得考慮使用把 Linux 核心包成 dpkg 套件(*.deb)。成為 dpkg 套件,可以享有其他包成 dpkg 套件軟件的優點,在安裝、管理和更新方面都較為方便。尤其當您要維護大量近似硬體配備及運行 dpkg 的 GNU/Linux 系統時,核心 dpkg 套件的長處就顯然易見。

預備編譯需要的工具

需要以下套件:

  • tar (GNU Tar) - 用來解開源碼壓縮檔(*.tar.*)。
  • gzip (GNU Zip) - 用來解開 GNU Zip 了的源碼壓縮檔(*.gz)。
  • bzip2 (BZip2) - 用來解開 BZip2 了的源碼壓縮檔(*.bz2)。
  • gcc (GNU C Compiler) - 用來編譯核心。
  • make (GNU Make) - 用來管理編譯過程。
  • libc6-dev (GNU Library C 標頭) - 編譯C程式(包括Linux核心)時需要的檔案。
  • kernel-package (Kernel Package) - 包含了一些工具可以輕易接您把核心編譯好,並包成 Debian 套件,方便管理。
  • fakeroot (Fake Root) - 在普通使用者環境模擬一個系統管理員環境,方使包封套件。
  • libncurses5-dev (NCurses 5 程式庫標頭) - make menuconfig 時編譯繪畫文字視窗的程式需要的檔案。(可略過)
  • wget (GNU WGet) - 下載源碼壓縮檔和相關程式。(可略過)

您可以真接打以下命令安裝所有所需套件:

apt-get install gcc make libc6-dev kernel-package libncurses5-dev fakeroot wget bzip2

取得 Linux 核心源碼

要編譯 Linux,首先當然是要最得 Linux 的源碼(source code)。最新的 Linux 官方源碼是可以從 Kernel.org 或其映射站取得,而最新 2.6.x 版本一般放在 /pub/linux/kernel/v2.6/ 中。

當然,您亦可以使用 distribution 所提供的 Linux 源碼。

核實 Linux 核心源碼 (可省略)

要確保您下載的 Linux 核心源碼沒有被人惡意植入有問題的程式碼,每個 tarball 都有一個 *.sign 記錄了相關程式碼的數碼簽署,可以讓您用 GNUPG 之類的軟件核實源碼的真偽。

先確定您擁有 Kernel.org 的數碼公鑰,您可以到 Kernel.org 或由金鑰伺服器 wwwkeys.pgp.net下載:

$ gpg --keyserver wwwkeys.pgp.net --recv-keys 0x517D0F0E
gpg: requesting key 517D0F0E from hkp server wwwkeys.pgp.net
gpg: key 517D0F0E: "Linux Kernel Archives Verification Key <ftpadmin@kernel.org>" 34 new signatures
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:         new signatures: 34
$

使用 GNUPG 核實源碼:

$ gpg --verify linux-2.6.36.tar.bz2.sign linux-2.6.36.tar.bz2
gpg: Signature made Thu 15 Dec 2005 02:13:27 PM HKT using DSA key ID 517D0F0E
gpg: Good signature from "Linux Kernel Archives Verification Key <ftpadmin@kernel.org>"

如果您得到以上結果,即表示您下載的源碼正確無誤。但如果您得到以下結果,您下載的源碼可能已被人更動過了。

Could not find a valid trust path to the key.  Let's see whether we
can assign some missing owner trust values.

No path leading to one of our keys found.
 
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.

解開核心源碼壓縮檔

解開GNU Zip了(*.tar.gz)的壓縮檔

如果您是下載了GNU Zip了的Linux核心源碼壓縮檔(檔案伸廷名稱為*.tar.gz),可以用指令 "tar zxvf linux-版本編號.tar.gz"解壓:

tar zxvf linux-2.6.36.tar.gz

解開BZip2了(*.tar.bz2)的壓縮檔

如果您是下載了BZip2了的Linux核心源碼壓縮檔(檔案伸廷名稱為*.tar.bz2),可以用指令 "tar jxvf linux-版本編號.tar.bz2"解壓:

tar jxvf linux-2.6.36.tar.bz2

建立連結

ln -s linux-2.6.36 /usr/src/linux

用 Patch 檔案

如果您有前一個版本的 Linux 核心源碼並下載了 GNU Zip 了的現在版本 patch 檔案 (檔名為patch-*.gz),可以使用工具 patch 把前一個版本的 Linux 核心源碼轉變成現在版本:

cd linux-2.6.18
gzip -cd ../patch-2.6.17.gz | patch -p1 --dry-run
gzip -cd ../patch-2.6.17.gz | patch -p1

如果您有前一個版本的 Linux 核心源碼並下載了 BZip2 了的現在版本 patch 檔案 (檔名為patch-*.bz2),可以使用工具 patch 把前一個版本的 Linux 核心源碼轉變成現在版本:

cd linux-2.6.18
bzip2 -cd ../patch-2.6.17.bz2 | patch -p1 --dry-run
bzip2 -cd ../patch-2.6.17.bz2 | patch -p1

設定編譯選項

編譯 Linux 核心其中一個最重要的步驟就是選擇您的新核心需要那些功能,那些功能要編譯成可載入模組(Loadable Modules),甚至那些功能不需要編入核心中。當然,越少功能可以令新核心大小越少,耗癈資源越少。但如果編譯功能太少,常需要新功能時,就需要再重新編譯核心。所以設定編譯選項亦成為編譯核心中最困難和最耗時的步驟。

Linux 提供了多個方法去讓您設定編譯選項:

  • make config - 文字模式遂行回答
  • make menuconfig - 全螢幕文字模式選單選擇選項
  • make xconfig - X Window 圖形介面 (Qt 或 Tcl/Tk) 選擇選項
  • make gconfig - X Window 圖形介面 (GTK+) 選擇選項
  • make oldconfig - 文字模式只遂行回答新選項

make config - 文字模式

make config 是最原始的設定方法,早在 Linux 0.x 時就出現了。當您打入 make config,系統就會在文字模式下會逐一問您每一個編譯選項:

$ make config
scripts/kconfig/conf arch/i386/Kconfig
*
* Linux Kernel Configuration
*
*
* Code maturity level options
*
Prompt for development and/or incomplete code/drivers (EXPERIMENTAL) [Y/n/?]
*
* General setup
*
Local version - append to kernel release (LOCALVERSION) []
Automatically append version information to the version string (LOCALVERSION_AUTO) [Y/n/?] 
Support for paging of anonymous memory (swap) (SWAP) [Y/n/?]
System V IPC (SYSVIPC) [Y/n/?]
POSIX Message Queues (POSIX_MQUEUE) [Y/n/?]
BSD Process Accounting (BSD_PROCESS_ACCT) [N/y/?]
Export task/process statistics through netlink (EXPERIMENTAL) (TASKSTATS) [N/y/?]
Auditing support (AUDIT) [N/y/?]
Kernel .config support (IKCONFIG) [Y/n/?]
  Enable access to .config through /proc/config.gz (IKCONFIG_PROC) [Y/n/?]
Kernel->user space relay support (formerly relayfs) (RELAY) [N/y/?]
Initramfs source file(s) (INITRAMFS_SOURCE) []
Optimize for size (Look out for broken compilers!) (CC_OPTIMIZE_FOR_SIZE) [Y/n/?] n
*
* Configure standard kernel features (for small systems)
*
Configure standard kernel features (for small systems) (EMBEDDED) [N/y/?]

一般編譯選項容許您選擇 (用大階字母顯示表示為預設選項):

  • y (Yes) - 啟用該功能或選項,並且編譯入 Linux 核心中。
  • n (No) - 關閉該功能或選項,並且不編譯入 Linux 核心或成為模組。
  • m (Module) - 將該功能或選項編譯成模組,需要時才載入系統。
  •  ? (Help) - 取得該功能或選項的說明。

這種方法的好處是設定時不需要額外的程式庫,壞處是當您發覺選錯選項時,您只可以按 Ctrl-C 中斷設定,重新回答每個問題,非常麻煩。現時編譯 Linux 有三千七百多個選項,make config 顯然不一個聰明的選擇。如果您沒有 NCurses 之類程式庫,直接用文字編輯器編輯檔案 .config 可能會比 make config 更方便。

make menuconfig - 文字選單模式

make menuconfig 使用 NCurses 程式庫在文字模式繪出選單讓您選擇編譯選項。您可以用上下箭咀鍵在各選項間穿梭,隨意調校任何選項,在操控上是最方便的。

同樣您可以按 y/n/m 選擇將該功能或選項開啟/關閉/編成模組。當您看到 “*” 就表示該功能被開啟了,空格為關閉,“M” 為編譯成模組。您可以按空間鍵 (Space bar) 在各狀態中切換。選項如用角括號 (“< >”) 括住表示選項可以設為 y/n/m 其中一個狀態,方括號 (“[ ]”) 則表示選項只可以設為 y/n 兩個狀態,花括號 (“{ }”) 則表示選項只可以設為 m/n 兩個狀態。

make xconfig - 圖像模式 (Qt/Tcl)

make xconfig 顧名思意就是讓您在 X Window 環境下選擇編譯選項。Linux 2.2 時使用 Tcl/Tk,2.4 開始轉用 Qt,GTK+ 則用下面的 gconfig 來啟動。當然選擇編譯選項,您需要有相關的圖形工具箱的程式庫。其操控反而不及 menuconfig 方便。

Qt 版面提供三種顯示方式:

  • Split - 以三個窗格顯示。左窗格以樹狀展示各選項分類,右上窗格以樹狀展示分類中的各選項,右下窗格顯示選項的詳細描述。
  • Single - 在單一窗格選擇了選項分類後,就會以上下兩個窗格顯示。上窗格以樹狀展示分類中的各選項,下窗格顯示選項的詳細描述。
  • Fullview - 以上下兩個窗格顯示。上窗格以樹狀展示所有選項,下窗格顯示選項的詳細描述。
Split View
Enlarge
Split View
Single View
Enlarge
Single View
Full View
Enlarge
Full View

「✓」表示啟用,空間表示關閉,圓點(「.」)表示編譯成模組。

舊 Tcl 版面 (2.2.x 或以前):

make gconfig - 圖像模式 (GTK+)

make gconfig 讓您在 X Window 環境下用 GTK+ 介面選擇編譯選項。當然選擇編譯選項,您需要有 GTK+ 圖形工具箱的程式庫。

GTK+ 版面和 Qt 版面一樣提供三種顯示方式:

  • Split - 以三個窗格顯示。左窗格以樹狀展示各選項分類,右上窗格以樹狀展示分類中的各選項,右下窗格顯示選項的詳細描述。
  • Single - 在單一窗格選擇了選項分類後,就會以上下兩個窗格顯示。上窗格以樹狀展示分類中的各選項,下窗格顯示選項的詳細描述。
  • Fullview - 以上下兩個窗格顯示。上窗格以樹狀展示所有選項,下窗格顯示選項的詳細描述
Split View
Enlarge
Split View
Single View
Enlarge
Single View
Full View
Enlarge
Full View

「✓」表示啟用,空間表示關閉,減號(「-」)表示編譯成模組。

make oldconfig - 只選擇新編譯選項

make oldconfig 操作方式和 make config 一樣,也是文字模式下遂個選項問您,但他只會問新的選項。如果您曾編譯早一兩版的 Linux,oldconfig 可以大大減低您設定的時間,亦讓您清楚知道新版 Linux 有什麼新功能。

使用則,您必需要取得以往編譯時的編譯選項 (即檔案 .config) 或 distribution 官方編譯選項。習慣上各核心的編譯設定檔會保存在目錄 /boot 中一些名為 “config-核心版本” 的檔案中,您可以直接複製至您的核心源碼目錄中:

cp /boot/config-`uname -r` .config

搞定後打「make oldconfig」設定新編譯選項:

make oldconfig

設定編譯選項提示

一般要留意的選項

  • Processor type and features
    • Symmetric multi-processing support (SMP) - 如果您的電腦有多過一個微處理器或多核心(Dual/Quad Core),請開啟這選項。
    • Processor family - 選擇適合您的微處理器家族,您可以看看檔案 /proc/cpuinfo 查閱您現時的微處理器型號。
      • 386 (M386) - Intel 80386 系列及 AMD, Cyrix 的兼容微處理器。
      • 486 (M486) - Intel 80486 系列及 AMD, Cyrix, IBM 的兼容微處理器。
      • 586/K5/5x86/6x86/6x86MX (M586) - 非 Intel 的 586/686 微處理器,包括AMD K5、Cyrix 5x86, 6x86 及 6x86MX。
      • Pentium-Classic (M586TSC) - 原始 Intel Pentium
      • Pentium-MMX (M586MMX) - 支援 MMX 圖形及多媒體擴充指令的 Intel Pentium
      • Pentium-Pro (M686) - Intel Pentium Pro
      • Pentium-II/Celeron(pre-Coppermine) (MPENTIUMII) - Intel Pentium II 及 pre-Coppermine Celeron
      • Pentium-III/Celeron(Coppermine)/Pentium-III Xeon (MPENTIUMIII) - Intel Pentium III、Coppermine Celeron 及 Intel Pentium-III Xeon
      • Pentium M (MPENTIUMM) - Intel Pentium III Mobile (不是 Pentium 4 Mobile)
      • Pentium-4/Celeron(P4-Based)/Pentium-4 M/Xeon (MPENTIUM4) - Intel Pentium 4,包括 Celeron 、 Xeon 及 Mobile
      • K6/K6-II/K6-III (MK6) - AMD K6 系列
      • Athlon/Duron/K7 (MK7) - AMD Athlon K7 系列
      • Opteron/Athlon64/Hammer/K8 (MK8) - AMD Opteron 或 Athlon64 Hammer 系列
      • Crusoe (MCRUSOE) - Transmeta Crusoe
      • Efficeon (MEFFICEON) - Transmeta Efficeon
      • Winchip-C6 (MWINCHIPC6) - IDT Winchip C6
      • Winchip-2 (MWINCHIP2) - IDT Winchip-2
      • Winchip-2A/Winchip-3 (MWINCHIP3D) - IDT Winchip-2A 或 3
      • GeodeGX1 (MGEODEGX1) - Geode GX1 (Cyrix MediaGX)
      • GeodeGX/LX (MGEODE_LX) - AMD Geode GX 或 LX
      • CyrixIII/VIA-C3 (MCYRIXIII) - Cyrix III 或 C3
      • VIA C3 (Nehemiah) (MVIAC3_2) - VIC C3 "Nehemiah"
    • Maximum number of CPUs (2-255) - 填入您電腦的 CPU 數量。例如 Duo Core 填「2」。CPU 最大數量每多一就會令 Linux 核心大約八千左右位元組。
    • High Memory Support - 如果您的電腦不會擁有 1GB 或以上的記憶體,請選off。如記憶體大小界符1GB 和 4GB 之間,選 4GB。如果多於 4GB,請選 64GB。
  • Device Drivers -> ATA/ATAPI/MFM/RLL support -> Include IDE/ATA-2 DISK support (BLK_DEV_IDEDISK) - 建議開啟。不開啟這選項,您就使用不到 IDE 硬盤,連開動 Linux 都不能。(當然,用 SCSI 硬盤的朋友可以不開啟這選項。)
  • Device Drive -> Block Devices -> Low Performance USB Block Driver (BLK_DEV_UB) - 建議關閉。不要開啟這選項或編譯成為模組。這選項會開啟效能較低的USB驅動器(ub)。[1] [2] (2.6.9 或以後)

如果您使用 nVidia 顯示咭,請關閉下列選項:

  • Graphics Support -> nVidia Riva support (FB_RIVA)
  • Kernel Hacking -> Use 4Kb for kernel stacks instead of 8Kb (4KSTACKS)
  • Processor Type and Features -> Local APIC support on uniprocessors (X86_UP_APIC)

設定桌面電腦(Desktop)要留意的選項

  • Preemption Model
    • Preemption (Low-Latency Desktop) (PREEMPT) - 開啟這選項可以令多媒體播放更流暢,是桌面電腦必用的選項。
    • Preempt The Big Kernel Lock (PREEMPT_BKL) - 建議開啟。
    • Timer frequency (CONFIG_HZ_250 或者 CONFIG_HZ_1000) - 對桌面電腦來說,選 250Hz 而可以令多媒體播放很流暢,但如果您對這方便要求高,可以考慮使用 1000Hz,但留意電量較高。
  • Block Layer -> IO Schedulers - 建議使用 CFQ I/O 排程器。這是決定使用硬碟存取排程器。在桌面平代方面,CFQ 的表現較平均。

設定筆記簿型電腦 (Laptop/Notebook) 要留意的選項

  • 留意上面設定桌面電腦 (Desktop) 要留意的選項
    • Timer frequency (CONFIG_HZ_250) - 對筆記簿型電腦來說,選 250Hz 而可以令多媒體播放很流暢,而 1000Hz 會令電池壽命大大縮短。

設定伺服器 (Server) 要留意的選項

  • Preemption Model
    • Preemptible Kernel (PREEMPT) - 建議關閉。開啟這選項可以令多媒體播放更流暢,但如果您是用來作伺服器之用,這選項可能會降低系統效能,請把此選項關掉。
    • No Forced Preemption (Server) (PREEMPT_NONE) - 建議選用。
    • Preempt The Big Kernel Lock (PREEMPT_BKL) - 建議關閉。
    • Timer frequency (CONFIG_HZ_100) - 建議使用 100Hz。
  • Block Layer
    • Support for Large Block Devices (LBD) - 如要存取超過 2TB 大小的儲存設備(如硬碟、RAID或硬碟映像檔等),就需要開啟選項。
    • Support for Large Single Files (LSF) - 如要處理超過 2TB 大小的檔案,就需要開啟選項。
    • IO Schedulers - 決定使用硬碟存取排程器。如果您的伺服器是用來跑資料庫 (Database),請使用deadline 排程器。

編譯核心

xkcd #303: Compiling[1]
Enlarge
xkcd #303: Compiling[1]

如果您之前曾編譯過,請先打 "make-kpkg clean"

打 "make-kpkg binary --rootcmd=fakeroot --revision=修訂版本 --append-to-version=核心擴充版本"。

  • 修訂版本 (revision) - dpkg 套件附加修訂版本,會附加 dpkg 套件版本後面,習慣用編譯的時間,如2006年11月6日8時21分 - 200611060821。
  • 核心擴充版本 (append-to-version) - 核心的擴充版本,會附加在 dpkg 套件的名稱和核心版本(命令 uname -r 的結果)後面 。可以用來分別不同優代的核心。習慣會使用安裝電腦的名稱,前頭最好加一個減號,例如 -tpx30 (Thinkpad X30)、-hal (電腦 hal) 等。
make-kpkg binary --rootcmd=fakeroot --revision=200611060821 --append-to-version=-hal

安裝新核心

安裝套件

dpkg -i kernel-image_2.6.8.2-200611060821.deb

設定開機管理程式

如果您是透過 dpkg 命令安裝新的 Linux 核心套件,系統會自動幫您設定開機管理程式。

不過您亦以按下指示檢查開機管理程式的設定是否有問題。

設定 GRUB

設定 GRUB 前請先輸入命令 df 查出目錄 //boot 所在的分割區名稱,例如:

$ df
檔案系統           1K-區段      已用     可用     已用% 掛載點
/dev/sda5         14535584   7275752  6527272  53% /
udev               1033204        60  1033144   1% /dev
devshm             1033204       184  1033020   1% /dev/shm
/dev/sda2            43256     24819    18437  57% /boot

如上例中,目錄 / 的分割區名稱就是 /dev/sda5。

修改 GRUB 的設定檔 /boot/grub/menu.lst 加上啟動新 Linux 核心的項目,以下是 Ubuntu/Debian 的例子:

## ## End Default Options ##

title           New Linux (2.6.36)
root            (hd0,4)
kernel          /boot/vmlinuz-2.6.36 root=UUID=a3b3df6a-a4b7-4395-8278-45c23e45ca53 ro quiet splash locale=zh_TW
quiet

title		Ubuntu 8.04, kernel 2.6.24-19-generic
root		(hd0,4)
kernel		/boot/vmlinuz-2.6.24-19-generic  root=UUID=a3b3df6a-a4b7-4395-8278-45c23e45ca53 ro quiet splash locale=zh_TW
initrd		/boot/initrd.img-2.6.24-19-generic
quiet

以下是 Fedora/CentOS 的例子:

splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title New Linux (2.6.36)
      root (hd0,0)
      kernel /vmlinuz-2.6.36 ro root=/dev/VolGroup00/LogVol100 rhgb quiet

title Fedora (2.6.26.10-86.fc9.i686)
      root (hd0,0)
      kernel /vmlinuz-2.6.25.10-86.fc9.i686 ro root=/dev/VolGroup00/LogVol100 rhgb quiet
      initrd /initrd-2.6.25.10-86.fc9.i686.img

簡單來說,把現有的項目設定複製一次,改一改標題 (title) 和核心名稱 (kernel) 就可以了。

設定 lilo

設定好設定檔案 /etc/lilo.conf

boot=/dev/hda
root=/dev/hda5
install=/boot/boot.b
map=/boot/map
vga=normal
delay=100
image=/boot/vmlinuz-2.6.36
    label=Linux
    read-only
image=/boot/vmlinuz-2.6.8
    label=LinuxOld
    read-only
other=/dev/hda1
    label=WinXP
    table=/dev/hda

打「lilo」把 LILO 和設定寫入指定的 MBR 或 VBR。

 lilo

失敗後的處理方法

參考資料

  1. xkcd (2007) Compiling. xkcd, #303. Retrieved at Nov 4, 2010 from: http://xkcd.com/303/

請參看

外部連結

Personal tools