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.