1

During the installation of Parrot on a VirtualBox machine, I manually created a 32 MiB partition (since I don't intend to multi-boot or upgrade the VM, that's way more than enough for the single OS) to be used as the EFI system partition and formatted it as FAT32 with the boot flag set. But it is not recognized (displayed/accessible) as a bootable (FS*, e.g. FS0) device by the UEFI.

The partition has the correct EFI system partition type GUID:

# fdisk -x /dev/sda
Disk /dev/sda: 64 GiB, 68719476736 bytes, 134217728 sectors
Disk model: VBOX HARDDISK   
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: 503DB523-B5BE-6141-AC9A-20EBB03A1F51
First LBA: 2048
Last LBA: 134217694
Alternative LBA: 134217727
Partition entries LBA: 2
Allocated partition entries: 128

Device     Start       End   Sectors Type-UUID                            UUID                                 Name Attrs
/dev/sda1   2048     67583     65536 C12A7328-F81F-11D2-BA4B-00A0C93EC93B 9C0E08DE-D160-314E-8BB2-F9AC2D5E4243      RequiredPartition
/dev/sda2  67584 134206976 134139393 0FC63DAF-8483-4772-8E79-3D69D8477DE4 24F77F2E-EFC0-E040-96F8-054E9D2BD063      RequiredPartition

UEFI is not able to boot the OS, it just fails to UEFI Shell, where the partition shows up as a BLK* device, but has no FS* mapping. Therefore none of the common suggestions of "run FS0:\EFI\boot\bootx64.efi" (and variants) are applicable.

UEFI shell screenshot

Going to the UEFI boot menu and manually selecting the configured entry corresponding to an EFI file in the partition only flashes a black screen, switching the video mode for a split second, and then returns back to the menu.

UEFI boot menu screenshot

2
  • the smallest FAT32 partition on a 512-byte-sector disk is slightly larger than 32 MiB, so make it 33 MiB
    – phuclv
    Commented Apr 27, 2022 at 2:30
  • @phuclv Or make it FAT other than FAT32. Yes.
    – antichris
    Commented Apr 27, 2022 at 6:43

2 Answers 2

1

For the partition to be recognized as an EFI partition:

  • For GPT disks, the partition-type should be set to the GUID C12A7328-F81F-11D2-BA4B-00A0C93EC93B

  • For MBR disks, the partition type ID should be set to EF.

See EFI system partition.

3
  • I've yet to see any UEFI implementation that actually cares about partition type. In reality they just probe every partition on a drive for filesystem "magics" that it recognizes.
    – Tom Yan
    Commented Apr 27, 2022 at 10:53
  • @TomYan: What kind of magics?
    – harrymc
    Commented Apr 27, 2022 at 14:07
  • None at all really, the only "universal" behavior is that `\EFI\BOOT` should be checked. Definitively from a marked EFI System Partition if it exits, but otherwise UEFI implementations can also support parsing any other one with the proper file system as noted above and elsewhere (how the logic should work here or when multiple ESPs are present, is left undefined though). Btw having the right GUID set is still pretty useful for OS-side auto-discovery.
    – mirh
    Commented Oct 7, 2022 at 13:44
1

Solution

