Linux-Kernel

Linux安裝在啟動過程中找不到磁碟的第一個分區

  • May 4, 2021

我有一個從 x86-64 機器上安裝的硬碟映像openSUSE,我不再可以訪問它。我正在嘗試使用quemu. 如果我使案例如qemu-system-x86_64 -m 4096 -curses -hda srv.sda -enable-kvmor啟動虛擬機qemu-system-x86_64 -m 4096 -curses -drive id=disk,file=srv.sda,if=none,format=raw -device ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0 -enable-kvm,那麼我最終會進入 GRUB 2.02 shell,我可以在其中使用以下命令指定 Linux 核心和初始 ramdisk:

grub> linux (hd0,msdos1)/boot/vmlinuz
grub> initrd (hd0,msdos1)/boot/initrd
grub> boot

這將啟動始終在此處結束的引導過程:

             [    0.234732] NET: Registered protocol family 10
             [    0.235188] lo: Disabled Privacy Extensions
             [    0.235592] lib80211: common routines for IEEE802.11 drivers
             [    0.236014] registered taskstats version 1
             [    0.236439]   Magic number: 1:617:774
             [    0.236774] mem zero: hash matches
             [    0.237151] rtc_cmos 00:01: setting system clock to 2021-04-22 07:46:24 UTC (
             1619077584)
             [    0.237802] Freeing unused kernel memory: 896k freed
             [    0.238330] Write protecting the kernel read-only data: 10240k
             [    0.238762] Freeing unused kernel memory: 1616k freed
             [    0.239578] Freeing unused kernel memory: 748k freed
             doing fast boot
             Creating device nodes with udev
             [    0.255337] udev: starting version 157
             mount: devpts already mounted or /dev/pts busy
             mount: according to mtab, devpts is already mounted on /dev/pts
             Boot logging started on /dev/char/../tty1(/dev/console) at Thu Apr 22 10:46:24 2
             021
             resume device  not found (ignoring)
             Waiting for device /dev/sda1 to appear: [    1.072809] input: ImExPS/2 Generic E
             xplorer Mouse as /devices/platform/i8042/serio1/input/input1
             ..............................Could not find /dev/sda1.
             Want me to fall back to /dev/sda1? (Y/n)

我可以qemu以某種方式修改磁碟的設置,使磁碟的第一個也是唯一一個分區可用於 Linux 嗎?例如,看起來 GRUB 在成功讀取/boot/vmlinuzand時能夠訪問它/boot/initrd

編輯 1:重新創建初始 ramdisk 並包括ata_piix核心模組後,qemu-system-x86_64引導過程如下:

             [    0.244118] rtc_cmos 00:01: setting system clock to 2021-04-27 15:31:52 UTC (
             1619537512)
             [    0.244762] Freeing unused kernel memory: 896k freed
             [    0.245284] Write protecting the kernel read-only data: 10240k
             [    0.245716] Freeing unused kernel memory: 1616k freed
             [    0.246529] Freeing unused kernel memory: 748k freed
             doing fast boot
             [    0.266568] SCSI subsystem initialized
             [    0.267653] megasas: 00.00.04.17.1-rc1 Thu. Oct. 29, 11:41:51 PST 2009
             [    0.278467] scsi0 : ata_piix
             [    0.278833] scsi1 : ata_piix
             [    0.279164] ata1: PATA max MWDMA2 cmd 0x1f0 ctl 0x3f6 bmdma 0xc060 irq 14
             [    0.279562] ata2: PATA max MWDMA2 cmd 0x170 ctl 0x376 bmdma 0xc068 irq 15
             Creating device nodes with udev
             [    0.444780] udev: starting version 157
             mount: devpts already mounted or /dev/pts busy
             mount: according to mtab, devpts is already mounted on /dev/pts
             Boot logging started on /dev/char/../tty1(/dev/console) at Tue Apr 27 18:31:52 2
             021
             resume device  not found (ignoring)
             Waiting for device /dev/sda1 to appear: [    1.080811] input: ImExPS/2 Generic E
             xplorer Mouse as /devices/platform/i8042/serio1/input/input1
             ..............................Could not find /dev/sda1.
             Want me to fall back to sda1? (Y/n)

