[parted-devel] [PATCH] gpt: support padding between Partition Header and Partition Table.

Tzu-Jung Lee roylee17 at currant.com
Mon Mar 21 18:49:51 UTC 2016


I understand this patch might not look good since I couldn't find a
suitable way to pass the PTE_LBA from UI to GPT handling path.
But I'd like to address the problem we have, and am open to better
solutions.

We'd like to use GPT partitions on an i.mx SoC based device. However, this
SoC family loads it's bootcode from a specific fixed location - 0x400,
which conflicts to a "default" location of PTE_LBA (LBA2). The following
provides more context from people porting Chromium OS to Freescale SoC.


https://groups.google.com/a/chromium.org/forum/#!topic/chromium-os-dev/uvoX-poonOU

Chromium OS project added this support to its 'cgpt' utilities. But I'd
like to stick with parted if possible.

Thanks,
Roy

On Mon, Mar 21, 2016 at 11:24 AM Tzu-Jung Lee <roylee17 at currant.com> wrote:

> From: =Tzu-Jung Lee <roylee17 at currant.com>
>
> Some SoC requires their booting code at a specific location, which
> might conflict with the default layout of GPT.
>
> Supporting a specified PartitionEntryLBA is required in this case.
>
> Signed-off-by: Tzu-Jung Lee <roylee17 at currant.com>
>
> diff --git a/include/parted/device.in.h b/include/parted/device.in.h
> index 82d4104..1ce7a97 100644
> --- a/include/parted/device.in.h
> +++ b/include/parted/device.in.h
> @@ -87,6 +87,8 @@ struct _PedDevice {
>          int             dirty;
>          int             boot_dirty;
>
> +        int             pte_lba;
> +
>          PedCHSGeometry  hw_geom;
>          PedCHSGeometry  bios_geom;
>          short           host, did;
> diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c
> index d69377a..004efce 100644
> --- a/libparted/labels/gpt.c
> +++ b/libparted/labels/gpt.c
> @@ -499,6 +499,7 @@ gpt_probe (const PedDevice *dev)
>        || ped_device_read (dev, pth_raw, dev->length - 1,
> GPT_HEADER_SECTORS))
>      {
>        GuidPartitionTableHeader_t *gpt = pth_new_from_raw (dev, pth_raw);
> +      ((PedDevice*)dev)->pte_lba = gpt->PartitionEntryLBA;
>        if (gpt->Signature == PED_CPU_TO_LE64 (GPT_HEADER_SIGNATURE))
>          gpt_sig_found = 1;
>        pth_free (gpt);
> @@ -519,8 +520,8 @@ gpt_alloc (const PedDevice *dev)
>    if (!disk)
>      goto error;
>
> -  data_start = 2 + GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE /
> dev->sector_size;
> -  data_end = dev->length - 2
> +  data_start = dev->pte_lba + GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE /
> dev->sector_size;
> +  data_end = dev->length - dev->pte_lba
>      - GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE / dev->sector_size;
>
>    /* If the device is too small to accommodate GPT headers and one data
> @@ -743,14 +744,14 @@ _parse_header (PedDisk *disk, const
> GuidPartitionTableHeader_t *gpt,
>    last_usable = PED_LE64_TO_CPU (gpt->LastUsableLBA);
>
>    /* Need to check whether the volume has grown, the LastUsableLBA is
> -     normally set to disk->dev->length - 2 - ptes_size (at least for
> parted
> -     created volumes), where ptes_size is the number of entries *
> +     normally set to disk->dev->length - disb->dev->pte_lba - ptes_size
> (at least
> +     for parted created volumes), where ptes_size is the number of
> entries *
>       size of each entry / sector size or 16k / sector size, whatever the
> greater.
>       If the volume has grown, offer the user the chance to use the new
>       space or continue with the current usable area.  Only ask once per
>       parted invocation. */
>
> -  last_usable_if_grown = disk->dev->length - 2 - _ptes_sectors(disk, gpt);
> +  last_usable_if_grown = disk->dev->length - disk->dev->pte_lba -
> _ptes_sectors(disk, gpt);
>
>    if (last_usable <= first_usable
>        || disk->dev->length < last_usable)
> @@ -1192,7 +1193,7 @@ _generate_header (const PedDisk *disk, int
> alternate, uint32_t ptes_crc,
>      {
>        gpt->MyLBA = PED_CPU_TO_LE64 (1);
>        gpt->AlternateLBA = PED_CPU_TO_LE64 (gpt_disk_data->AlternateLBA);
> -      gpt->PartitionEntryLBA = PED_CPU_TO_LE64 (2);
> +      gpt->PartitionEntryLBA = PED_CPU_TO_LE64 (disk->dev->pte_lba);
>      }
>
>    gpt->FirstUsableLBA = PED_CPU_TO_LE64 (gpt_disk_data->data_area.start);
> @@ -1284,7 +1285,7 @@ gpt_write (const PedDisk *disk)
>    free (pth_raw);
>    if (!write_ok)
>      goto error_free_ptes;
> -  if (!ped_device_write (disk->dev, ptes, 2, ptes_sectors))
> +  if (!ped_device_write (disk->dev, ptes, disk->dev->pte_lba,
> ptes_sectors))
>      goto error_free_ptes;
>
>    /* Write Alternate PTH & PTEs */
> @@ -1962,7 +1963,7 @@ gpt_get_max_primary_partition_count (const PedDisk
> *disk)
>   *
>   * The number of possible partitions or supported partitions is:
>   * SP = FirstUsableLBA*Blocksize - 2*Blocksize / SizeOfPartitionEntry
> - * SP = Blocksize(FirstusableLBA - 2) / SizeOfPartitoinEntry
> + * SP = Blocksize(FirstusableLBA - PartitionEntryLBA) /
> SizeOfPartitoinEntry
>   */
>  static bool
>  gpt_get_max_supported_partition_count (const PedDisk *disk, int *max_n)
> @@ -1986,7 +1987,7 @@ gpt_get_max_supported_partition_count (const PedDisk
> *disk, int *max_n)
>          = PED_CPU_TO_LE32 (sizeof (GuidPartitionEntry_t));
>      }
>
> -  *max_n = (disk->dev->sector_size * (PED_LE64_TO_CPU
> (pth->FirstUsableLBA) - 2)
> +  *max_n = (disk->dev->sector_size * (PED_LE64_TO_CPU
> (pth->FirstUsableLBA) - PED_LE64_TO_CPU (pth->PartitionEntryLBA))
>              / PED_LE32_TO_CPU (pth->SizeOfPartitionEntry));
>    pth_free (pth);
>    return true;
> diff --git a/parted/parted.c b/parted/parted.c
> index a9426c4..cfd5de8 100644
> --- a/parted/parted.c
> +++ b/parted/parted.c
> @@ -511,6 +511,7 @@ do_mklabel (PedDevice** dev, PedDisk** diskp)
>  {
>          PedDisk*                disk;
>          const PedDiskType*      type = NULL;
> +        int                     pte_lba = 2;
>
>          if (*diskp)
>                  disk = *diskp;
> @@ -524,6 +525,11 @@ do_mklabel (PedDevice** dev, PedDisk** diskp)
>          if (!command_line_get_disk_type (_("New disk label type?"),
> &type))
>                  goto error;
>
> +        if (!command_line_get_integer (_("Starting LBA of partition entry
> array?"), &pte_lba))
> +                goto error;
> +
> +        (*dev)->pte_lba = pte_lba;
> +
>          if (disk) {
>                  if (!_disk_warn_busy (disk))
>                          goto error;
> --
> 2.7.3
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.alioth.debian.org/pipermail/parted-devel/attachments/20160321/dc2f66a2/attachment.html>


More information about the parted-devel mailing list