Patchwork add GPT partition support.

login
register
mail settings
Submitter Dinar Valeev
Date April 23, 2013, 11:06 a.m.
Message ID <CADqALGRR0JThxtpoH4un31ODFumhmhXTi5j+6JFCOrwWsY3MPg@mail.gmail.com>
Download mbox | patch
Permalink /patch/238887/
State Under Review
Headers show

Comments

Dinar Valeev - April 23, 2013, 11:06 a.m.
The patch adds GPT partitions support.
It looks for GPT_BASIC_DATA (parted default) and GPT_LINUX_NATIVE gpt
uuids.
---
 include/gpt-part.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 second/partition.c | 45 +++++++++++++++++++++++++++++++++--
 2 files changed, 113 insertions(+), 2 deletions(-)
 create mode 100644 include/gpt-part.h

+                        cpu_to_le64(part->end) -
cpu_to_le64(part->start) + 1, \
+                        prom_blksize, 1);
+        }
+    }
+}
+
+
 /* I don't know if it's possible to handle multisession and other multitrack
  * stuffs with the current OF disklabel package. This can still be implemented
  * with direct calls to atapi stuffs.
@@ -357,14 +395,17 @@ partitions_lookup(const char *device)
       goto bail;
      }

-     /* Read boot blocs */
-     if (prom_readblocks(disk, 0, 1, block_buffer) != 1) {
+     /* Read boot blocks */
+     if (prom_readblocks(disk, 0, 2, block_buffer) != 1) {
       prom_printf("Can't read boot blocks\n");
       goto bail;
      }
      if (desc->signature == MAC_DRIVER_MAGIC) {
       /* pdisk partition format */
       partition_mac_lookup(device, disk, prom_blksize, &list);
+     } else if (gpt_magic_present(block_buffer, prom_blksize)) {
+      /* gpt partition format */
+      partition_gpt_lookup(disk, prom_blksize, &list);
      } else if ((block_buffer[510] == 0x55) && (block_buffer[511] == 0xaa)) {
       /* fdisk partition format */
       partition_fdisk_lookup(device, disk, prom_blksize, &list);
--
1.8.1.4
Dinar Valeev - April 25, 2013, 8:29 a.m.
On Thu, Apr 25, 2013 at 6:12 AM, Tony Breeds <tonyb@au1.ibm.com> wrote:
> On 04/23/2013 09:06 PM, Dinar Valeev wrote:
>> The patch adds GPT partitions support.
>> It looks for GPT_BASIC_DATA (parted default) and GPT_LINUX_NATIVE gpt
>> uuids.
>
> This looks pretty good.  Thanks for that.
>
> I'm wondering how you tested this?  AFAICT there isn't any firmware
> support for GPT yet.
You're right, there is no firmware that capable to find PReP on GPT
(even UUID is not registered. Yet?). But we still can boot from 0x41
and later on scan GPT partitions.  So 0x41 is in pMBR (or
gpt_sync_mbr) The root shouldn't be there, so we don't have 2TB limits
for root devices.

I've tested that under KVM. With PReP in msdos and root with ext3 fs
on GPT (mbr doesn't have it). So I placed just dummy yaboot.conf under
/etc/yaboot.conf.

>
> Tony.
>
Tony Breeds - May 11, 2013, 4:52 a.m.
On Tue, Apr 23, 2013 at 01:06:56PM +0200, Dinar Valeev wrote:
> The patch adds GPT partitions support.
> It looks for GPT_BASIC_DATA (parted default) and GPT_LINUX_NATIVE gpt
> uuids.

You forgot to sign off the patch.

> ---
>  include/gpt-part.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  second/partition.c | 45 +++++++++++++++++++++++++++++++++--
>  2 files changed, 113 insertions(+), 2 deletions(-)
>  create mode 100644 include/gpt-part.h
> 
> diff --git a/include/gpt-part.h b/include/gpt-part.h
> new file mode 100644
> index 0000000..83b4f77
> --- /dev/null
> +++ b/include/gpt-part.h
> @@ -0,0 +1,70 @@
> +/*
> + *  gpt-part.h - Structure of gpt partition table
> + *
> + *  Copyright (C) 2013 Dinar Valeev
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, write to the Free Software
> + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
> + */
> +
> +#include <byteorder.h>
> +
> +#define GPT_LINUX_NATIVE \
> +((gpt_part_type_t){ cpu_to_le32(0x0FC63DAF), cpu_to_le16(0x8483),
> cpu_to_le16(0x4772),0x8E, 0x79, \

Hmm very damaged in transit :(

I've fixed all of these up as they were pretty simple.

Asside from that the patch looks good.

Yours Tony

Patch

diff --git a/include/gpt-part.h b/include/gpt-part.h
new file mode 100644
index 0000000..83b4f77
--- /dev/null
+++ b/include/gpt-part.h
@@ -0,0 +1,70 @@ 
+/*
+ *  gpt-part.h - Structure of gpt partition table
+ *
+ *  Copyright (C) 2013 Dinar Valeev
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <byteorder.h>
+
+#define GPT_LINUX_NATIVE \
+((gpt_part_type_t){ cpu_to_le32(0x0FC63DAF), cpu_to_le16(0x8483),
cpu_to_le16(0x4772),0x8E, 0x79, \
+    {0x3D, 0x69, 0xD8, 0x47, 0x7D, 0xE4}})
+#define GPT_LINUX_RAID \
+((gpt_part_type_t){ cpu_to_le32(0xa19d880f), cpu_to_le16(0x05fc),
cpu_to_le16(0x4d3b), 0xa0, 0x06, \
+    { 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e }})
+#define GPT_BASIC_DATA \
+((gpt_part_type_t){ cpu_to_le32 (0xebd0a0a2), cpu_to_le16 (0xb9e5),
cpu_to_le16 (0x4433), 0x87, 0xc0, \
+    { 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xC7 }})
+
+
+#define GPT_HEADER_SIGNATURE 0x5452415020494645LL
+
+typedef struct
+{
+ u32 data1;
+ u16 data2;
+ u16 data3;
+ u8  data4;
+ u8  data5;
+ u8  data6[6];
+} gpt_part_type_t;
+
+struct gpt_partition {
+    gpt_part_type_t type;           /* Partition type GUID */
+    u8  guid[16];                   /* Unique partition GUID */
+    u64 start;                      /* First partition LBA */
+    u64 end;                        /* End LBA */
+    u64 flags;                      /* Attribute flags */
+    char name[72];                  /* Partition name */
+} __attribute__ ((packed));
+
+struct gpt_header {
+    u64 signature;
+    u32 revision;
+    u32 header_size;
+    u32 header_crc32;
+    u32 reserved;
+    u64 primary;
+    u64 backup;
+    u64 start;
+    u64 end;
+    u8  dguid[16];
+    u64 partitions;
+    u32 maxpart;
+    u32 partentry_size;
+    u32 partentry_crc32;
+} __attribute__ ((packed));
diff --git a/second/partition.c b/second/partition.c
index eb383bc..f5be637 100644
--- a/second/partition.c
+++ b/second/partition.c
@@ -1,6 +1,8 @@ 
 /*
  *  partition.c - partition table support
  *
+ *  Copyright (C) 2013 Dinar Valeev
+ *
  *  Copyright (C) 2004 Sven Luther
  *
  *  Copyright (C) 2001, 2002 Ethan Benson
@@ -34,6 +36,7 @@ 
 #include "mac-part.h"
 #include "fdisk-part.h"
 #include "amiga-part.h"
+#include "gpt-part.h"
 #include "partition.h"
 #include "prom.h"
 #include "string.h"
@@ -184,6 +187,41 @@  partition_fdisk_lookup( const char *dev_name,
prom_handle disk,
      }
 }

+/* GPT partition format */
+static int gpt_magic_present(unsigned char *block_buffer, unsigned
int prom_blksize)
+{
+    struct gpt_header *header = (struct gpt_header *)(block_buffer +
prom_blksize);
+    return cpu_to_le64(header->signature) == GPT_HEADER_SIGNATURE;
+}
+
+static inline int
+guid_cmp (gpt_part_type_t left, gpt_part_type_t right)
+{
+    return memcmp(&left, &right, sizeof (gpt_part_type_t));
+}
+
+static void partition_gpt_lookup(prom_handle disk, unsigned int prom_blksize,
+                            struct partition_t **list)
+{
+    int partition;
+    struct gpt_header *header = (struct gpt_header *)(block_buffer +
prom_blksize);
+
+    if (prom_readblocks(disk, cpu_to_le64(header->partitions), 1,
block_buffer) != 1) {
+        prom_printf("Can't read GPT partition table %Lu\n",
header->partitions);
+        return;
+    }
+    struct gpt_partition *part = (struct gpt_partition *)(block_buffer);
+
+    for (partition = 1; partition <= cpu_to_le32(header->maxpart);
partition++, part++) {
+        if ((!guid_cmp(part->type,
GPT_BASIC_DATA))||(!guid_cmp(part->type,
GPT_LINUX_NATIVE))||(!guid_cmp(part->type, GPT_LINUX_RAID))) {
+            add_new_partition(list, partition, "Linux", 0,
le64_to_cpu(part->start), \