Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學

解決 GRUB 引導錯誤:分區調整導致 CentOS 無法啟動的完整排查實錄

編輯:Linux 系統常見問題解答

問題背景

我的電腦配置了雙硬盤:一塊固態硬盤(sda)安裝 Windows 7,另一塊機械硬盤(sdb)安裝 Ubuntu 和 CentOS 兩個 Linux 發行版。系統啟動由 sdb 上 Ubuntu 的 GRUB 2 管理,負責引導選單中選擇不同作業系統啟動。

故障觸發:新增分區導致分區號漂移

昨晚我在 sdb 硬盤中間新增了一個分區(sdb6),導致後續所有邏輯分區編號全部後移。具體變化如下:

  • CentOS 根分區原為 /dev/sdb8,變更為 /dev/sdb9
  • Ubuntu 根分區位於 /dev/sdb1,編號未變,故仍能正常啟動
  • CentOS 因根分區路徑改變而無法啟動
Disk /dev/sdb: 500.1 GB, 500107862016 bytes
...
Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048   125829119    62913536   83  Linux
/dev/sdb2       125829246   970502711   422336733    f  W95 Ext'd (LBA)
/dev/sdb5       125829248   221983352    48077052+   7  HPFS/NTFS/exFAT
/dev/sdb6       221983424   228274807     3145692    b  W95 FAT32  ← 新增分區
/dev/sdb7       228274872   518603944   145164536+   7  HPFS/NTFS/exFAT
/dev/sdb8       518604008   782021941   131708967    7  HPFS/NTFS/exFAT
/dev/sdb9       782024704   918054911    68015104   83  Linux  ← CentOS 根分區新位置
/dev/sdb10      918056960   934834175     8388608   83  Linux
/dev/sdb11      934836224   951613439     8388608   83  Linux
/dev/sdb12      951615488   960004095     4194304   82  Linux swap / Solaris
/dev/sdb13      960004159   970502711     5249276+   83  Linux

初步嘗試:更新 GRUB 配置

在 Ubuntu 下執行 update-grub,輸出顯示三個作業系統均被偵測到:

Generating grub configuration file ...
Found background image: ubuntu_kylin_grub_bg.tga
Found linux image: /boot/vmlinuz-3.13.0-46-generic
Found initrd image: /boot/initrd.img-3.13.0-46-generic
Found linux image: /boot/vmlinuz-3.13.0-32-generic
Found initrd image: /boot/initrd.img-3.13.0-32-generic
Found memtest86+ image: /boot/memtest86+.elf
Found memtest86+ image: /boot/memtest86+.bin
Found Windows 7 (loader) on /dev/sda1
Found CentOS release 6.6 (Final) on /dev/sdb9
done

重啟後 CentOS 仍無法啟動,說明問題不在 GRUB 選單生成,而在啟動參數傳遞。

深入排查:fstab 與 UUID 掛載

懷疑 CentOS 啟動時自動掛載 /home 和 /var 獨立分區失敗,遂修改 CentOS 的 /etc/fstab,將所有分區標識從裝置名(如 /dev/sdb9)改為 UUID。查看 UUID 對應關係可用:

ls -l /dev/disk/by-uuid/

修改後重啟,問題依舊。

核心原因:GRUB 配置中的內核啟動參數錯誤

檢視 /boot/grub/grub.cfg 中 CentOS 的啟動條目,發現關鍵問題在第 9 行 linux 命令的 root= 參數:

menuentry 'CentOS release 6.6 (Final) (on /dev/sdb9)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-simple-d24c3228-5ffc-4937-8411-a69681c3b54e' {
    insmod part_msdos
    insmod ext2
    set root='hd1,msdos9'
    if [ x$feature_platform_search_hint = xy ]; then
        search --no-floppy --fs-uuid --set=root --hint-bios=hd1,msdos9 --hint-efi=hd1,msdos9 --hint-baremetal=ahci1,msdos9 d24c3228-5ffc-4937-8411-a69681c3b54e
    else
        search --no-floppy --fs-uuid --set=root d24c3228-5ffc-4937-8411-a69681c3b54e
    fi
    linux /boot/vmlinuz-2.6.32-504.12.2.el6.i686 ro root=/dev/sdb8 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=128M KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet vga=791
    initrd /boot/initramfs-2.6.32-504.12.2.el6.i686.img
}

錯誤點:root=/dev/sdb8 指向舊分區,實際上 sdb8 現為 NTFS 分區,導致內核無法識別檔案系統類型。手動改為 root=/dev/sdb9 即可正常啟動。

根源定位:os-prober 讀取 CentOS 舊版 GRUB 配置

執行 update-grub 後配置又被覆蓋。分析發現,CentOS 的啟動條目由 /etc/grub.d/30_os-prober 生成,而 linux-boot-prober 透過讀取 CentOS 分區中的 menu.lst(GRUB Legacy 配置)來提取啟動參數。檢視 CentOS /boot/grub/menu.lst:

title CentOS (2.6.32-504.12.2.el6.i686)
root (hd0,9)
kernel /boot/vmlinuz-2.6.32-504.12.2.el6.i686 ro root=/dev/sdb8 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=128M KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet vga=791
initrd /boot/initramfs-2.6.32-504.12.2.el6.i686.img

第 2 行 root (hd0,9) 已修正(對應 sdb9),但第 3 行 root=/dev/sdb8 未同步更新,導致 os-prober 提取錯誤參數。

最終解決

修正 CentOS menu.lst 中 kernel 行的 root= 參數為 /dev/sdb9,再次執行 update-grub,CentOS 終於能正常啟動。

經驗總結

  1. 分區調整後,必須同步更新所有引導配置,包括 GRUB 選單、fstab、以及舊版 GRUB 的 menu.lst
  2. 優先使用 UUID 而非裝置路徑標識分區,避免編號漂移導致故障
  3. 多重引導環境下,os-prober 會讀取其他作業系統的引導配置,需確保各系統內部配置一致
Copyright © Windows教程網 All Rights Reserved