Partitioning hard disk drives for BIOS-MBR, BIOS-GPT and UEFI-GPT in Linux
Introduction
This post was prompted by recent threads in the Gentoo Linux Forums such as the following:
- ‘partition MBR/GPT fdisk question‘ in which two people asked how to partition a HDD using GPT. One has a computer that only has BIOS firmware; the other has a computer with firmware that supports UEFI and BIOS (user-selectable) and who apparently wanted to boot using BIOS.
- ‘[SOLVED] installing on UEFI system‘ in which someone asked how to partition a HDD for a computer with UEFI firmware.
These Gentoo Linux users were confused by the instructions in the Gentoo Installation Guide – Preparing the disks. In my opinion the Gentoo Installation Guide is confusing. You do not need a BIOS boot partition (Code EF02) if you want to use a GPT-partitioned HDD with a UEFI computer; you only need a BIOS boot partition on a GPT-partitioned HDD if you want to use it with a BIOS computer. You do not need an ESP (EFI System Partition) if you want to use a GPT-partitioned HDD with a BIOS computer; you only need an ESP (Code EF00) — which must be formatted as FAT32 — if you want to use UEFI.
Coincidentally, recently an Ubuntu user also told me he finds GPT partitioning for UEFI confusing.
So, in the hope of helping people having trouble understanding how to partition a HDD for Linux, I decided to post some information on the two firmware designs and the two partitioning designs, plus list a few (of the many) partitioning schemes that can be used. The purpose of this post is to provide an overview of the designs and possible schemes, not to explain how to use the various partitioning tools or to list the precise steps you must follow. I have tried to avoid going into fine detail (for example the oft-quoted limit of 2TiB for MBR-partitioned HDDs is contigent on 512B sectors).
Firstly, let’s get the terminology straight: you should say ‘UEFI firmware’, not ‘UEFI BIOS’. The latter is an oxymoron. I know that some computer manufacturers and third-party firmware providers use the term ‘UEFI BIOS’, but it is incorrect. The ‘BIOS’ (a.k.a. ‘PC BIOS’) and the UEFI are two different designs of firmware used during the booting process. BIOS firmware and MBR partitioning are older (‘legacy’) designs; UEFI firmware and GPT partitioning are the latest designs, intended to replace BIOS and MBR. See the end of this post for links to articles regarding BIOS, MBR, UEFI and GPT that I recommend you also read.
I personally have not come across computers that support solely UEFI; all the computers I have used allow the user to configure the firmware at boot via the Setup menu to use either UEFI or BIOS. Some UEFI firmware manufacturers show the BIOS support option in the Setup menu as ‘Compatibility Support Module’ (CSM) or ‘Legacy Mode’.
‘Secure Boot’ is one of the touted UEFI features not present in BIOS. Linux expert Roderick W. Smith explains Secure Boot in his article ‘Linux on UEFI: A Quick Installation Guide‘:
One optional feature of UEFI deserves mention: Secure Boot. This feature is designed to minimize the risk of a computer becoming infected with a boot kit, which is a type of malware that infects the computer’s boot loader. Boot kits can be particularly difficult to detect and remove, which makes blocking them a priority. Microsoft requires that all desktop and laptop computers that bear a Windows 8 logo ship with Secure Boot enabled. This type of configuration complicates Linux installation, although some distributions handle this problem better than do others. Do not confuse Secure Boot with EFI or UEFI, though; it’s possible for an EFI computer to not support Secure Boot, and it’s possible to disable Secure Boot even on x86-64 EFI computers that support it. Microsoft requires that users can disable Secure Boot for Windows 8 certification on x86 and x86-64 computers; however, this requirement is reversed for ARM computers—such computers that ship with Windows 8 must not permit the user to disable Secure Boot. Fortunately, ARM-based Windows 8 computers are currently rare. I recommend avoiding them.
GPT-partitioned HDDs have become the norm these days for two principal reasons:
- the MBR design limits the amount of disk space accessible to a maximum of 2TiB but HDDs larger than 2TiB are now common;
- Microsoft has standardised on UEFI, and UEFI will not boot an MBR-partitioned HDD (Section 5.2.1 of Version 2.6 of the UEFI Specification specifies that UEFI firmware shall not execute the boot code in an MBR located at the first logical block of a disk with the MBR disk layout).
The ‘Protective MBR’ at the beginning of every GPT-partitioned disk (in the same location on the disk as a legacy MBR would be) is designed to prevent MBR-based disk utilities misrecognising and possibly overwriting GPT-partitioned disks. A fake (i.e. it does not really exist) single partition called the ‘GPT Protective Partition’ (Code EE00) is specified in the Protective MBR to occupy as much of the drive as can be represented in an MBR, namely a maximum of 2TiB in the case of a disk with 512B sectors. Operating systems and tools not designed for GPT disks will read the Protective MBR and detect that the disk contains a single partition of unknown type and with no empty space, and will refuse to modify the disk unless the user deletes this partition. This design (i.e. the Protective MBR and GPT Protective Partition) was devised in order to minimise the possibility of a) legacy software accidentally overwriting a GPT-partitioned HDD; b) GPT-aware software accidentally overwriting an MBR-partitioned HDD (the absence of a partition of type EEh defined in the Protective MBR would indicate to GPT-aware operating systems and tools that the HDD is not GPT-partitioned).
You can use an MBR-partitioned HDD with BIOS; you can use a GPT-partitioned HDD with BIOS; you can use a GPT-partitioned HDD with UEFI; you cannot use an MBR-partitioned HDD with UEFI. If the firmware in your computer has an option to select BIOS mode (some firmware manufacturers refer to this as ‘Compatibility Support Module’ or ‘Legacy Mode’) instead of UEFI and you want to use an MBR on the HDD, you will have to use BIOS. In summary, for Linux your options are BIOS-MBR, BIOS-GPT or UEFI-GPT. I will discuss these three options and provide some possible partitioning schemes in each case.
The layout of a GPT-partitioned HDD is as follows:
Protective MBR | 512B |
Primary GPT Header | 512B |
Primary Partition Table entries | Up to 16KiB (maximum of 128 partitions) |
Therefore the unpartitioned space at the beginning of the HDD should be at least 17KiB.
Unlike in the MBR design, the end of a GPT-partitioned disk stores a backup of the partition table:
Secondary Partition Table entries | Up to 16KiB (maximum of 128 partitions) |
Secondary GPT Header | 512B |
(The Secondary GPT Header really does come after the Secondary Partition Table entries.)
Therefore the upartitioned space at end of a GPT-partitioned disk should be at least 16.5KiB.
The partitions themselves are located between the Primary GPT and the Secondary GPT, i.e. between the above two tables.
The remainder of a GPT-partitioned disk between the above two areas can contain up to 128 partitions. One partition — normally the first partition is used — must be the ‘ESP’ (EFI System Partition), which should be formatted as FAT32 and have the ‘esp’ and ‘boot’ flags set. The partition code must be EF02. The minimum possible size of a FAT32 partition is 33,549,824B (~32MiB) with 65525 clusters and 512 byte sectors, or 268,398,592B (~256MiB) with 65525 clusters and 4KiB sectors. The required size of the ESP will depend on what is stored in it (for example the now-orphaned ELILO boot loader stored the Linux kernel images in it, whereas the GRUB boot loader does not). The Ubuntu Community Help Wiki specifies a minimum of 100MiB and recommends 200MiB. The Gentoo Installation Guide recommends 128MB.
The versions of GParted and KDE Partition Manager I have used to partition HDDs seem to want to reserve at least 2048 512B sectors of empty space before the first partition (sometimes these two utilities force me to have 4096 512B sectors of empty space before the first partition), so I suggest leaving at least 1MiB of unpartitioned space at the beginning and end of the HDD if you want to partition a disk for GPT using those tools. Actually, for peace of mind you may as well leave 1MiB of empty space at the beginning and end of the disk whatever GUI tools or console commands (parted
, fdisk
, gdisk
, etc.) you use to partition the disk.
By the way, if you wanted to use MBR instead of GPT, the MBR (512B) plus the GRUB embedding area after the MBR (~31KiB) means that 1MiB would also be more than enough for an MBR HDD (see GNU GRUB Manual – 3.4 BIOS installation).
Thus my suggestions for HDD partitioning would be as shown below. Note that the order of the partitions I have adopted below is not obligatory; you can change the order if you wish. I prefer to specify precise sizes for the swap and root partitions, and put /home
on the last partition so it can occupy the remainder of the disk, whatever size that may be.
UEFI-GPT
Option 1
This is my preferred option because I can edit /etc/fstab
and specify that /boot
must not be mounted at boot, thus reducing the possibility of the files in /boot
getting corrupted.
1.00 MiB of empty space at the beginning of the disk. |
/dev/sda1 Size: 512 MiB File system: FAT32 Flags: boot & esp Code: EF00 Label: ESP Mount point: /boot/efi |
/dev/sda2 Size: 16 GiB for a computer with 16 GiB of RAM* File system: linux-swap Flags: None Code: 8200 Label: SWAP Mount point: None |
/dev/sda3 Size: 512 MiB File system: ext2 Flags: None Code: 8300 Label: BOOT Mount point: /boot Therefore /boot/grub/ will be on this partition if you use GRUB. |
/dev/sda4 Size: e.g. 64 GiB (128 GiB if the drive is big) File system: ext4 Flags: None Code: 8300 Label: ROOT Mount point: / (root) |
/dev/sda5 Size: 1.00 MiB less than the remaining disk space File system: ext4 Flags: None Code: 8300 Label: HOME Mount point: /home |
1.00 MiB of empty space at the end of the disk. |
* You will often see recommendations to make the size of the swap partition the same as the size of the RAM if you want to be able to put the computer into hibernation. In fact, the Linux kernel is normally configured to compress the contents of the RAM image for hibernation, and I personally have seen the disk image of 4GB of RAM compressed to 23% of that size. Nevertheless, if you have a large HDD you may as well just take the easy route and allocate the size of the swap partition to be the same as the RAM size, even if all of the swap partition will never be used in practice. That way you are guaranteed to be able to put the computer into hibernation.
Below is an example of the above partitioning scheme on a virtual UEFI machine with a 64GiB virtual GPT-partitioned HDD:
root # gdisk -l /dev/sda
GPT fdisk (gdisk) version 1.0.1
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Disk /dev/sda: 134217728 sectors, 64.0 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 54B3C38F-1C55-4A19-9BAA-499C4D0D8DD0
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 134217694
Partitions will be aligned on 2048-sector boundaries
Total free space is 4029 sectors (2.0 MiB)
Number Start (sector) End (sector) Size Code Name
1 2048 1050623 512.0 MiB EF00
2 1050624 5244927 2.0 GiB 8200
3 5244928 6293503 512.0 MiB 8300
4 6293504 72353791 31.5 GiB 8300
5 72353792 134215679 29.5 GiB 8300
root # fdisk -l /dev/sda
Disk /dev/sda: 64 GiB, 68719476736 bytes, 134217728 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
Disklabel type: gpt
Disk identifier: 54B3C38F-1C55-4A19-9BAA-499C4D0D8DD0
Device Start End Sectors Size Type
/dev/sda1 2048 1050623 1048576 512M EFI System
/dev/sda2 1050624 5244927 4194304 2G Linux swap
/dev/sda3 5244928 6293503 1048576 512M Linux filesystem
/dev/sda4 6293504 72353791 66060288 31.5G Linux filesystem
/dev/sda5 72353792 134215679 61861888 29.5G Linux filesystem
root # parted /dev/sda print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 68.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 538MB 537MB fat32 boot, esp
2 538MB 2685MB 2147MB linux-swap(v1)
3 2685MB 3222MB 537MB ext2
4 3222MB 37.0GB 33.8GB ext4
5 37.0GB 68.7GB 31.7GB ext4
root # blkid
/dev/sda4: LABEL="ROOT" UUID="174ac3e8-f105-4606-bed1-7a1aa22c3631" TYPE="ext4" PARTUUID="01d9c139-fe70-415a-abc6-2351fad33384"
/dev/sda1: UUID="B4C1-7EA5" TYPE="vfat" PARTUUID="d941f728-c386-4f4c-b0c3-aa76f4290774"
/dev/sda2: LABEL="SWAP" UUID="e3ddf9b5-2ae3-4469-a121-0a1a78aa6702" TYPE="swap" PARTUUID="a4daec88-da44-4ae3-8119-01cc81325f03"
/dev/sda3: LABEL="BOOT" UUID="1e24ea9d-5358-4e9b-8667-d7a42e7b6ad7" TYPE="ext2" PARTUUID="b5369ce3-4b44-4d19-be6f-1d226dc71cb3"
/dev/sda5: LABEL="HOME" UUID="87f6a0af-dbed-4587-b810-efca8f269618" TYPE="ext4" PARTUUID="19fd7d00-2d89-4653-af03-e81618a3b70d"
Option 2
You could use this scheme if you are not interested in having /boot
on its own partition.
1.00 MiB of empty space at the beginning of the disk. |
/dev/sda1 Size: 512 MiB File system: FAT32 Flags: boot & esp Code: EF00 Label: ESP Mount point: /boot/efi |
/dev/sda2 Size: 16 GiB for a computer with 16 GiB of RAM* File system: linux-swap Flags: None Code: 8200 Label: SWAP Mount point: None |
/dev/sda3 Size: e.g. 64 GiB (128 GiB if the drive is big) File system: ext4 Flags: None Code: 8300 Label: ROOT Mount point: / (root) Therefore /boot (and /boot/grub/ ) will on this partition too. |
/dev/sda4 Size: 1.00 MiB less than the remaining space on the disk File system: ext4 Flags: None Code: 8300 Label: HOME Mount point: /home |
1.00 MiB of empty space at the end of the disk. |
* See my earlier note regarding hibernation.
Below is an example of the above scheme on a virtual UEFI machine with a 64GiB virtual GPT-partitioned HDD:
root # gdisk -l /dev/sda
GPT fdisk (gdisk) version 1.0.1
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Disk /dev/sda: 134217728 sectors, 64.0 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 54B3C38F-1C55-4A19-9BAA-499C4D0D8DD0
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 134217694
Partitions will be aligned on 2048-sector boundaries
Total free space is 4029 sectors (2.0 MiB)
Number Start (sector) End (sector) Size Code Name
1 2048 1050623 512.0 MiB EF00
2 1050624 5244927 2.0 GiB 8200
3 5244928 72353791 32.0 GiB 8300
4 72353792 134215679 29.5 GiB 8300
root # fdisk -l /dev/sda
Disk /dev/sda: 64 GiB, 68719476736 bytes, 134217728 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
Disklabel type: gpt
Disk identifier: 54B3C38F-1C55-4A19-9BAA-499C4D0D8DD0
Device Start End Sectors Size Type
/dev/sda1 2048 1050623 1048576 512M EFI System
/dev/sda2 1050624 5244927 4194304 2G Linux swap
/dev/sda3 5244928 72353791 67108864 32G Linux filesystem
/dev/sda4 72353792 134215679 61861888 29.5G Linux filesystem
root # parted /dev/sda print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 68.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 538MB 537MB fat32 boot, esp
2 538MB 2685MB 2147MB linux-swap(v1)
3 2685MB 37.0GB 34.4GB ext4
4 37.0GB 68.7GB 31.7GB ext4
root # blkid
/dev/sda3: LABEL="ROOT" UUID="fdf2b11a-8c6b-4bb3-9534-477c3ed49d95" TYPE="ext4" PARTUUID="f393129f-ab32-40fb-bf78-3aead3dd4af0"
/dev/sda1: UUID="C024-8A30" TYPE="vfat" PARTUUID="d941f728-c386-4f4c-b0c3-aa76f4290774"
/dev/sda2: LABEL="SWAP" UUID="1f752a05-a1fb-4c5f-ab2e-079715207b4d" TYPE="swap" PARTUUID="a4daec88-da44-4ae3-8119-01cc81325f03"
/dev/sda4: LABEL="HOME" UUID="041e4ab2-d54c-4092-b445-779997ac09ce" TYPE="ext4" PARTUUID="7e1b8dc0-2f38-4260-95af-fbb80bb72156"
Option 3
You could use this scheme if you are not interested in having /boot
and /home
on their own partitions.
1.00 MiB of empty space at the beginning of the disk. |
/dev/sda1 Size: 512 MiB File system: FAT32 Flags: boot & esp Code: EF00 Label: ESP Mount point: /boot/efi |
/dev/sda2 Size: 16 GiB for a computer with 16 GiB of RAM* File system: linux-swap Flags: None Code: 8200 Label: SWAP Mount point: None |
/dev/sda3 Size: 1.00 MiB less than the remaining space on the disk File system: ext4 Flags: None Code: 8300 Label: ROOT Mount point: / (root) Therefore /boot (and /boot/grub/ ) and /home will on this partition too. |
1.00 MiB of empty space at the end of the disk. |
* See my earlier note regarding hibernation.
BIOS-GPT
If you have partitioned a large drive correctly then a computer with BIOS firmware will be able to access partitions larger than 2TiB. One of my computers has BIOS firmware only but can access its 3TiB GPT-partitioned HDDs.
Option 1
This is my preferred option because I can edit /etc/fstab
and specify that /boot
must not be mounted at boot, thus reducing the possibility of the files in /boot
getting corrupted.
1.00 MiB of empty space at the beginning of the disk. |
/dev/sda1 ← This is the BIOS boot partition Size: 1.00 MiB File system: Unformatted Flags: bios_grub Code: EF02 Label: Not applicable Mount point: Not applicable |
/dev/sda2 Size: 512 MiB File system: ext2 Flags: None Code: 8300 Label: BOOT Mount point: /boot |
/dev/sda3 Size: 16 GiB for a computer with 16 GiB of RAM* File system: linux-swap Flags: None Code: 8200 Label: SWAP Mount point: None |
/dev/sda4 Size: e.g. 64 GiB (128 GiB if the drive is big) File system: ext4 Flags: None Code: 8300 Label: ROOT Mount point: / (root) Therefore /boot and (/boot/grub/ ) will on this partition too. |
/dev/sda5 Size: 1.00 MiB less than the remaining space on the disk File system: ext4 Flags: None Code: 8300 Label: HOME Mount point: /home |
1.00 MiB of empty space at the end of the disk. |
* See my earlier note regarding hibernation.
Option 2
You could use this scheme if you are not interested in having /boot
on its own partition.
1.00 MiB of empty space at the beginning of the disk. |
/dev/sda1 ← This is the BIOS boot partition Size: 1.00 MiB File system: Unformatted Flags: bios_grub Code: EF02 Label: Not applicable Mount point: Not applicable |
/dev/sda2 Size: 16 GiB for a computer with 16 GiB of RAM* File system: linux-swap Flags: None Code: 8200 Label: SWAP Mount point: None |
/dev/sda3 Size: e.g. 64 GiB (128 GiB if the drive is big) File system: ext4 Flags: None Code: 8300 Label: ROOT Mount point: / (root) Therefore /boot (and /boot/grub/ ) will on this partition too. |
/dev/sda4 Size: 1.00 MiB less than the remaining space on the disk File system: ext4 Flags: None Code: 8300 Label: HOME Mount point: /home |
1.00 MiB of empty space at the end of the disk. |
* See my earlier note regarding hibernation.
Option 3
You could use this scheme if you are not interested in having /boot
and /home
on their own partitions.
1.00 MiB of empty space at the beginning of the disk. |
/dev/sda1 ← This is the BIOS boot partition Size: 1.00 MiB File system: Unformatted Flags: bios_grub Code: EF02 Label: Not applicable Mount point: Not applicable |
/dev/sda2 Size: 16 GiB for a computer with 16 GiB of RAM* File system: linux-swap Flags: None Code: 8200 Label: SWAP Mount point: None |
/dev/sda3 Size: 1.00 MiB less than the remaining space on the disk File system: ext4 Flags: None Code: 8300 Label: ROOT Mount point: / (root) Therefore /boot and /home will on this partition too. |
1.00 MiB of empty space at the end of the disk. |
* See my earlier note regarding hibernation.
BIOS-MBR
Option 1
This is my preferred option because I can edit /etc/fstab
and specify that /boot
must not be mounted at boot, thus reducing the possibility of the files in /boot
getting corrupted.
1.00 MiB of empty space at the beginning of the disk. |
/dev/sda1 Size: 512 MiB Type: Primary File system: ext2 Flags: boot Label: BOOT Mount point: /boot |
/dev/sda2 Size: 16 GiB for a computer with 16 GiB of RAM* Type: Primary File system: linux-swap Flags: None Label: SWAP Mount point: None |
/dev/sda3 Size: e.g. 64 GiB (128 GiB if the drive is big) File system: ext4 Flags: None Label: ROOT Mount point: / (root) |
/dev/sda4 Size: remaining space on the disk Type: Primary File system: ext4 Flags: None Label: HOME Mount point: /home |
* See my earlier note regarding hibernation.
Option 2
You could use this scheme if you are not interested in having /boot
on its own partition.
1.00 MiB of empty space at the beginning of the disk. |
/dev/sda1 Size: 16 GiB for a computer with 16 GiB of RAM* Type: Primary File system: linux-swap Flags: None Label: SWAP Mount point: None |
/dev/sda2 Size: e.g. 64 GiB (128 GiB if the drive is big) Type: Primary File system: ext4 Flags: boot Label: ROOT Mount point: / (root) Therefore /boot will be on this partition too. |
/dev/sda3 Size: remaining space on the disk Type: Primary File system: ext4 Flags: None Label: HOME Mount point: /home |
* See my earlier note regarding hibernation.
Option 3
You could use this scheme if you are not interested in having /boot
and /home
on their own partitions.
1.00 MiB of empty space at the beginning of the disk. |
/dev/sda1 Size: 16 GiB for a computer with 16 GiB of RAM* Type: Primary File system: linux-swap Flags: None Label: SWAP Mount point: None |
/dev/sda2 Size: remaining space on the disk Type: Primary File system: ext4 Flags: boot Label: ROOT Mount point: / (root) Therefore /boot and /home will be on this partition too. |
* See my earlier note regarding hibernation.
Option 4
If you want to have more than four partitions — let’s say you wanted to have a separate NTFS partition, for example — you would need to use an Extended Partition.
1.00 MiB of empty space at the beginning of the disk. |
/dev/sda1 Size: 512 MiB Type: Primary File system: ext2 Flags: boot Label: BOOT Mount point: /boot |
/dev/sda2 Size: 16 GiB for a computer with 16 GiB of RAM* Type: Primary File system: linux-swap Flags: None Label: SWAP Mount point: None |
/dev/sda3 Size: Remainder of disk Type: Extended File system: Not applicable Flags: None Label: Not applicable Mount point: Not applicable |
/dev/sda4 Will not exist |
/dev/sda5 Size: e.g. 128GiB Type: Logical File system: ext4 Flags: None Label: ROOT Mount point: / (root) |
/dev/sda6 Size: e.g. 256GiB Type: Logical File system: ext4 Flags: None Label: HOME Mount point: /home |
/dev/sda7 Size: remaining space on the disk Type: Logical File system: NTFS Flags: None Label: NTFS Mount point: /media/NTFS |
* See my earlier note regarding hibernation.
Below is an example of the above scheme (this happens to be the scheme on my main laptop):
root # fdisk -l /dev/sda
Disk /dev/sda: 698.7 GiB, 750156374016 bytes, 1465149168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x291ba0e7
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 264191 262144 128M 83 Linux
/dev/sda2 264192 33822719 33558528 16G 82 Linux swap / Solaris
/dev/sda3 33822720 1465147391 1431324672 682.5G 5 Extended
/dev/sda5 33824768 302260223 268435456 128G 83 Linux
/dev/sda6 302262272 839133183 536870912 256G 83 Linux
/dev/sda7 839135232 1465147391 626012160 298.5G 7 HPFS/NTFS/exFAT
root # lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT,LABEL,PARTFLAGS /dev/sda
NAME TYPE SIZE FSTYPE MOUNTPOINT LABEL PARTFLAGS
sda disk 698.7G
├─sda1 part 128M ext2 /boot BOOT
├─sda2 part 16G swap [SWAP] SWAP
├─sda5 part 128G ext4 / ROOT
├─sda6 part 256G ext4 /home HOME
└─sda7 part 298.5G ntfs-3g /media/NTFS NTFS
Notice that the boot flag is not set. Nevertheless the laptop boots fine.
Command-line tools
Below are examples of command-line utilities parted
, gdisk
and fdisk
examining a GPT-partitioned HDD and an MBR-partitioned HDD. The original fdisk
utility predates the invention of GPT, but the latest versions of fdisk
understand the GPT design (you can check this by using the command ‘man fdisk
‘). Personally, to partition GPT HDDs from the command line I would use parted
or gdisk
before fdisk
, and to partition MBR HDDs from the command line I would use parted
or fdisk
before gdisk
. Mind you, I like an easy life and so I tend to use the GUI tools GParted or KDE Partition Manager to partition and format an HDD for Linux.
GPT-partitioned HDD
root # parted /dev/sda print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 68.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 2097kB 539MB 537MB fat32 boot, esp
2 539MB 1076MB 537MB ext2 /boot
3 1076MB 3223MB 2147MB linux-swap(v1) linuxswap
4 3223MB 37.6GB 34.4GB ext4 /
5 37.6GB 68.7GB 31.1GB ext4 /home
root # gdisk -l /dev/sda
GPT fdisk (gdisk) version 1.0.1
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Disk /dev/sda: 134217728 sectors, 64.0 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 9807AF0F-8BD5-4727-A3CD-9995B2705732
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 134217694
Partitions will be aligned on 2048-sector boundaries
Total free space is 8125 sectors (4.0 MiB)
Number Start (sector) End (sector) Size Code Name
1 4096 1052671 512.0 MiB EF00
2 1052672 2101247 512.0 MiB 8300 /boot
3 2101248 6295551 2.0 GiB 8200 linuxswap
4 6295552 73404415 32.0 GiB 8300 /
5 73404416 134213631 29.0 GiB 8300 /home
root # fdisk -l /dev/sda
Disk /dev/sda: 64 GiB, 68719476736 bytes, 134217728 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
Disklabel type: gpt
Disk identifier: 9807AF0F-8BD5-4727-A3CD-9995B2705732
Device Start End Sectors Size Type
/dev/sda1 4096 1052671 1048576 512M EFI System
/dev/sda2 1052672 2101247 1048576 512M Linux filesystem
/dev/sda3 2101248 6295551 4194304 2G Linux swap
/dev/sda4 6295552 73404415 67108864 32G Linux filesystem
/dev/sda5 73404416 134213631 60809216 29G Linux filesystem
MBR-partitioned HDD
root # parted /dev/sda print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 68.7GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 538MB 537MB primary ext2 boot
2 538MB 2685MB 2147MB primary linux-swap(v1)
3 2685MB 37.0GB 34.4GB primary ext4
4 37.0GB 68.7GB 31.7GB primary ext4
root # gdisk -l /dev/sda
GPT fdisk (gdisk) version 1.0.1
Partition table scan:
MBR: MBR only
BSD: not present
APM: not present
GPT: not present
***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format
in memory.
***************************************************************
Warning! Secondary partition table overlaps the last partition by
33 blocks!
You will need to delete this partition or resize it in another utility.
Disk /dev/sda: 134217728 sectors, 64.0 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): F6E9E53E-33BE-44CB-BEFC-D93E03B79B84
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 134217694
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 1050623 512.0 MiB 8300 Linux filesystem
2 1050624 5244927 2.0 GiB 8200 Linux swap
3 5244928 72353791 32.0 GiB 8300 Linux filesystem
4 72353792 134217727 29.5 GiB 8300 Linux filesystem
root # fdisk -l /dev/sda
Disk /dev/sda: 64 GiB, 68719476736 bytes, 134217728 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
Disklabel type: dos
Disk identifier: 0x7b9f1623
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 1050623 1048576 512M 83 Linux
/dev/sda2 1050624 5244927 4194304 2G 82 Linux swap / Solaris
/dev/sda3 5244928 72353791 67108864 32G 83 Linux
/dev/sda4 72353792 134217727 61863936 29.5G 83 Linux
Notice the gdisk
warning that the last partition would not be viable on a GPT-partitioned HDD because there would not be space for the Secondary GPT. However, as this is an MBR-partitioned HDD for use with a BIOS firmware computer, that does not apply.
A warning note if installing Ubuntu on a UEFI computer
When I installed Ubuntu Desktop 16.04.1 in a virtual machine I encountered a bug (in VirtualBox? in the Ubuntu Installer?) which results in subsequent reboots leaving the virtual machine running the UEFI Shell instead of launching GRUB and booting Ubuntu. To fix that, I did the following as soon as Ubuntu booted from the virtual HDD for the first time after I had clicked ‘Restart Now’ in the ‘Installation Complete’ window:
user $ sudo su
root # mount /dev/sda1 /mnt
root # cd /mnt
root # echo "\EFI\ubuntu\grubx64.efi" > startup.nsh
root # cd
root # umount /dev/sda1
root # exit
The partition /dev/sda1 being the FAT32 ESP in this case.
This creates the file /boot/efi/startup.nsh
required by the UEFI Shell. Then you can reboot and all should work as intended, i.e. the UEFI machine boots to the UEFI Shell which, after a few seconds, launches GRUB.
UPDATE (16 February 2017): A downside to the above approach is the 5-second timeout in the UEFI Shell until startup.nsh is launched. Below is an alternative that avoids having to wait for the 5-second countdown in the UEFI Shell until startup.nsh is launched. The downside is that you must remember to repeat this procedure if a new version of GRUB is installed and there is a new version of /EFI/ubuntu/grubx64.efi.
user $ sudo su
root # mount /dev/sda1 /mnt
root # cd /mnt/EFI/
root # ls
ubuntu
root # ls ubuntu
fw fwupx64.efi grub.cfg grubx64.efi MokManager.efi shimx64.efi
root # mkdir BOOT
root # cp ubuntu/grubx64.efi BOOT/BOOTX64.EFI
root # cd
root # umount /dev/sda1
root # exit
See the Arch Linux Wiki article VirtualBox – 2.1 Installation in EFI mode.
A warning note if installing Gentoo on a UEFI computer
To date, the Gentoo Minimal Installation CD does not support UEFI, and therefore I recommend that you use SystemRescueCd instead. It is a Gentoo-based LiveCD with several tools useful for installing Gentoo, including a Web browser so you can access the on-line Gentoo documentation during installation. You can follow the Gentoo Installation Guide verbatim. SystemRescueCd also has a Desktop Environment with various GUI utilities, so you could partition the HDD using GParted instead of the command-line utilities if you wish. SystemRescueCd also comes with various wireless network card drivers and a network manager, so there is a good chance you will be able to connect easily to a wireless network if you prefer (I once used SystemRescueCd to install Gentoo on a laptop using Wi-Fi alone, as a wired connection was not convenient at the time).
How can I find out in Linux if a computer has booted using UEFI?
Check if the RAM-based directory /sys/firmware/efi/
exists. If it does not exist, the computer did not boot using UEFI.
Further Reading
- Wikipedia – BIOS
- Wikipedia – Master boot record
- UEFI Specification Version 2.6, January 2016
- Wikipedia – Unified Extensible Firmware Interface
- Wikipedia – GUID Partition Table
Also, the diagram GUID Partition Table Scheme in that article is quite helpful in understanding the layout of a GPT-partitioned HDD. - Wikipedia – BIOS boot partition
Also, the diagram GNU GRUB 2 in that article is quite helpful in understanding: a) MBR partitioning; b) how GRUB 2 fits on an MBR-partitioned HDD; c) GPT partitioning; d) how GRUB 2 fits on a GPT-partitioned HDD; e) where the BIOS boot partition fits on a GPT-partitioned HDD and how it is used by GRUB 2. - GNU GRUB Manual – 3.4 BIOS installation
- Ubuntu Documentation – UEFI
- Gentoo Installation Guide – Preparing the disks
- Ubuntu Bug Reports – Bug No. 811485 – Ubuntu partman-efi package – EFI SYSTEM PARTITION should be atleast 100 MiB size and formatted as FAT32, not FAT16
- Roderick W. Smith’s Web Page