After my CentOS 7 upgrade, I rebooted it. It gets stuck and shows a prompt like this:
grub >
It is an annoying start.
Firstly, I tried typing load_env
to check the grub env, and it told me can not find env file from /EFI/redhat/grubenv
. I guess I found the root cause.
Since CentOS is recompiled from RHEL, there are 3 directories in /boot/efi/EFI
: BOOT
, redhat
, and centos
.
Here is an example file tree:
. └── EFI ├── BOOT │ ├── BOOTX64.EFI │ └── fbx64.efi ├── centos │ ├── grub.cfg │ └── grubenv └── redhat ├── BOOT.CSV ├── BOOTX64.CSV ├── fonts │ └── unicode.pf2 ├── grubx64.efi ├── mmx64.efi ├── shim.efi ├── shimx64.efi └── shimx64-redhat.efi
After upgrading the kernel, some scripts may regenerate the grub config file, (please follow this link for more detail.) and finally due to some issues, grub cannot find the files grub.cfg
and grubenv
in the redhat
folder.
If we had BusyBox or LiveCD, things would be very simple. We can boot from that OS, mount the folder, and copy the files to the correct path:
. └── EFI ├── BOOT │ ├── BOOTX64.EFI │ └── fbx64.efi ├── centos │ ├── grub.cfg │ └── grubenv └── redhat ├── BOOT.CSV ├── BOOTX64.CSV ├── fonts │ └── unicode.pf2 ├── grub.cfg # copied from centos ├── grubenv # copied from centos ├── grubx64.efi ├── mmx64.efi ├── shim.efi ├── shimx64.efi └── shimx64-redhat.efi
However, I have neither.
Then I try to boot myself from the grub command line.
> linux (hd1,gpt2)/vmlinuz-0-rescue-xxx > initrd (hd1,gpt2)/initramfs-0-rescue-xxx.img
But it doesn't work.
> linux (hd1,gpt2)/vmlinuz-0-rescue-xxx error: cant't find command linux
According to this Q&A, I replaced the linux
to linuxefi
and initrd
to initrdefi
. And try again:
> linuxefi (hd1,gpt2)/vmlinuz-0-rescue-xxx > initrdefi (hd1,gpt2)/initramfs-0-rescue-xxx.img
It starts but stops at 'switch root'. This is because we did not pass the root
parameter correctly. It should probably be something like /dev/sda1
, which is a device label. Since I am using an LVM to manage the devices, this is too complicated for me.
However, I am still in a nice environment with some basic functionality.
I mounted my devices and copied grub.cfg
and grubenv
to the correct path and then rebooted the system.
It works.
Conclusion
Booting from grub using the keyboard is not easy, as the full correct command is:
load_video set gfxpayload=keep insmod gzio insmod part_gpt insmod ext2 set root='hd1,gpt2' search --no-floppy --fs-uuid --set=root --hint-bios=hd1,gpt2 --hint-efi=hd1,gpt2 --hint-baremetal=ahci1,gpt2 xxxx-xxxx-xxxx-xxxx-xxxxxxx linuxefi /vmlinuz-xxxx root=/dev/mapper/xxxx ro crashkernel=auto spectre_v2=retpoline rd.lvm.lv=xxxx/xxxx rhgb quiet LANG=en_US.UTF-8 initrdefi /initramfs-xxxx.x86_64.img
It's a horrible sequence.
As for us, the easiest way is to just boot a minimal system, correct the problem, then reboot and let it continue to work.