If you recall, when I was initially learning UEFI, I accidentally deleted one of the NVRAM variables from my ThinkPad X1. Ultimately I fixed that by copying the variable from another ThinkPad.
This X1 certainly gets a workout: it's the laboratory on which I experiment, including RC kernels, beta video drivers, alternate backends for Phonon, and anything else I might want to [strike]kill several hours with[/strike] learn something new about. Most recently, that took the form of replacing GRUB with ELILO.
GRUB is a rather complicated beast, what with incorporating its own graphics support, device nomenclature, multibooting every operating system on the planet, and probably a mechanism to repack the drum bearing on my recently kaput clothes dryer. (My icemaker also heaved out its last harvest before screeching to a noisy halt; apparently an electro-mechanical pall has decended on my house: stay away, one and all!). As I have no need for GRUB's sophistication, ELILO's simplicity appealed to me.
After an error-free apt-get install (and a silently failed dpkg-reconfigure), I set about learning how it works. The scripts never seemed to get elilo.conf to configure correctly:
kept whining about some parition "appearing to be mounted." Eh? And when it came time to add ELILO's boot loader entry to the UEFI boot manger with
an error message appeared: something to the extent that the attempt was unsuccessful. Googling on said error didn't reveal much. (I don't remember what it was, now.) I gave up, thinking there was something weird about Ubuntu's ELILO. I double-checked to confirm that GRUB's boot loader was still present; it was. I uninstalled ELILO and then forgot about it.
Earlier this evening, I updated and dist-upgraded the X1 (it's been several days, I was traveling). Included in this batch of upgrades was a newer version of GRUB. As you probably know, of the post-installation script calls update-grub. On a UEFI machine, the script also regenerates the NVRAM variable for the boot loader. The output of this process includes a verbose listing of all NVRAM variables. And while the script ran seemingly without error, I noticed the distinct lack of a very important variable: namely, the one containing the pointer to the GRUB boot loader for my operating system:
So now we have two failures to properly create an NVRAM variable: first when adding a new one that would boot ELILO, and second when replacing an existing one that boots GRUB. Time to investigate the UEFI settings.
I rebooted, pressed [F1], and examined the settings. All looked fine. I chose "Save and exit" from the menu, which would force a rewrite of all current settings, and was greeted with an error that spiked my adrenaline:
No matter what combinations I tried, I was unable to make any changes to my UEFI. And, furthermore, my operating system was invisible because of the missing variable. Something more fundamental than whacked boot loaders had haunted my X1. But what?
[strike]Google[/strike] StartPage found exactly one result when I queried that error message: a fellow Linux-on-UEFI traveler with an X220, seeking help at the Lenovo forum. Following the steps there, I disconnected the CMOS battery, waited a while, then reconnected it. The first reboot threw the expected checksum error; the second reboot returned the machine to its broken state.
Perhaps a fresh UEFI update would fix the problem. Like the writer on the Lenovo forum, I had configured the X1 to boot UEFI only, so the UEFI image extracted from the ISO wouldn't boot: it creates only a DOS-based BIOS-mode flasher. Once more to the CMOS disconnect, and this time, immedately after the checksum error, I changed the UEFI's setting to allow booting both kinds of media. Now my USB would boot, and indeed I successfully flashed an updated UEFI. Changing UEFI settings post-flash threw no errors.
But the OS still wouldn't boot because the NVRAM boot loader variable wasn't there. With a Kubuntu alternate installer USB, I booted into rescue mode, entered into a Linux command shell on the root partition (/dev/sda2), and created the variable:
One more reboot and voi la! The GRUB menu appears. (I have never been so happy to see that thing in my life.)
Now that my UEFI was working, I attempted the GRUB-to-ELILO conversion again. It occurred to me that the weird "appears to be mounted" error might mean I need to unmount the EFI boot partition, so I did:
This time, the ELILO configuration command worked: ELILO's boot loader installed in the appropriate place and an elilo.conf landed next to it. (Oh, and this time the ELILO script wiped out GRUB's boot loader; this matters momentarily.) But now, the kernel wouldn't boot. initrd loaded fine, but vmlinuz threw the X1 into a boot loop every time. The variously-suggested kernel parameter reboot=a,w didn't work for me. So I needed to get back to GRUB.
But wait -- GRUB's boot loader had been deleted. So while the NVRAM variable still existed, it pointed to nothing. Now what? Well, fortunately, in anticipation of such clobbering, I saved a copy of grubx64.efi into a separate subdirectory in the boot partition. So, relatively speaking, this final repair was a cinch. I booted into the EFI shell. With a few simple commands:
And once more GRUB's menu adorns my screen. Whew. Potential disaster #2 averted. (map displays your storage devices; you need to run this to find the name/number of your boot partition. On my X1, that's blk1:) If I had not saved a copy of the boot loader, an alternate approach would be to boot with a Kubuntu rescue USB, drop to a command shell in the root partition, mount the EFI boot partition, and copy /boot/grub/grub.efi to /boot/efi/EFI/ubuntu/grubx64.efi.
My assessment of UEFI is that it's rather delicate at the moment, and prone to rare errors that appear to offer little explanation. But also, if you know what you're dong, UEFI can be repaired. Remember, everything's a file: my actual boot loader (grubx64.efi) never had a problem and never disappeared (except when the ELILO script wiped it out, but that's purely a script issue, not a UEFI malfunction). Once I fixed the UEFI scaffolding, hooking the boot loader back into the boot manager was pretty simple.
I now, by habit, install the EFI shell on every UEFI machine I encounter. I strongly encourage you to do the same.
You will not actually add the EFI shell into your UEFI boot manager. Instead, when you need to boot the shell, press your computer's boot interrupt key, which displays the boot manager menu. In this menu you'll see a list of installed boot loaders ("ubuntu" in the case a a default grub-efi install) and also a list of bootable storage devices. Select the device containing the EFI boot partition. In this case, UEFI will automatically look for any boot loader called \EFI\boot\bootx64.efi and run it. That's why you need to rename the downloaded file. I'd also recommend downloading a copy of the shell command manual.
I know this is a lot of info. This stuff needs to be documented better -- not just the official bits, but also the real-life experiences of people figuring it all out. For now, Kubuntu Forums appears to be an appropriate place for me to chronicle my forays. I hope those of you so inclined to experiment will find my information useful.
This X1 certainly gets a workout: it's the laboratory on which I experiment, including RC kernels, beta video drivers, alternate backends for Phonon, and anything else I might want to [strike]kill several hours with[/strike] learn something new about. Most recently, that took the form of replacing GRUB with ELILO.
GRUB is a rather complicated beast, what with incorporating its own graphics support, device nomenclature, multibooting every operating system on the planet, and probably a mechanism to repack the drum bearing on my recently kaput clothes dryer. (My icemaker also heaved out its last harvest before screeching to a noisy halt; apparently an electro-mechanical pall has decended on my house: stay away, one and all!). As I have no need for GRUB's sophistication, ELILO's simplicity appealed to me.
After an error-free apt-get install (and a silently failed dpkg-reconfigure), I set about learning how it works. The scripts never seemed to get elilo.conf to configure correctly:
Code:
elilo --autoconf --verbose --debug --boot /dev/sda1 --root /dev/sda2
Code:
efibootmgr -v -c -d /dev/sda -p 1 -w -L "Ubuntu-elilo" -l \\EFI\ubuntu\elilo.efi
Earlier this evening, I updated and dist-upgraded the X1 (it's been several days, I was traveling). Included in this batch of upgrades was a newer version of GRUB. As you probably know, of the post-installation script calls update-grub. On a UEFI machine, the script also regenerates the NVRAM variable for the boot loader. The output of this process includes a verbose listing of all NVRAM variables. And while the script ran seemingly without error, I noticed the distinct lack of a very important variable: namely, the one containing the pointer to the GRUB boot loader for my operating system:
Code:
Boot0013* ubuntu HD(1,28,100000,6ead9c9b-5ed2-46a0-80ad-e53905c57b4a)File(\EFI\ubuntu\grubx64.efi)
I rebooted, pressed [F1], and examined the settings. All looked fine. I chose "Save and exit" from the menu, which would force a rewrite of all current settings, and was greeted with an error that spiked my adrenaline:
Code:
Security - Failed to save storage: LocalSecurityVars. Status: 0x9
[strike]Google[/strike] StartPage found exactly one result when I queried that error message: a fellow Linux-on-UEFI traveler with an X220, seeking help at the Lenovo forum. Following the steps there, I disconnected the CMOS battery, waited a while, then reconnected it. The first reboot threw the expected checksum error; the second reboot returned the machine to its broken state.
Perhaps a fresh UEFI update would fix the problem. Like the writer on the Lenovo forum, I had configured the X1 to boot UEFI only, so the UEFI image extracted from the ISO wouldn't boot: it creates only a DOS-based BIOS-mode flasher. Once more to the CMOS disconnect, and this time, immedately after the checksum error, I changed the UEFI's setting to allow booting both kinds of media. Now my USB would boot, and indeed I successfully flashed an updated UEFI. Changing UEFI settings post-flash threw no errors.
But the OS still wouldn't boot because the NVRAM boot loader variable wasn't there. With a Kubuntu alternate installer USB, I booted into rescue mode, entered into a Linux command shell on the root partition (/dev/sda2), and created the variable:
Code:
efibootmgr -v -c -d /dev/sda -p 1 -w -L "ubuntu" -l \\EFI\ubuntu\grubx64.efi
Now that my UEFI was working, I attempted the GRUB-to-ELILO conversion again. It occurred to me that the weird "appears to be mounted" error might mean I need to unmount the EFI boot partition, so I did:
Code:
umount /dev/sda1
But wait -- GRUB's boot loader had been deleted. So while the NVRAM variable still existed, it pointed to nothing. Now what? Well, fortunately, in anticipation of such clobbering, I saved a copy of grubx64.efi into a separate subdirectory in the boot partition. So, relatively speaking, this final repair was a cinch. I booted into the EFI shell. With a few simple commands:
Code:
map blk1: cd \EFI\ubuntu rm * cp \EFI\save\grubx64.efi exit
My assessment of UEFI is that it's rather delicate at the moment, and prone to rare errors that appear to offer little explanation. But also, if you know what you're dong, UEFI can be repaired. Remember, everything's a file: my actual boot loader (grubx64.efi) never had a problem and never disappeared (except when the ELILO script wiped it out, but that's purely a script issue, not a UEFI malfunction). Once I fixed the UEFI scaffolding, hooking the boot loader back into the boot manager was pretty simple.
I now, by habit, install the EFI shell on every UEFI machine I encounter. I strongly encourage you to do the same.
- download the shell from Tianocore's repository
- in your computer's EFI boot partition, create the subdirectory \EFI\boot (this is likely to be mounted to /boot/efi)
- copy the EFI shell binary into this subdirectory, and rename it from Shell_Full.efi to bootx64.efi (the full filespec of this will be /boot/efi/EFI/boot/bootx64.efi -- wordy, but "standard")
You will not actually add the EFI shell into your UEFI boot manager. Instead, when you need to boot the shell, press your computer's boot interrupt key, which displays the boot manager menu. In this menu you'll see a list of installed boot loaders ("ubuntu" in the case a a default grub-efi install) and also a list of bootable storage devices. Select the device containing the EFI boot partition. In this case, UEFI will automatically look for any boot loader called \EFI\boot\bootx64.efi and run it. That's why you need to rename the downloaded file. I'd also recommend downloading a copy of the shell command manual.
I know this is a lot of info. This stuff needs to be documented better -- not just the official bits, but also the real-life experiences of people figuring it all out. For now, Kubuntu Forums appears to be an appropriate place for me to chronicle my forays. I hope those of you so inclined to experiment will find my information useful.
Comment