如上所示,該ata_piix模組似乎已載入,但/dev/sda1仍未找到。

編輯 2:我以一種替換為的方式修改了/etc/fstabinchroot環境,重新生成了初始 ramdisk,並嘗試通過在 GRUB shell 中指定 Linux 核心和初始 ramdisk 來引導該系統:/dev/sda1 / reiserfs acl,user_xattr 1 1``UUID=dafc3c3a-1469-44b1-b85c-deb904aac291 / reiserfs acl,user_xattr 1 1

grub> linux (hd0,msdos1)/boot/vmlinuz root=UUID=dafc3c3a-1469-44b1-b85c-deb904aac291
grub> initrd (hd0,msdos1)/boot/initrd
grub> boot

不幸的是,系統沒有啟動。我還將添加mkinitrd輸出:

# mkinitrd -v -k vmlinuz-2.6.34.10-0.6-default -i initrd-2.6.34.10-0.6-default -d /

Kernel image:   /boot/vmlinuz-2.6.34.10-0.6-default
Initrd image:   /boot/initrd-2.6.34.10-0.6-default
[MODULES]       02-start.sh: reiserfs thermal megaraid_sas ata_piix ata_generic processor fan
[MODULES]       02-start.sh:
[MODULES]       03-rtc.sh: rtc_cmos
[MODULES]       03-storage.sh: reiserfs
[MODULES]       11-usb.sh: usbcore
[MODULES]       11-usb.sh: ohci_hcd
[MODULES]       11-usb.sh: uhci-hcd
[MODULES]       11-usb.sh: ehci_hcd
[MODULES]       11-usb.sh: usbhid
[MODULES]       'modinfo -k "2.6.34.10-0.6-default" -F supported'  returned with an error.
Kernel Modules: reiserfs thermal_sys thermal scsi_mod megaraid_sas libata ata_piix ata_generic processor fan usbcore pcmcia_core pcmcia mmc_core ssb ohci-hcd ehci-
hcd uhci-hcd usbhid
[MOUNT] Root:   /
Features:       usb resume.userspace resume.kernel
Bootsplash:     openSUSE (640x480)
Shared libs:    /lib/udev/collect_lvm is a script
/lib/udev/findkeyboards is a script
/lib/udev/idedma.sh is a script
/lib/udev/iwlwifi-led.sh is a script
/lib/udev/keyboard-force-release.sh is a script
/lib/udev/kpartx_id is a script
/lib/udev/udev-add-printer is a script
/lib/udev/write_cd_rules is a script
/lib/udev/write_net_rules is a script
/lib/mkinitrd/bin/ipconfig.sh is a script
/sbin/ifup is a script
/lib/mkinitrd/bin/ipconfig.sh is a script
/lib/mkinitrd/bin/linuxrc is a script
/usr/bin/on_ac_power is a script
lib64/ld-2.11.2.so lib64/libacl.so.1.1.0 lib64/libattr.so.1.1.0 lib64/libblkid.so.1.1.0 lib64/libcap.so.2.16 lib64/libcom_err.so.2.1 lib64/libcrypto.so.1.0.0 lib64
/libc-2.11.2.so lib64/libdevmapper.so.1.02 lib64/libdl-2.11.2.so lib64/libgcrypt.so.11.5.2 lib64/libgpg-error.so.0.5.0 lib64/libkeyutils-1.3.so lib64/liblzo2.so.2.
0.0 lib64/libm-2.11.2.so lib64/libncurses.so.5.7 lib64/libpcre.so.0.0.1 lib64/libpthread-2.11.2.so lib64/libreadline.so.6.1 lib64/libresolv-2.11.2.so lib64/librt-2
.11.2.so lib64/libselinux.so.1 lib64/libsepol.so.1 lib64/libssl.so.1.0.0 lib64/libudev.so.0.8.2 lib64/libutil-2.11.2.so lib64/libuuid.so.1.3.0 lib64/libz.so.1.2.3
usr/lib64/libatasmart.so.4.0.3 usr/lib64/libcups.so.2 usr/lib64/libdal-0.3.so.0.0.0 usr/lib64/libdirect-1.2.so.9.0.0 usr/lib64/libdirectfb-1.2.so.9.0.0 usr/lib64/l
ibfusion-1.2.so.9.0.0 usr/lib64/libglib-2.0.so.0.2400.1 usr/lib64/libgssapi_krb5.so.2.2 usr/lib64/libk5crypto.so.3.1 usr/lib64/libkrb5.so.3.3 usr/lib64/libkrb5supp
ort.so.0.1 usr/lib64/libparted.so.0.0.1 usr/lib64/libreiserfs-0.3.so.0.0.0 usr/lib64/libsplashycnf.so.1.0.0 usr/lib64/libsplashy.so.1.0.0 usr/lib64/libusb-0.1.so.4
.4.4 usr/lib64/libusb-1.0.so.0.0.0 lib64/libnss_dns-2.11.2.so lib64/libnss_dns.so.2 lib64/libnss_files-2.11.2.so lib64/libnss_files.so.2 lib64/libgcc_s.so.1
37516 blocks
Perl-Bootloader: 2021-05-03 18:57:38 ERROR: UDEVMAPPING: dmdev /dev/dm-0 doesn't have defined DM_NAME in udev
#

