From: Dinar Valeev Date: Sat, 11 May 2013 08:20:09 +0000 (+0200) Subject: add GPT partition support. X-Git-Url: http://git.ozlabs.org/?p=yaboot.git;a=commitdiff_plain;h=daa52aabe1b4e8f4fc87a7e7153d98041636729d add GPT partition support. The patch adds GPT partitions support. It looks for GPT_BASIC_DATA (parted default) and GPT_LINUX_NATIVE gpt uuids. Signed-off-by: Dinar Valeev Signed-off-by: Tony Breeds --- 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 + +#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..7facbc4 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), \ + 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);