Skip to content

Add support for UEFI installations #53

Merged
merged 7 commits into from
Sep 7, 2018

Conversation

pmenzel
Copy link
Contributor

@pmenzel pmenzel commented Aug 30, 2018

Now, on a UEFI system, the output looks like below.

$ sudo ./mxgrub mariux-4.14.67-217
/boot/grub/grub.cfg: updated
mount -L ESP /boot/efi
grub-install --target=x86_64-efi /dev/nvme0n1
Installing for x86_64-efi platform.
Installation finished. No error reported.
umount /boot/efi
GRUB is already installed in MBR.
grub-editenv - set chosen=all-other-kernel>mariux-4.14.67-217

@wwwutz
Copy link
Contributor

wwwutz commented Aug 30, 2018

Just for my innocent mind... Are we going to install standard MarIuX systems so it will boot from UEFI ? So we have System disks with UEFI and others with Legacy ?

Sounds like a boy group to me... "Wrong Direction".

@donald
Copy link
Collaborator

donald commented Aug 30, 2018

  • Is /boot/efi supposed to be the mounted FAT32 EFI system partition? And therefore not disted?
  • Does sys 'grub-install','--target=x86_64-efi',$root_disk write a GRUB MBR? Although an UEFI boot doesn't read it?
  • Does /boot/grub differ depending on whether the --target=x86_64-efi is being given to grub-install? Currently /boot/grub is disted, so this would be a problem.
  • Can we make mxgrub install always install /boot/efi and MBR (and - although disted - /boot/grub) . To my (wrong?) understanding the switch, how we boot, is in the firmware. Can we have a system disk which can take any kind of boot? .

@donald
Copy link
Collaborator

donald commented Sep 3, 2018

Do we need to depend sys 'grub-install','--target=x86_64-efi',$root_disk and exit 1; on is_efi ? Maybe we should use "if there is a UEFI partition" instead. Maybe we should mount it (if not already mounted) and dismount if (if we mounted it).

@pmenzel pmenzel force-pushed the add-support-for-uefi-installations branch from 234a49d to e87196b Compare September 3, 2018 11:01
@pmenzel
Copy link
Contributor Author

pmenzel commented Sep 3, 2018 via email

@pmenzel pmenzel force-pushed the add-support-for-uefi-installations branch from e87196b to 35bc97d Compare September 3, 2018 11:16
@pmenzel
Copy link
Contributor Author

pmenzel commented Sep 3, 2018 via email

@pmenzel pmenzel force-pushed the add-support-for-uefi-installations branch from 35bc97d to 72bdd99 Compare September 3, 2018 12:05
@donald
Copy link
Collaborator

donald commented Sep 4, 2018

Suggestion: Instead of is_efi ( = -d '/sys/firmware/efi') use have_ESP ( = !system "blkid -L ESP>/dev/null" ) ?

@pmenzel
Copy link
Contributor Author

pmenzel commented Sep 4, 2018 via email

@donald
Copy link
Collaborator

donald commented Sep 4, 2018

The intended advantage is, that I'd install the bootcode into the ESP partition (if available on the target disk) and into the MBR and between the partitions (if available on the target disk) no matter how my system booted.

blkid --probe --match-token PART_ENTRY_TYPE="0xef"  $device

might be correct.

@pmenzel
Copy link
Contributor Author

pmenzel commented Sep 4, 2018 via email

@donald
Copy link
Collaborator

donald commented Sep 5, 2018

works for me (not UEFI bootet) :

