[parted-devel] [PATCH 2/2] gpt: Recalculate PrimaryPartitionEntryLBA when primary partition table is invalid

Pascal Hambourg pascal at plouf.fr.eu.org
Wed Nov 19 18:44:48 GMT 2025


When the primary partition table is invalid, the primary PartitionEntryLBA
may be reset at two possible locations:
- just after the primary header
- just before the FirstUsableLBA

On some platforms based on ARM SoCs, a boot loader may be present at any
location between the primary header and the FirstUsableLBA. E.g.:

- Allwinner family: start 8KiB, end < 1MiB
- NXP/Freescale i.MX family: start 1KiB, end < 1MiB
- OLPC XO (Marvell Armada): start 31.5KiB, end < 64KiB
- BeagleBoard-X15, BeagleBone Black (TI OMAP): start 128KiB, end ~2MiB
- Rockchip family (RK3288, RK3328, RK3399): start 32KiB, end ~10MB

A boot loader which starts before LBA 34 may interfere with the primary
PEA, so the primary PEA may have been moved after the boot loader.
A boot loader which ends after 1MiB may interfere with partitions using
default alignment, so the FirstUsableLBA may have been moved after the
boot loader.

>From the above examples it appears that
- boot loaders which end after 1MiB start after LBA 34;
- boot loaders which start before LBA 34 end before 1MiB.

So the following logic seems safe:
- if FirstUsableLBA <= 1MiB, the purpose is likely to avoid interference
between the boot loader and the primary PEA -> move the primary PEA just
before the FirstUsableLBA;
- if FirstUsableLBA > 1MiB, the purpose is likely to avoid interference
between the boot loader and partitions -> leave the primary PEA just
after the primary header (default).
---
 libparted/labels/gpt.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c
index 87261dbd..422720b6 100644
--- a/libparted/labels/gpt.c
+++ b/libparted/labels/gpt.c
@@ -1076,6 +1076,15 @@ gpt_read (PedDisk *disk)
         goto error_free_gpt;
 
       gpt = backup_gpt;
+      /* Set PrimaryPartitionEntryLBA before FirstUsableLBA if <= 1MiB */
+      if ((PED_LE32_TO_CPU (gpt->FirstUsableLBA) * disk->dev->sector_size)
+          <= 1048576)
+        {
+          gpt_disk_data->PrimaryPartitionEntryLBA =
+            PED_LE32_TO_CPU (gpt->FirstUsableLBA)
+            - (ped_div_round_up (PED_LE32_TO_CPU (gpt->NumberOfPartitionEntries)
+               * sizeof(GuidPartitionEntry_t), disk->dev->sector_size));
+        }
     }
   backup_gpt = NULL;
   primary_gpt = NULL;
-- 
2.39.5




More information about the parted-devel mailing list