Muller's World

Mike Muller's Homepage

2021-08-29 Getting my HP Pavilion to boot in Linux after power-up

I had to replace my desktop computer at the end of last year. I bought an HP Pavilion gaming PC from Walmart cause it was cheap and I was in a hurry.

This was a Windows 10 system that booted with UEFI, a technology I have largely managed to ignore, and I was initially unable to figure out how to get it to boot to Linux. I had simply moved my hard drive from my old system to the new one, and I achieved some degree of success by disabling secure boot in the BIOS and enabling legacy boot, but I couldn't find a way to either disable the UEFI boot or to force legacy boot to happen first. But I seldom reboot, so I punted on the problem.

Of course, when we went on vacation last week there was a power failure due to a storm the day after we left. This took my system down for a week. I came home determined to get it to automatically boot into Linux in this situation. Read on to hear how I ultimately solved the problem.

)

Windows Boot Manager and UEFI

First of all, I had to learn about UEFI. UEFI is the replacement for the old school "master boot record" (MBR) that was executed by the BIOS as the beginning of the boot process. UEFI replaces the MBR with an "EFI partition," which is a FAT partition (FAT12, FAT16 or FAT32) on your hard drive that contains a directory structure that the BIOS can use during startup.

First I had to identify the block device for the built-in solid-state drive:

    $ lsblk
    NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
    sda           8:0    0   3.7T  0 disk
    ├─sda1        8:1    0     1M  0 part
    ├─sda2        8:2    0   3.6T  0 part /
    ├─sda3        8:3    0    16G  0 part [SWAP]
    └─sda4        8:4    0     8G  0 part /boot
    nvme0n1     259:0    0 238.5G  0 disk
    ├─nvme0n1p1 259:1    0   260M  0 part
    ├─nvme0n1p2 259:2    0    16M  0 part
    ├─nvme0n1p3 259:3    0 237.7G  0 part
    └─nvme0n1p4 259:4    0   511M  0 part

The block device for the drive was nvme0n1. Armed with this information, I was able to mount the main Windows 10 drive ("nvme0n1p3") and look at files. "fdisk" revealed even more information:

    $ sudo fdisk /dev/nvme0n1

    Welcome to fdisk (util-linux 2.33.1).
    Changes will remain in memory only, until you decide to write them.
    Be careful before using the write command.


    Command (m for help): p
    Disk /dev/nvme0n1: 238.5 GiB, 256060514304 bytes, 500118192 sectors
    Disk model: SK hynix BC511 HFM256GDJTNI-82A0A
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: gpt
    Disk identifier: 40C6FE39-E4D2-4532-9CDB-47D06A169FB9

    Device             Start       End   Sectors   Size Type
    /dev/nvme0n1p1      2048    534527    532480   260M EFI System
    /dev/nvme0n1p2    534528    567295     32768    16M Microsoft reserved
    /dev/nvme0n1p3    567296 499058687 498491392 237.7G Microsoft basic data
    /dev/nvme0n1p4 499058688 500105215   1046528   511M Windows recovery environment


    Command (m for help):

So the EFI system partition is "nvme0n1p1". This is a normal, mountable FAT partition (FAT32, in my case) and I was able to mount it and examine its contents:

    $ sudo mount /dev/nvme0n1p1 /mnt
    $ ls /mnt
     EFI  'System Volume Information'

The EFI directory is where all the good stuff happens:

    $ ls /mnt/EFI
    Boot  HP  Microsoft

So I figured I'd need to stick some information into that directory (probably a "Linux" subdirectory) to get my drive to be part of the EFI boot-up party, now the only question was what.

Unsurprisingly, the necessary subtree can be installed with "grub-install". For starters, I needed to get another grub package:

    $ sudo apt-get install grub-efi-amd64

grub-install doesn't seem to work directly against an EFI block device, so I had to specify its location on the filesystem:

    $ sudo grub-install --target=x86_64-efi --efi-directory=/mnt

The term "EFI directory" is confusing, it turns out this refers to the directory of the root of the EFI partition, not the EFI directory within that partition.

The EFI directory looked a little different now:

    $ ls /mnt/EFI
    Boot  debian  HP  Microsoft

Having done this, I attempted a reboot and came back up in Windows Boot Manager, "Windows 10" was still listed as the only option, so apparently Windows Boot Manager doesn't just allow you to boot anything that is bootable by UEFI. Ths BIOS also didn't list the new Debian option in the UEFI boot order, so apparently EFI exists in some gray area between the BIOS and the OS specific boot managers.

efibootmgr came to the rescue:

    $ efibootmgr
    BootCurrent: 0006
    Timeout: 0 seconds
    BootOrder: 0000,0006,0001,0005
    Boot0000* Windows Boot Manager
    Boot0001* Hard Drive
    Boot0005* Network Card
    Boot0006* debian

Changing the boot order was straightforward:

    $ sudo efibootmgr --bootorder=0006,0000,0001,0005

After doing this, reboot took me directly into the grub menu (configured to time out into the default Debian install after a few seconds).

The next step was getting the system to start up on a power restore. This was also straightforward once I knew where to look. In the BIOS, under "Configuration", there is an option for something like "State on Power Off". Switching this to "On" had the desired effect.

Mission accomplished. The system will now boot into Linux after power returns.

So at this point, the only thing I'm not sure about is how to boot into Windows. There's probably a way to do so from grub, but in the worst case I suppose I could just use efibootmgr to change the boot order. As I hardly ever boot Windows, this isn't something I care a lot about.