DM_NAME中的變數有錯誤udev,但另一方面,會創建新的初始 ramdisk 文件,例如,添加ata_piix明顯有效的文件。我也嘗試過使用不同的根設備(-d選項)來獲取mkinitrdlike sda1

通過重新創建 initrd 文件mkinitrd是正確的做法,只是應該從盡可能接近最終目標作業系統將使用的系統中完成。這是因為在執行mkinitrd它的核心和系統上執行了大量的自動檢測,特別是對於 initrd 文件可用的核心模組。您已經從您的主機作業系統重新創建了 initrd 文件,這顯然與您的舊機器非常不同,因此建構了一個不完整/不一致的 initrd。mkinitrd

在這些情況下,最好的方法通常是從原始發行版的安裝 CD/DVD/ISO引導即將成為目標的機器,因為這些通常具有在這些情況下派上用場的“救援模式”,以重新創建來自那裡的 initrd 文件。在您的情況下,目標作業系統似乎是 openSuSE 11.3,因此您可以獲取它的 ISOqemu ,使用您希望目標作業系統調整到的任何虛擬系統啟動它(-hda或者-device ahci如果您願意,甚至可以使用一些 SCSI/SAS),選擇該 ISO 的第一個引導菜單中可用的“救援系統”選項,登錄root並從那裡執行:

~# mount /dev/sda1 /mnt
~# cd /mnt
/mnt# mount --rbind /dev dev && mount --make-rslave dev
/mnt# mount -t proc proc proc
/mnt# mount -t sysfs sysfs sys
/mnt# chroot .
<chrooted># mkinitrd
...
<chrooted># exit
/mnt# umount dev/pts dev/shm dev proc sys
/mnt# cd ..
/# umount mnt

重新創建 initrd 文件。

使用在真實目標qemu系統上執行的真正原始核心(來自 openSuSE 11.3 的核心)啟動後mkinitrd,沒有選項的簡單核心應該可以正常工作。

當然,在上述操作之後,您將使用相同的虛擬系統但沒有 ISO 映像poweroff重新執行。qemu


完全有可能像您嘗試過的那樣從完全不同的作業系統重新創建 initrd 文件,但是需要準確地知道所有**必需的驅動程序才能覆蓋由mkinitrd.

