How to mark a GPT Partition bootable under Linux
How to boot from a GPT Partition?
Booting a Linux installation involves multiple stages and software components, including firmware initialization, execution of a boot loader, loading and startup of a Linux kernel image, and execution of various startup scripts and daemons. For each of these stages and components there are different variations and approaches; for example, GRUB, LILO, SYSLINUX or Loadlin can be used as boot loaders, while the startup scripts can be either traditional init-style, or the system configuration can be performed through modern alternatives such as systemd or Upstart.
Another popular program to use to boot with is rEFInd a UEFI boot manager capable of launching EFISTUB kernels.
The EFI (Extensible Firmware Interface) system partition or ESP is a partition on a data storage device (usually a hard disk drive or solid-state drive) that is used by computers adhering to the Unified Extensible Firmware Interface (UEFI). When a computer is booted, UEFI firmware loads files stored on the ESP to start installed operating systems and various utilities.
An ESP contains the boot loaders or kernel images for all installed operating systems
Is it like the MBR way that needs a partition that has the bootable flag on?
The boot flag is from ancient times, where you would indicate an MBR partition record as bootable, so you could indicate where the boot loader resided. So to answer your question no you don’t have to flag a boot partition bootable.
The globally unique identifier (GUID) for the EFI system partition in the GUID Partition Table (GPT) scheme is C12A7328-F81F-11D2-BA4B-00A0C93EC93B, while its ID in the master boot record (MBR) partition-table scheme is 0xEF.
How to mark a GPT Partition bootable under Linux?
- In gdisk, you set the type code to EF00. (gdisk uses two-byte type codes that expand out to the real type codes on the disk; «EF00» is just a mnemonic for «C12A7328-F81F-11D2-BA4B-00A0C93EC93B«.)
- In GParted or parted, you set the «boot flag.» Note, however, that this works only on GPT disks; you cannot set the ESP type code on MBR disks with these programs. (This isn’t normally a big deal, since EFI-based computers usually boot from GPT disks.)
- In recent versions of Linux fdisk, you set the partition type by its number (1 for «EFI System» on GPT disks or 0xEF on MBR disks) or by entering the full type code on GPT disks.
Thanks for the most comprehensive answer. Follow up question to make it 100% clear, «In GParted or parted, you set the «boot flag»», does that means that there can be more than one «boot flag» set for the GPT Partitions? Moreover, can you show the output of sgdisk -p or fdisk -l of a GPT that has such «boot flag» set please? Thx
Found from the gdisk help: gdisk type code of EF00 stands for «EFI System», which doesn’t look like «boot flag» to me (the «ef02», «BIOS boot partition» looks more so). Kindly to elaborate a bit please? (Temporarily flipped the accept flag in waiting for answer for these two follow up questions)
In Gparted the boot flag is used by some commercial operating system boot loaders. The boot flag indicates the partition is active or bootable. Only one partition on a disk device can be active. The output from fdisk -l is: /dev/sda1 2048 1050623 1048576 512M EFI System
The boot flag «EF00» is just a mnemonic for or GUID partition type «C12A7328-F81F-11D2-BA4B-00A0C93EC93B» is the EFI system partition . «ef02» is the GUID 21686148-6449-6E6F-744E-656564454649 or BIOS boot partition.
Thanks Donald. The supplementary answer is normally put within the answer instead of here in comments, BTW.
Is it like the MBR way that needs a partition that has the bootable flag on?
Hmm well before we go on a brief recall on how the bios hands over the boot execution follow.
- Bios reads first sector (512 Bytes) of the boot medium.
- If the last two bytes of the sector are 55 AA it executes that sector. So here ends the responsibility of the bios.
That 440 Bytes code snipped is named MBR (Master Boot record) It’s purpose is to look in the 4 partitions table entries for the bootable flag. If it for some partition marked as bootable it’ll load it’s first sector and handover flow of boot execution to the code in this sector.
Note for compatibility reason that so called protective MBR is even there when using GPT. (The GPT starts at second sector)
So it the MBR-code that cares for the the ‘bootable flag’. However that 440 Bytes MBR-code snipped can be altered or different. And when indeed when installing GRUB that is that case. So for example Installing GRUB2 like this:
sudo grub-install --boot-directory=/mnt/boot --force --target=i386-pc /dev/sdb -v
Will completely replace the the standard MBR code with it’s own code. ( note a copy of that code can be found at /boot/grub/i386-pc/boot.img )
Conclusion: -> The Grub code will not care for any bootable flags.
Installing grub on Non-EFI GPT-Device
By ‘Non-EFI’ I mean we’ve an old device whose Bios has no UEFI or on which UEFI runs in CSM(Compatibility Support Module) Mode and boots the traditional way I described above.
When Grub is installed via ‘blocklists’, it installs itself in the partition gap between the MBR and the first boot sector. However when we have GPT is used Grub refuses to go that partition gap way. Instead it wants a tiny partition to be made were it can safely install it’s code into.
So this is how we setup this using Gparted:
- Create a formatted partition that is 1MB
- Mark that partition as ‘bios-grub’ When you enable that ‘bios-grub’ checkbox in gparted it’ll change the GPT-type to ‘BIOS boot partition’.
Alternatively you can use: gdisk -l /dev/sdb to check and .
sgdisk -t 3:ef02 /dev/sdb ^- marks 3rd partition as ef02 => ‘BIOS boot partition’
. to accomplish that same without gparted. Note: «ef02» is short for ‘BIOS boot partition’ or the GUID 21686148-6449-6E6F-744E-656564454649 .
Okay that’s it. Now we can run Grub setup.
Mount ya Linux ( or /boot/grub partition ) to /mnt/boot and run
sudo grub-install --boot-directory=/mnt/boot --force --target=i386-pc /dev/sdb -v
If ya lucky and all went well and you see:
grub-install: Info: setting the root device to `hostdisk//dev/sda,gpt6'. grub-install: Info: saving . .
So that content of /boot/grub/i386-pc/core.img is directly copied into that 1 MB ‘BIOS boot partition’ —force is needed else grub refuses get installed via blocklists. Incase it fails here is a shortcut to try start at the block list part of the installation again:
grub-bios-setup --verbose --force --directory= /mnt/boot/grub/i386-pc /dev/sdb
So in short grub-bios-setup will copy
/mnt/boot/grub/i386-pc/boot.img -> Sector 0 (MBR) /mnt/boot/grub/i386-pc/core.img -> Sector 556324864 (BIOS boot partition)
However the most important part the ‘compilation’ of core.img is not performed by it.
I use Virtualbox to test the booting process:
sudo chmod 666 /dev/sd* VBoxManage internalcommands createrawvmdk -filename ~/sdb.vmdk -rawdisk /dev/sdb
That command is in particular useful to get the whole physical device into the virtual machine.
‘Fun’ with grub rescue>
Just a brief rush since you probably will encounter it on the way. Okay goal is to get these 2 commands execute without error:
set is useful to see what is set. ls shows what partitions are there ls (hd0,2) shows what files are on partition #1 if found the grub folder on (hd0,2) set prefix=(hd0,2)/boot/grub is the command that’ll get you out. now insmod normal and normal will get you to into the ‘normal’ grub menu. once you got normal.mod running there is just one cool thing to mention:
will give you a more details view on what partitions are there what are their name and the file system used.
How to mark the partition with grub.cfg ?
This happens indirectly when install grub. After that it is fix and nearly impossible to change. Thanks to some stupid design decisions. Okay let’s look more closely into that not well designed part of grub.
The key to this core.img. During grub setup that is directly written into the 1 MB partition we created for that purpose It’s contains a script that may look more or less like this
set prefix=(hd0,2)/boot/grub insmod normal normal
This script and all the filesystem drivers it’ll need to access the partition with the grub files will be glued together and compressed(. ) into core.img. Because of the compression you can’t use a disk editor to view it or alter small things like change (hd0,2) to (hd0,4) or things like that that might be needed you use gdisk to sort GPT partitions or do some other changes. There is also no way to disable the compression (or well there is a switch for but it doesn’t work) Also that script is autogenerated and you’ve no way to alter it to make it a little more smart. For ex. use search.label to find the needed Grub partition instead of fixed partition numbers. All you can partially do is rerun the grub setup and hope it’ll gets all right for booting.
Note: Strangely when using EFI things are more open and friendly for quick customisation.
Unfortunately I’m still researching how ‘grub-install’ works. Currently I’m messing around with oddities like with it messes around with sda while I explicitly specify it should use sdb.
I may edit this post later if I learned more about. EDIT: Okay here we go. Here is how to do the ‘impossible’:
nano /mnt/boot/grub/i386-pc/load.cfg
search.fs_uuid 39ff90d3-00b1-4cb9-8b94-03a7a9053352 root hd0,gpt6 set prefix=($root)'/mnt/boot/grub'
is crap and not what I need. I change it to:
search.fs_label boot root hd0,gpt5 set prefix=($root)/grub
wow that looks better. 🙂 . now generate ‘core.img’. :
grub-mkimage -O i386-pc -o /mnt/boot/grub/i386-pc/core.img -C none \ --prefix /grub -c /mnt/boot/grub/i386-pc/load.cfg \ ext2 ntfs part_gpt biosdisk search_label normal
Note: beside ntfs I also added the module ‘normal’ for more comfort at the rescue console. Now tab to complete a command as well cursor up down to scroll command history will work. And as mentioned before currently —Compression none has no effect. Core.img is always compressed with xz.
grub-bios-setup -v -f -d /mnt/boot/grub/i386-pc /dev/sdb
So what partition is start from depends on what is written in grub.cfg and of course what is the users selected to boot.
Creating grub.cfg
Mount your linux system to /mnt/MINT then run:
grub-mkconfig -o /mnt/MINT/boot/grub/grub.cfg
Adding UEFI Support
Preparation: With Gparted add 1 MB FAT32 partition. and set the Type to ‘ef00 EFI system partition’ I use sgdisk -t 11:ef00 /dev/sdb ^- marks 11th partition as ef00 => ‘EFI system partition’
gdisk -l /dev/sdb to check the result. However most of the time there is already some ‘EFI system partition’. So in that case just use, instead of creation an additional one.
The ‘EFI system partition’ will store grubx64.efi that later is load and run by the EFI bios. Note that EFI-Bios knows by default how to read a GPT as well as FAT32. Now mount
/mnt/boot -> Linux System containing grub.cfg /mnt/UEFI -> The 'EFI system partition'
sudo grub-install --boot-directory=/mnt/boot \ --efi-directory=/mnt/UEFI --target=x86_64-efi /dev/sdb -v
Not much changed. Well —force is not need anymore there is another —target and there’s an additional arguments needed —efi-directory