Boot from grub in CentOS 7

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.

References

CHAPTER 26. WORKING WITH GRUB 2

Classic SysAdmin: How to Rescue a Non-booting GRUB 2 on Linux

error: cant’t find command linux when booting system