在您的情況下,我看到您重新創建的 initrd 文件缺少sd_mod實際上提供/dev/sd*磁碟設備所需的驅動程序。它沒有被複製可能是因為您的主機作業系統(您在其上操作以重新創建 initrd 文件)沒有將該驅動程序作為sd_mod.ko可載入模組,而是將其編譯到核心映像本身中。ide-disk.ko這是很有可能的,因為該模組現在已經成為相當預設的模組,而 10年前它根本不是,就像它的 IDE 對應模組(它經常被完全忽略。

因此,您可能只是重複在主機作業系統上執行的相同操作,同時還指定sd_modas ata_piix,您可能已經準備就緒。但是,在這種情況下,例如,如果原始安裝 CD/DVD/ISO 不可用,則更安全的選擇是mkinitrd -A從主機作業系統上的 chrooted 環境內部執行,因為該參數指示mkinitrd簡單地包含所有可能的驅動程序. 當然,這需要更多的磁碟空間來關閉 initrd 文件所在的文件系統,但是一旦啟動到目標作業系統的磁碟,您最終可以使用一個簡單的mkinitrd(即沒有參數)重新創建 initrd,它會重建一個精簡的 initrd 文件對於新的硬體系統。

我的第一個猜測是原始系統中的儲存控制器與 qemu 提供的儲存控制器不同,因此 initrd 文件不包含執行虛擬儲存控制器的正確模組。

的預設儲存控制器qemu-system-x86_64似乎不是 AHCI,而是經典的 Intel PIIX3 IDE 控制器。它需要ata_piix核心模組,這在任何使用 AHCI 作為最低基線的合理現代物理系統的 initrd 中都是不必要的。

結果,核心根本看不到磁碟,引導過程也永遠無法從 initrd 過渡到真正的根文件系統。

GRUB 可以很好地看到磁碟,因為它使用 BIOS 常式來訪問磁碟……而且由於 BIOS 是由 qemu 提供的,因此 BIOS 顯然具有完全適合該工作的常式。

如果您可以訪問虛擬機的命令提示符,請嘗試以下命令:

dmesg | grep -e piix -e ahci -e " sd"

它應該顯示與磁碟檢測相關的任何消息:如果沒有顯示任何內容,那麼您的(虛擬)儲存控制器沒有被檢測到,這使得檢測虛擬磁碟變得不可能。


要修復它,您可能必須訪問正常系統中的磁碟映像:(如果/dev/loop0已在系統中使用,請改用免費循環設備)

losetup -P /dev/loop0 srv.sda

然後安裝/dev/loop0p1到正常系統中合適的臨時位置:

mkdir /mnt/opensuse
mount /dev/loop0p1 /mnt/opensuse

將必要的虛擬文件系統和 chroot 添加到磁碟映像的文件系統中,類似於從實時 Linux 介質引導物理系統時可能執行的操作:

mount --rbind /dev /mnt/opensuse/dev
mount --bind /proc /mnt/opensuse/proc
mount --bind /sys /mnt/opensuse/sys
chroot /mnt/opensuse

現在您應該能夠在磁碟映像中重新創建 initrd/initramfs 文件。您沒有在映像上指定 OpenSUSE 系統的版本,但經典mkinitrd命令可能是要使用的工具 - 或者它實際上dracut可能是新版本可能使用的任何新工具(也許?)的兼容性別名。

無論使用哪個工具在該版本的 OpenSUSE 中創建 initrd 文件,該工具很可能具有強制將特定核心模組包含在 initrd 中的選項。閱讀該工具的手冊頁以找出該選項,並使用它創建一個包含該ata_piix模組的新 initrd。(為了安全起見,先把原來的 initrd 文件移到一邊。)

一旦你在鏡像initrd的正確位置成功創建了一個新文件,在 chroot 環境之外,你之前所做的所有掛載,並使用. 現在您可以嘗試再次啟動映像,希望能夠成功。/boot``exit``umount``losetup -d /dev/loop0

引用自:https://unix.stackexchange.com/questions/646214