EFI, Linux and other boot-loading fun | a.k.a. where's my Grub gone

I've been gaming more recently, on hardware that is decent-in-some-contexts-but-definitely-not-in-this-one which has meant pathetic frame rates as low as 7~12FPS as my save files grew bigger. A kind soul took pity on me and installed a better graphics card in my machine while I wasn't looking - which of course is when everything started going wrong.

I'll gloss over the "Not turning on" part because that was due to mislabelled wires - the real problem began when Windows for some reason picked up that something had changed at boot time, and promptly overwrote the boot loader.

Cannot boot from USB keys

None of my LiveUSB sticks would boot.

This turned out to be due to the device (or the system on it?) not being compatible with EFI. I'm not sure how to make a EFI-compatible Live USB system and didn't need to in the end - if you absolutely need to, enabling CSM mode in the BIOS ("Compatibility Support Module") was useful there, but likely wouldn't have helped with fixing my boot-loader. EFI and Legacy OS shouldn't be dual-booted in parallel - you can read more about this at the beginning of that excellent page.

Side-note: "chroot: cannot execute /bin/sh"

That was because the Live USB stick turned out to be a 32 bit system, while my desktop OS is 64 bits.

Where's my EFI partition anyway

I found an old install CD for Debian testing 7.10 (64 bits) lying around that turned out to have a Rescue mode option.

To prepare the system for the chroot that would fix All My Problems, first I had to figure out what was on which partition. The rescue mode let me mount them one by one and take a peek, though using parted would have been much faster.

# parted /dev/sda print
Model: Blah
Disk /dev/sda: 1000GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system     Name                          Flags
 1      1049kB  420MB   419MB   ntfs            Basic data partition          hidden, diag
 2      420MB   735MB   315MB   fat32           EFI system partition          boot, esp
 3      735MB   869MB   134MB                   Microsoft reserved partition  msftres
 4      869MB   247GB   247GB   ntfs            Basic data partition          msftdata
 6      247GB   347GB   100GB   ext4            debian-root                   msftdata
etc etc etc

So my Debian partition is on /dev/sda6, the EFI stuff is on /dev/sda2. I need to make a Debian chroot and reinstall Grub from there - that's the kind of stuff I learnt last time I broke a lot of things.

Let's chroot and grub!

After selecting the "Execute a shell in Installer environment" option:

# mount /dev/sda6 /mnt
# mount -o bind /dev /mnt/dev
# chroot /mnt

Error: update-grub: device node not found

This one I think happened because I only bind mounted /dev, when you also need things like /dev/pts, /sys, /proc.

# for i in /dev /dev/pts /proc /sys ; do mount -o bind $i /mnt$i ; done

Error: grub-install /dev/sda: cannot find EFI directory

That one was before I figured out I also needed to mount the EFI special boot partition - sda2 as shown in the printed output.

# mount /dev/sda2 /mnt/boot/efi

From then on I read about the efibootmgr tool and decided to try and use that instead.

Error: efibootmgr: EFI variables are not supported on this system

Outside the chroot, you need to load the efivars module:

# modprobe efivars

How are things looking by now

# modprobe efivars
# mount /dev/sda6 /mnt
# mount /dev/sda2 /mnt/boot/efi
# for i in /dev /dev/pts /proc /sys ; do mount -o bind $i /mnt$i ; done
# chroot /mnt

Usually I can never remember the mount syntax (does the mount point come first or second?!) but I typed these commands so many times today, I bet I'll remember the syntax for at least a week.

Playing with efibootmgr

I tried to use the following command from the "Managing EFI Boot Loaders for Linux" page but it didn't quite work for me.

# efibootmgr -c -d /dev/sda -p 2 -l \\EFI\\debian\\grubx64.efi -L Linux

While this did add a Linux entry to my F12 BIOS boot menu (yay!), that booted straight into a black screen ("Reboot and Select proper Boot Device or Insert Boot Media" etc etc). Later on I learnt about the efibootmgr --verbose command which shows the difference between the working entry and the non-working one:

# efibootmgr --verbose
Boot0000* debian    HD(2,c8800,96000,0123456789-abcd-1234)File(\EFI\debian\grubx64.efi)
Boot0005  Linux    HD(2,c8800,96000,0123456789-abcd-1234)File(\EFI\redhat\grub.efi)\EFI\debian\grubx64.efi

I'm not quite sure how the path ended up looking like that. It could be a default somewhere, or I'm quite willing to believe I did something wrong - I also made a mistake on the partition number when I first ran the command.

But how did you fix it?!

Despite showing all the options I wanted in the efibootmgr output within the chroot, running grub-install and update-grub multiple times did nothing: I'd still boot straight into Windows or straight into a black screen. The strange thing is that even though only "Windows Boot Manager" and my new "Linux" entry were in the F12 boot menu, the BIOS setup did offer a 'debian' entry (created automatically at install time a long time ago) was in the boot ordering options. Moving it around didn't change a thing though.

The efibootmgr man page talks of a "BootNext" option. With the 'debian' entry right in front of me, why not try it? It's entry Boot0000 on my list, therefore:

# efibootmgr -n 0

Ta-dah! I rebooted straight into Grub then Debian. From there, grub-install /dev/sda and update-grub worked just fine.

Things I still don't know

  • Why did this happen in the first place? Can I prevent it from happening again?
  • I'm not sure why the grub install properly worked that last time. Did I miss something when working from the chroot?
  • Where does the "redhat\grub.efi" line come from, and can I amend that?
  • Why does Windows take so long to restart each time, when I don't even log in?

References

  • Linux on UEFI: A quick installation guide - I found this site incredibly informational.
  • The efibootmgr man page is very nice and contains useful examples.
  • GrubEFIReinstall - I probably would have tried that tool at some point. I postponed because I didn't have an easy way to burn a CD and wasn't sure about how to boot from USB without enabling CSM.
  • Booting with EFI, a blog entry about fallback boot loaders. While this didn't help in my case, I found the article very clear and enjoyed getting an explanation of the context around the problem in addition to the solution.

Punch line: the graphics card wasn't the bottle neck and my frame rate still hovers around 9FPS.

links

social