Linux 核心編譯是驅動開發、嵌入式移植、效能調校的基本功。本文提供**標準化、可重現**的完整流程:從 make menuconfig 配置、make bzImage/modules 編譯、mkinitramfs 產生初始虛擬檔案系統、修改 GRUB 開機項目,到虛擬機實測驗證。
/usr/src/linux-source-x.xx.x (或 git clone 核心樹)gcc, make, bc, libssl-dev, libelf-dev, bison, flexsudo 或 rootcd /usr/src/linux-source-x.xx.x
make menuconfig # 互動式選單配置 (NCURSES)
# 或 make nconfig / xconfig / gconfig
cp /boot/config-$(uname -r) .config → make olddefconfigCONFIG_IKCONFIG=y、CONFIG_IKCONFIG_PROC=y (支援 /proc/config.gz)、CONFIG_DEBUG_INFO=y (除錯符號)、模組化驅動 (M) 以縮小核心體積。make mrproper # 徹底清理,含 .config
# 或
make clean # 僅清理編譯產物 (.o, .ko 等),保留 .config
# 多核心並行編譯 (N = 邏輯核心數 + 1)
make -j$(nproc) bzImage # 編譯核心映像 → arch/x86/boot/bzImage
make -j$(nproc) modules # 編譯所有模組 (*.ko)
sudo make modules_install # 安裝模組至 /lib/modules/x.xx.x/
產物:arch/x86/boot/bzImage (核心映像)、/lib/modules/x.xx.x/ (模組樹)。
# 複製配置檔供套件管理器參考
sudo cp .config /boot/config-x.xx.x
# 產生 initramfs (Debian/Ubuntu 系列)
sudo mkinitramfs -o /boot/initrd.img-x.xx.x x.xx.x
# x.xx.x 必須與 /lib/modules/ 下目錄名完全一致
# RHEL/Fedora 系列
# sudo dracut -f /boot/initramfs-x.xx.x.img x.xx.x
編輯 /boot/grub/grub.cfg (或 /etc/grub.d/40_custom 再 update-grub),複製現有啟動項並修改核心/initrd 路徑:
menuentry 'Test Kernel 3.7.4' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
gfxmode $linux_gfx_mode
insmod gzio
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set=root 7b4e922c-d943-4b84-9c75-4fdc57cf1a3f
linux /boot/vmlinuz-3.7.4 root=UUID=7b4e922c-d943-4b84-9c75-4fdc57cf1a3f ro quiet splash $vt_handoff
initrd /boot/initrd.img-3.7.4
}
關鍵點:linux 行指向核心映像 (vmlinuz-*),initrd 行指向對應 initramfs,root=UUID=... 必須指向根檔案系統分區。
dmesg | less、journalctl -b,確認無 FAILED/ERROR/panic。lsmod | grep your_module。| 現象 | 可能原因 | 排查方向 |
|---|---|---|
| Kernel panic: VFS: Unable to mount root fs | initramfs 缺少儲存/檔案系統模組、root=UUID 錯誤 | 檢查 mkinitramfs 參數、lsinitramfs /boot/initrd.img-* | grep -E 'ext4|xfs|btrfs|nvme|ahci' |
| 模組載入失敗: Unknown symbol | 核心配置與模組版本不符 | 重跑 make modules_install、確認 /lib/modules/$(uname -r) 正確 |
| 啟動卡在 "Waiting for root device" | initramfs 未包含 SATA/NVMe/USB 儲存驅動 | make menuconfig → Device Drivers → 將控制器設為 Y (內建) 而非 M |
| 編譯錯誤: implicit declaration of function | 缺少標頭檔或 API 變更 | 核心版本與原始碼樹不匹配,檢查 KERNELRELEASE |
#!/bin/bash
set -e
KVER="5.15.100-custom"
cd /usr/src/linux-${KVER}
make -j$(nproc) bzImage modules
sudo make modules_install
sudo cp arch/x86/boot/bzImage /boot/vmlinuz-${KVER}
sudo cp .config /boot/config-${KVER}
sudo mkinitramfs -o /boot/initrd.img-${KVER} ${KVER}
sudo update-grub
echo "Kernel ${KVER} built & installed. Reboot to test."
核心編譯看似繁雜,實則遵循固定流程:**配置 → 清理 → 編譯核心/模組 → 安裝模組 → 產生 initramfs → 更新 GRUB → 驗證** 掌握此流程,即可自由裁剪核心功能、回溯/前瞻版本、驗證補丁、優化啟動速度。建議配合 ccache、distcc 加速重複編譯,並將 .config 納入版控,實現核心建構的基礎設施即代碼化。