Announcement

Collapse
No announcement yet.

My UEFI fright: did I bork my X1? Part deux

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    My UEFI fright: did I bork my X1? Part deux

    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:
    Code:
    elilo --autoconf --verbose --debug --boot /dev/sda1 --root /dev/sda2
    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
    Code:
    efibootmgr -v -c -d /dev/sda -p 1 -w -L "Ubuntu-elilo" -l \\EFI\ubuntu\elilo.efi
    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:
    Code:
    Boot0013* ubuntu  HD(1,28,100000,6ead9c9b-5ed2-46a0-80ad-e53905c57b4a)File(\EFI\ubuntu\grubx64.efi)
    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:
    Code:
    Security - Failed to save storage: LocalSecurityVars. Status: 0x9
    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:
    Code:
    efibootmgr -v -c -d /dev/sda -p 1 -w -L "ubuntu" -l \\EFI\ubuntu\grubx64.efi
    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:
    Code:
    umount /dev/sda1
    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:
    Code:
    map
    blk1:
    cd \EFI\ubuntu
    rm *
    cp \EFI\save\grubx64.efi
    exit
    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.
    1. download the shell from Tianocore's repository
    2. in your computer's EFI boot partition, create the subdirectory \EFI\boot (this is likely to be mounted to /boot/efi)
    3. 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.

    #2
    Very nice -- thanks Steve. Next computer I build, this is gonna be important to review and apply.

    Comment


      #3
      I don't have any EUFI computers to play with, but why are you installing the boot loader to a partition and not to the drive? /dev/sda instead of /dev/sda2?

      Comment


        #4
        Traditionally, BIOS-based machines with MBR-style drives reserve the first 512 bytes to store a very basic bootstrap loader and a partition table. The first 440 bytes constitute the bootstrap loader. Well, 440 bytes isn't a lot of space; the BIOS/MBR bootstrap loader searches for the one partition marked active and passes control to a more sophisticated second-stage boot loader located in that partition. Examples of such boot loaders include GRUB, (E)LILO, and Syslinux for Linux; BOOTMGR and NTLDR for Windows.

        On BIOS/MBR Linux machines, GRUB is typcially installed to a drive, as you mention. The installer places GRUB's bootstrap loader into the 440-byte portion of the MBR; this bit of code is actually just some instructions that point the BIOS to the partition containing the second-stage GRUB boot loader.

        UEFI behaves differently. GPT-style disks don't have active flags. Instead, the UEFI looks for the first FAT16/32 partition it can find with the code EF00 -- "EFI System". Here's my GPT layout:
        Code:
        steve@x1:~$ [B]sudo gdisk -l /dev/sda[/B]
        GPT fdisk (gdisk) version 0.8.1
        
        Partition table scan:
          MBR: protective
          BSD: not present
          APM: not present
          GPT: present
        
        Found valid GPT with protective MBR; using GPT.
        Disk /dev/sda: 250069680 sectors, 119.2 GiB
        Logical sector size: 512 bytes
        Disk identifier (GUID): C803B5C9-5912-4046-9F23-E39B626CEEFC
        Partition table holds up to 128 entries
        First usable sector is 34, last usable sector is 250069646
        Partitions will be aligned on 8-sector boundaries
        Total free space is 13 sectors (6.5 KiB)
        
        Number  Start (sector)    End (sector)  Size       Code  Name
           1              40         1048615   512.0 MiB   EF00  
           2         1048616        63963175   30.0 GiB    8300  
           3        63963176       231735335   80.0 GiB    8300  
           4       231735336       250069639   8.7 GiB     8200
        You'll note that my EFI system partition is 512 MiB. This is larger than it has to be, but I made it this big with the anticipation that I'd be conducting a variety of experiments.

        To continue... When UEFI boots, it consults an NVRAM variable called BootOrder, which contains an ordered list of boot loaders installed in the EFI system partition. It will then automatically boot the first loader in the list for which it can find the corresponding boot loader. If you want to interrupt this, you have to press your system's boot interrupt key. This brings up the UEFI boot manager, which displays available UEFI applications and all discovered boot loaders.

        This flexibility leads to a bit more complication when configuring the boot manager and installing boot loaders. Boot loaders must be placed into the EFI system partition on the drive containing that partition. So the installation command must specify all these components. Let's dissect one example:
        Code:
        efibootmgr -v -c -d /dev/sda -p 1 -w -L "ubuntu" -l \\EFI\ubuntu\grubx64.efi
        -v : be verbose while doing the work
        -c : create a new NVRAM variable pointing to the boot loader
        -d : the disk containing the EFI system partition
        -p : the partition number of the EFI system partition
        -w : write a disk signature to the MBR (GPT disks maintain a "protective" MBR)
        -L : the name that will be displayed in the EFI boot manager
        -l : the location of the boot loader

        In my case, /dev/sda1 is my EFI system partition. This partition contains a single directory, EFI. Within this directory are two subdirectories, each one containing a boot loader:
        * /EFI/ubuntu/grubx64.efi for GRUB
        * /EFI/boot/bootx64.efi for the EFI shell

        Here is the verbose output of Ubuntu's EFI boot manager utility:
        Code:
        steve@x1:~$ [B]sudo efibootmgr -v[/B]
        BootCurrent: 0013
        Timeout: 0 seconds
        BootOrder: 0013,0006,0007,000A,0009,000C,0008,000D
        Boot0000  Setup
        Boot0001  Boot Menu
        Boot0002  Diagnostic Splash Screen
        Boot0003  Startup Interrupt Menu
        Boot0004  ME Configuration Menu
        Boot0005  Rescue and Recovery
        Boot0006* USB CD        030a2400d23878bc820f604d8316c068ee79d25b86701296aa5a7848b66cd49dd3ba6a55
        Boot0007* USB FDD       030a2400d23878bc820f604d8316c068ee79d25b6ff015a28830b543a8b8641009461e49
        Boot0008* ATA HDD2      030a2500d23878bc820f604d8316c068ee79d25b91af625956449f41a7b91f4f892ab0f602
        Boot0009* ATA HDD0      030a2500d23878bc820f604d8316c068ee79d25b91af625956449f41a7b91f4f892ab0f600
        Boot000A* USB HDD       030a2400d23878bc820f604d8316c068ee79d25b33e821aaaf33bc4789bd419f88c50803
        Boot000B* PCI LAN       030a2400d23878bc820f604d8316c068ee79d25b78a84aaf2b2afc4ea79cf5cc8f3d3803
        Boot000C* ATAPI CD1     030a2500d23878bc820f604d8316c068ee79d25baea2090adfde214e8b3a5e471856a35403
        Boot000D* ATA HDD3      030a2500d23878bc820f604d8316c068ee79d25b91af625956449f41a7b91f4f892ab0f603
        Boot000E* IDER BOOT CDROM       ACPI(a0341d0,0)PCI(16,2)ATAPI(0,1,0)
        Boot000F* IDER BOOT Floppy      ACPI(a0341d0,0)PCI(16,2)ATAPI(0,0,0)
        Boot0010* ATA HDD       030a2400d23878bc820f604d8316c068ee79d25b91af625956449f41a7b91f4f892ab0f6
        Boot0011* ATAPI CD:     030a2400d23878bc820f604d8316c068ee79d25baea2090adfde214e8b3a5e471856a354
        Boot0012* PCI LAN       030a2400d23878bc820f604d8316c068ee79d25b78a84aaf2b2afc4ea79cf5cc8f3d3803
        Boot0013* ubuntu        HD(1,28,100000,6ead9c9b-5ed2-46a0-80ad-e53905c57b4a)File(\EFI\ubuntu\grubx64.efi)
        When I boot my computer normally, UEFI first consults the variable BootOrder. The first item in the list is Boot0013. UEFI reads the variable and searches the EFI system partition for the named boot loader, which here is \EFI\ubuntu\grubx64.efi. It finds the boot loader, sets the variable BootCurrent, and finally begins executing the boot loader's code -- which here is the second-stage loader for GRUB-EFI.

        BIOS/MBR are old and hobbled with lots of design assumptions: limits on numbers of partitions, sizes of disks, and the notion that only one operating system would be installed. Various modifications over the years have allowed for extended partitions to overcome the limit of 4 physical partitions, logical block addressing and larger sector numbers to overcome disk size limits, and various boot managers to provide a mechanism to chain-load multiple second-stage boot loaders. This is really quite crufty and rather arbitrary, but it does have the benefit of being familiar.

        UEFI/GPT eliminate these constraints. The tradeoff is that it takes something approaching a small operating system to do so, which creates something of a technical learning curve, portions of which require more crispness with vocabulary (the differences between bootstrap loader, boot loader, and boot manager, for example) and certain changes of habit.

        Comment


          #5
          My education continues.:cool:

          Comment


            #6
            Awesome. I ask again... are you SURE you only picked up Linux two years ago? :eek: 8)
            My friend, I am not anywhere near your league! I feel like Salieri, able to recognize genius when I see it but never able to match it.

            I had never heard of gdisk so I installed and ran it on this Acer 7739 out of curiosity:
            sudo gdisk -l /dev/sda
            GPT fdisk (gdisk) version 0.8.1


            Partition table scan:
            MBR: MBR only
            BSD: not present
            APM: not present
            GPT: not present




            ************************************************** *************
            Found invalid GPT and valid MBR; converting MBR to GPT format.
            ************************************************** *************


            Disk /dev/sda: 1250263728 sectors, 596.2 GiB
            Logical sector size: 512 bytes
            Disk identifier (GUID): 9BCCAA6D-F47F-4179-9A6A-399B8665A001
            Partition table holds up to 128 entries
            First usable sector is 34, last usable sector is 1250263694
            Partitions will be aligned on 2048-sector boundaries
            Total free space is 8125 sectors (4.0 MiB)


            Number Start (sector) End (sector) Size Code Name
            1 2048 31459327 15.0 GiB 2700 Windows RE
            2 31459328 31664127 100.0 MiB 0700 Microsoft basic data
            3 31664128 662825647 301.0 GiB 0700 Microsoft basic data
            5 662827008 1246357503 278.2 GiB 8300 Linux filesystem
            6 1246359552 1250260991 1.9 GiB 8200 Linux swap

            "A nation that is afraid to let its people judge the truth and falsehood in an open market is a nation that is afraid of its people.”
            – John F. Kennedy, February 26, 1962.

            Comment


              #7
              Originally posted by GreyGeek View Post
              Awesome. I ask again... are you SURE you only picked up Linux two years ago? :eek: 8)
              Never saw it before 9 May 2009. Haven't looked back since. So I guess I'm up to three years now

              Originally posted by GreyGeek View Post
              My friend, I am not anywhere near your league! I feel like Salieri, able to recognize genius when I see it but never able to match it.
              *blush* You're too kind.

              Originally posted by GreyGeek View Post
              I had never heard of gdisk so I installed and ran it on this Acer 7739 out of curiosity:
              gdisk is the fdisk-equivalent tool for managing partitions on GPT-style disks.

              Comment


                #8
                Vary nice write up (thank you @SteveRiley )........bookmarking it for when I ever run into one of these UEFI systems.

                VINNY
                i7 4core HT 8MB L3 2.9GHz
                16GB RAM
                Nvidia GTX 860M 4GB RAM 1152 cuda cores

                Comment

                Working...
                X