root@theinternet:~/git/mariuxinstaller (add-uefi-support)# rm -r /scratch/local2/test.dat
rm: cannot remove ‘/scratch/local2/test.dat’: No such file or directory
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# truncate -s500G /scratch/local2/test.dat
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# loop=$(losetup -f --show -- /scratch/local2/test.dat)
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# ./mxpartit ${loop#/dev/}           # from add-uefi-support branch
[mxpartit INFO] Device: loop0
[mxpartit INFO]  size=1048576000 512 byte blocks / 500GiB
[mxpartit INFO]  hwsectorsize=512 bytes (using: 512 bytes )
[mxpartit INFO]  root: size=274877906944 bytes (256 GiB) (536870912 sectors)
[mxpartit INFO]  data: size=261858787328 bytes (243 GiB) (511442944 sectors)
[mxpartit INFO]  ESP: size=134217728 bytes ( GiB) (262144 sectors)
[mxpartit INFO] partitioning disk loop0 using sfdisk ..
Creating new GPT entries.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
GPT data structures destroyed! You may now partition the disk using fdisk or
other utilities.
Disk /dev/loop0: 500 GiB, 536870912000 bytes, 1048576000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

>>> Created a new DOS disklabel with disk identifier 0xfa86a495.
/dev/loop0p1: Created a new partition 1 of type 'Linux' and of size 256 GiB.
/dev/loop0p2: Created a new partition 2 of type 'Linux' and of size 243.9 GiB.
/dev/loop0p3: Created a new partition 3 of type 'EFI (FAT-12/16/32)' and of size 127 MiB.
/dev/loop0p4: Done.

New situation:
Disklabel type: dos
Disk identifier: 0xfa86a495

Device       Boot      Start        End   Sectors   Size Id Type
/dev/loop0p1 *          2048  536872959 536870912   256G 83 Linux
/dev/loop0p2       536872960 1048313855 511440896 243.9G 83 Linux
/dev/loop0p3      1048313856 1048573951    260096   127M ef EFI (FAT-12/16/32)

The partition table has been altered.
Calling ioctl() to re-read partition table.
Re-reading the partition table failed.: Invalid argument
The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8).
Syncing disks.
[mxpartit INFO] reloading partition table of loop0 using partprobe ..
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# mkfs.vfat -F32 -n ESP ${loop}p3
mkfs.fat 3.0.26 (2014-03-07)
unable to get drive geometry, using default 255/63
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# mkfs.xfs -f -L root ${loop}p1
meta-data=/dev/loop0p1           isize=512    agcount=4, agsize=16777216 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=0, rmapbt=0, reflink=0
data     =                       bsize=4096   blocks=67108864, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=32768, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# mkdir -p /mnt/x/
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# mount ${loop}p1 /mnt/x
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# mkdir -p /mnt/x/boot/efi
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# mount ${loop}p3 /mnt/x/boot/efi
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# grub-install --target=x86_64-efi --boot-directory=/mnt/x/boot $loop
Installing for x86_64-efi platform.
Installation finished. No error reported.
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# umount /mnt/x/boot/efi /mnt/x
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# losetup -d $loop
root@theinternet:~/git/mariuxinstaller (add-uefi-support)# rm -r /scratch/local2/test.dat

@pmenzel
Copy link
Contributor Author

pmenzel commented Sep 5, 2018

I guess, the is_efi() check can be removed, and we just handle sys 'mount','-L','ESP','/boot/efi' and exit 1; and the umount gracefully.

@donald
Copy link
Collaborator

donald commented Sep 5, 2018

Yes. Another idea might be to not immediately exit 1if MBR or EFI install failes, but attempt both in any case (and then exit 1 if either failed). So if MBR or EFI install is prevented by bad partiton layout, we'd ar least have the other boot option available.

If you want, I can take over and code this. I mean its perl. For people from the vaults.

@pmenzel
Copy link
Contributor Author

pmenzel commented Sep 6, 2018 via email

Instead of always mounting the EFI System Partition (ESP), only mount it
when checking if GRUB is installed.

The mount point `/boot/efi` was created on the distmaster.
As that’s the common case, maybe it’s just spam, and should be a verbose
option.
Contradicting the documentation, that `i386-pc` is the default target,
on UEFI systems it is not.

    $ sudo grub-install --boot-directory=/boot /dev/nvme0n1
    Installing for x86_64-efi platform.
    grub-install: error: cannot find EFI directory.