Format the EFI system partition as FAT16.

  • Partitions up to 16 MiB should be formatted as FAT12.
  • Partitions in the range of 16-32 MiB (inclusive) should be formatted as FAT16.
  • For anything larger than 32 MiB — FAT32 is recommended. Although, technically, FAT16 supports volume sizes up to 2 GB (or even more, on specific OS'es).

Note, that since of all the three flavors of FAT the UEFI specification only requires FAT32 for system partitions, some tools choose not to support FAT12 partitions (<16 MiB). So things might not work with a partition that's smaller than 16 MiB, and you may not be able to, for example, install GRUB (the version of Calamares used by Parrot at the time of writing has this exact problem).

Script

Of the following only the archive creation and the partition inspection (lsblk and partprobe) operations can be performed by an unprivileged user, so you'd be better off if you could just run all of this in a root shell.

#!/bin/sh

ESP=/dev/sda1                    ## EFI system partition (ESP).
ROOT=/dev/sda2                   ## The partition of the root file system.
MNT=$(mktemp -d --suffix=-mnt)   ## Mount point path.
TGZ=$(mktemp --suffix=-eps.tgz)  ## ESP backup archive.
FSTAB=$MNT/etc/fstab             ## The`fstab` of the root file system.
(
    set -e  ## Abort on error.

    mount $ESP "$MNT"                             ## (2.1)
    (cd "$MNT" && tar -czf "$TGZ" *)              ## (2.2)
    umount "$MNT"                                 ## (2.3)

    OLD=$(lsblk -no UUID $ESP)                    ## (3.1)
    mkfs.vfat -F 16 $ESP                          ## (3.2)
    partprobe $ESP                                ## (3.3)
    NEW=$(lsblk -no UUID $ESP)                    ## (3.4)

    mount $ROOT "$MNT"                            ## (4.1)
    sed -Ei'' "s/^(UUID)=$OLD/\1=$NEW/" "$FSTAB"  ## (4.2)
    umount "$MNT"                                 ## (4.3)

    mount $ESP "$MNT"                             ## (5.1)
    tar -C "$MNT" -xf "$TGZ"                      ## (5.2)
    umount "$MNT"                                 ## (5.3)

    TYPE=$(lsblk -no PARTTYPENAME $ESP)  ## Partition type name.
    if [ "$TYPE" != "EFI System" ]; then          ## (6.1)
        DEV=${ESP%%[0-9]*}
        parted $DEV set ${ESP#$DEV} esp on        ## (6.2)
    fi
)

Unlike the other variables that we can be sure are safe, MNT, TGZ and FSTAB have been quoted here because there is a chance, however slim, that the generated temporary names could contain characters that could break command invocations.

Steps in detail

  1. Boot the system from a Live CD/DVD/USB that has the mkfs.vfat utility (the one you installed from should do).

  2. Back up the contents of the EFI system partition.

    1. Mount the partition.

      We're using a temporary directory here, but you could use, e.g., /mnt (unless it is already being used by something else — check first).

    2. Archive its contents to a gzipped TAR archive.

      You could just as well copy all of it to some local directory, but archiving is safer.

    3. Unmount the partition.

  3. Format the file system of ESP as FAT16.

    1. Back up the current file system UUID of the ESP.

      You can skip this if you intend to perform the upcoming step 4.2 manually.

    2. Use mkfs.vfat to format the partition.

      If your ESP is smaller than 16 MiB, you should format it as FAT12 by passing 12 as the -F parameter instead.

      This changes the file system UUID for the partition.

    3. Ensure the operating system registers the above changes.

    4. Get the new file system UUID for ESP.

      To simplify the upcoming step 4.2, we're assigning it to a shell variable here, but you can also view the value by executing

      lsblk -o UUID $ESP
      
  4. Update /etc/fstab in the root partition with the new UUID

    1. Mount the root partition.

    2. Replace the old UUID in the root partition's /etc/fstab with the new value.

      Alternatively, you could edit the fstab file and replace the value manually.

    3. Unmount the partition.

  5. Restore the backed-up ESP contents.

    1. Mount the ESP again.

    2. Extract the archived contents.

    3. Unmount the partition.

  6. Ensure that the ESP actually has the correct partition type.

    1. Check if the partition type name matches EFI System.

      Alternatively, you could compare c12a7328-f81f-11d2-ba4b-00a0c93ec93b with what is returned by

      lsblk -no PARTTYPE $ESP
      

      Either way, the next step is not necessary if we get a match here.

    2. Use parted to set the partition type (if necessary).

      We're using crude shell pattern matching to separate the device name (e.g. /dev/sda) and the partition number (e.g. 1) when calling parted, since that is the argument format it requires.

Verify

You could (and probably, should) verify that the partition has the valid format and type now by running lsblk:

$ lsblk -o PATH,FSTYPE,FSVER,PARTTYPE,PARTTYPENAME $ESP
PATH      FSTYPE FSVER PARTTYPE                             PARTTYPENAME
/dev/sda1 vfat   FAT16 c12a7328-f81f-11d2-ba4b-00a0c93ec93b EFI System

You should be seeing FAT12 in that output, if that is what you were aiming for instead of FAT16.

Reboot

UEFI should be able to recognize the partition and successfully boot the system now.

6
  • how does this answer the question?
    – phuclv
    Commented Apr 27, 2022 at 2:26
  • @phuclv By the very first sentence, rather directly. Is there something you can't understand? There's probably always room for improvement: I'm open to suggestions.
    – antichris
    Commented Apr 27, 2022 at 6:50
  • Unless your BIOS is non-standard, FAT16 is only recommended for partitions smaller than 32MB. It's strange that this was the problem.
    – harrymc
    Commented Apr 27, 2022 at 8:21
  • @harrymc It indeed is. This had me stumped for a whole day while I tried everything else I could think of besides re-formatting, which finally did it. May be a quirk of the UEFI implementation in VirtualBox. 🤷
    – antichris
    Commented Apr 27, 2022 at 10:28
  • The UEFI implementation in VirtualBox might possibly be an early version.
    – harrymc
    Commented Apr 27, 2022 at 14:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .