編譯客製化核心是 Linux 進階使用者的必修課。可精簡模組、支援新硬體、啟用特定功能(如即時核心、特定檔案系統)。本文以 Linux 2.6.0 為例,在 RedHat 9.0 平台上演示完整流程:環境準備、配置、編譯、安裝、開機載入與常見問題排解。
2.6 核心模組副檔名由 .o 改為 .ko,舊版 modutils 無法處理,必須升級:
# 強制移除舊套件
rpm -e --nodeps modutils
# 安裝原始碼 RPM
rpm -ivh modutils-2.4.21-23.src.rpm
# 進入 SPECS 目錄建構二進制 RPM
cd /usr/src/redhat/SPECS
rpmbuild -bb modutils.spec
# 安裝產生的 RPM
cd ../RPMS/i386
rpm -ivh modutils*.rpm
/etc/rc.d/rc.sysinit2.6 核心移除 /proc/ksyms,啟動腳本中檢查該檔案會導致模組載入失敗:
# 備份
cp /etc/rc.d/rc.sysinit /etc/rc.d/rc.sysinit.bak
# 編輯
vi /etc/rc.d/rc.sysinit
# 找到並修改:
# 原:if ! LC_ALL=C grep -iq nomodules /proc/cmdline 2>/dev/null && [ -f /proc/ksyms ]; then
# 新:if ! LC_ALL=C grep -iq nomodules /proc/cmdline 2>/dev/null; then
同時確認 /proc/sys/kernel/modprobe 內容為 /sbin/modprobe。
# 下載並複製至 /usr/src
cp linux-2.6.0.tar.gz /usr/src
cd /usr/src
tar xvzf linux-2.6.0.tar.gz
cd linux-2.6.0
# 若有補丁
# zcat patch-2.6.0.gz | patch -p1
# 或使用 scripts/patch-kernel 自動打補丁
# 清理舊配置 (全新解壓可略過)
make mrproper
# 圖形化配置 (需 gtk/qt 開發庫)
make gconfig # GTK 介面
# 或
make xconfig # Qt 介面
# 文字模式
make menuconfig
| 選項路徑 | 設定值 | 原因 |
|---|---|---|
| File systems → Ext3/Ext2 | Y (內建而非模組) | 根分區若為 ext3/ext2,必須內建否則無法掛載根檔案系統 (kernel panic: VFS: Unable to mount root fs) |
| Kernel → Module unloading | Y | 允許 rmmod 卸載模組 |
| Processor type and features | 選擇正確 CPU 型號 | 效能優化 |
# 開始編譯 (含 bzImage + modules)
make
# 依硬體效能約 20-60 分鐘
# 編譯完成後核心映像位於
arch/i386/boot/bzImage
# 一鍵安裝模組、核心、System.map、建立 initrd、更新開機載入器
make modules_install install
執行後:
/lib/modules/2.6.0//boot 下產生 vmlinuz-2.6.0、System.map-2.6.0、initrd-2.6.0.img/boot/grub/grub.conf;LILO 需手動執行 lilo新核心下 rpm 會因 glibc 版本判斷失敗而無法執行,需設定環境變數:
# 編輯 /etc/profile
vi /etc/profile
# 末尾加入
if [ `uname -r` = "2.6.0" ]; then
export LD_ASSUME_KERNEL=2.2.5
fi
或臨時執行 export LD_ASSUME_KERNEL=2.2.5。
shutdown -r now
# 開機選單選擇新核心
uname -r # 應顯示 2.6.0
lsmod # 模組載入正常
iptables -L # 防火牆模組載入成功
| 問題 | 可能原因 | 解決方案 |
|---|---|---|
| 核心無法開機 (kernel panic) | 根檔案系統驅動未內建、initrd 缺失、GRUB 配置錯誤 | 重新配置核心 (內建 ext3/ext2、SATA/SCSI 控制器)、重建 initrd、檢查 grub.conf |
| 模組無法載入 | module-init-tools 版本過舊、rc.sysinit 未修正 | 升級 module-init-tools、修正 rc.sysinit |
| rpm 指令失效 | glibc 版本檢查機制 | 設定 LD_ASSUME_KERNEL=2.2.5 |
編譯報錯 Unknown pseudo-op: .incbin | binutils/gcc 版本過舊 | 升級編譯工具鏈 (RedHat 9.0 以上通常已解決) |
make localmodconfig 依目前載入模組自動生成精簡配置ccache 加速重複編譯make rpm-pkg / make deb-pkg 方便部署與回滾scripts/sign-file