So, pass `--target=i386-pc` to install GRUB in the MBR.

    $ sudo grub-install --target=i386-pc --boot-directory=/boot /dev/nvme0n1
    Installing for i386-pc platform.
    Installation finished. No error reported.
@pmenzel pmenzel force-pushed the add-support-for-uefi-installations branch from 72bdd99 to 7a21fb7 Compare September 6, 2018 10:50
@pmenzel
Copy link
Contributor Author

pmenzel commented Sep 6, 2018

Thank you for the review. I’ll introduced has_esp(), and use that to hopefully avoid error messages on the console.

There is one drawback with efibootmgr, which is called by grub-install, and fails if the system is not booted with UEFI. @donald wants to not have it run by grub-install, and I’ll try to add a switch there. But, it’s not a showstopper in my opinion.

@pmenzel
Copy link
Contributor Author

pmenzel commented Sep 6, 2018

Looks like the switch no-nvram will skip executing efibootmgr.

[…]
    case OPTION_NO_NVRAM:
      update_nvram = 0;
      return 0;
[…]
      if (!removable && update_nvram)
        {
          char * efifile_path;
          char * part;
          int ret;

          /* Try to make this image bootable using the EFI Boot Manager, if available.  */
          if (!efi_distributor || efi_distributor[0] == '\0')
            grub_util_error ("%s", _("EFI bootloader id isn't specified."));
          efifile_path = xasprintf ("\\EFI\\%s\\%s",
                                    efi_distributor,
                                    efi_file);
          part = (efidir_grub_dev->disk->partition
                  ? grub_partition_get_name (efidir_grub_dev->disk->partition)
                  : 0);
          grub_util_info ("Registering with EFI: distributor = `%s',"
                          " path = `%s', ESP at %s%s%s",
                          efi_distributor, efifile_path,
                          efidir_grub_dev->disk->name,
                          (part ? ",": ""), (part ? : ""));
          grub_free (part);
          ret = grub_install_register_efi (efidir_grub_dev,
                                           efifile_path, efi_distributor);
          if (ret)
            grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
                             strerror (ret));
        }
[…]

In case a drive with an EFI System Partition (ESP) is put into a system
that boots in legacy mode, running `grub-install --target=x86_64-efi`
will fail, as `efibootmgr` fails to update the NVRAM. Therefore, pass
`--no-nvram` to `grub-install`, which skip running efibootmgr.

    --no-nvram             don't update the `boot-device'/`Boot*' NVRAM
                           variables. This option is only available on EFI
                           and IEEE1275 targets.

As a downside, the administrator needs to go int the firmware menu, and add the
entry in the boot manager manually.
With a system booted from UEFI, starting the Linux kernel from GRUB,
GRUB outputs

    error: not suitable video mode found
    booting in blind mode

and no Linux messages can be seen.

Jordan_U’s answer from #grub@irc.freenode.net:

> Are you using a manually written grub.cfg or one made by
> grub-mkconfig?
>
> If the former, add "insmod all_video" to your grub.cfg. That will
> allow grub to set up a video mode to then pass on to linux. IIRC, the
> text mode for UEFI is only intended for use by bootloaders, and thus
> should not be used by linux. I think that means that if grub doesn't
> pass a video mode to linux (which it needs video modules to be able to
> do) then you won't get early printk from the kernel, messages will
> only be displayed once native graphics drivers and KMS kicks in.
@pmenzel pmenzel force-pushed the add-support-for-uefi-installations branch from 7a21fb7 to e78c67f Compare September 6, 2018 14:13
@pmenzel
Copy link
Contributor Author

pmenzel commented Sep 6, 2018

I added the switch. (Just for your interest, there is also --no-bootsector for the legacy case.)

@donald donald merged commit 38fb40b into master Sep 7, 2018
Sign in to join this conversation on GitHub.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants