4 Copyright (C) 2000-2001 Dell Computer Corporation <Matt_Domsch@dell.com>
6 EFI GUID Partition Table handling
7 Per Intel EFI Specification v1.02
8 http://developer.intel.com/technology/efi/efi.htm
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #define _FILE_OFFSET_BITS 64
32 #include <sys/ioctl.h>
42 #if BYTE_ORDER == LITTLE_ENDIAN
43 # define __le16_to_cpu(x) (uint16_t)(x)
44 # define __le32_to_cpu(x) (uint32_t)(x)
45 # define __le64_to_cpu(x) (uint64_t)(x)
46 # define __cpu_to_le32(x) (x)
47 #elif BYTE_ORDER == BIG_ENDIAN
48 # define __le16_to_cpu(x) bswap_16(x)
49 # define __le32_to_cpu(x) bswap_32(x)
50 # define __le64_to_cpu(x) bswap_64(x)
51 # define __cpu_to_le32(x) bswap_32(x)
54 #ifndef BLKGETLASTSECT
55 #define BLKGETLASTSECT _IO(0x12,108) /* get last sector of block device */
58 #define BLKGETSIZE _IO(0x12,96) /* return device size */
61 #define BLKSSZGET _IO(0x12,104) /* get block device sector size */
64 #define BLKGETSIZE64 _IOR(0x12,114,sizeof(uint64_t)) /* return device size in bytes (u64 *arg) */
67 struct blkdev_ioctl_param {
69 size_t content_length;
70 char * block_contents;
74 * efi_crc32() - EFI version of crc32 function
75 * @buf: buffer to calculate crc32 of
76 * @len - length of buf
78 * Description: Returns EFI-style CRC32 value for @buf
80 * This function uses the little endian Ethernet polynomial
81 * but seeds the function with ~0, and xor's with ~0 at the end.
82 * Note, the EFI Specification, v1.02, has a reference to
83 * Dr. Dobbs Journal, May 1994 (actually it's in May 1992).
85 static inline uint32_t
86 efi_crc32(const void *buf, unsigned long len)
88 return (crc32(~0L, buf, len) ^ ~0L);
92 * is_pmbr_valid(): test Protective MBR for validity
93 * @mbr: pointer to a legacy mbr structure
95 * Description: Returns 1 if PMBR is valid, 0 otherwise.
96 * Validity depends on two things:
97 * 1) MSDOS signature is in the last two bytes of the MBR
98 * 2) One partition of type 0xEE is found
101 is_pmbr_valid(legacy_mbr *mbr)
103 int i, found = 0, signature = 0;
106 signature = (__le16_to_cpu(mbr->signature) == MSDOS_MBR_SIGNATURE);
107 for (i = 0; signature && i < 4; i++) {
108 if (mbr->partition[i].sys_type ==
109 EFI_PMBR_OSTYPE_EFI_GPT) {
114 return (signature && found);
118 /************************************************************
121 * - filedes is an open file descriptor, suitable for reading
124 * Last LBA value on success
127 * Try getting BLKGETSIZE64 and BLKSSZGET first,
128 * then BLKGETSIZE if necessary.
129 * Kernels 2.4.15-2.4.18 and 2.5.0-2.5.3 have a broken BLKGETSIZE64
130 * which returns the number of 512-byte sectors, not the size of
131 * the disk in bytes. Fixed in kernels 2.4.18-pre8 and 2.5.4-pre3.
132 ************************************************************/
134 _get_num_sectors(int filedes)
139 rc = ioctl(filedes, BLKGETSIZE64, &bytes);
141 return bytes / get_sector_size(filedes);
146 /************************************************************
147 * last_lba(): return number of last logical block of device
151 * Description: returns Last LBA value on success, 0 on error.
152 * Notes: The value st_blocks gives the size of the file
153 * in 512-byte blocks, which is OK if
154 * EFI_BLOCK_SIZE_SHIFT == 9.
155 ************************************************************/
158 last_lba(int filedes)
161 uint64_t sectors = 0;
163 memset(&s, 0, sizeof (s));
164 rc = fstat(filedes, &s);
166 fprintf(stderr, "last_lba() could not stat: %s\n",
171 if (S_ISBLK(s.st_mode)) {
172 sectors = _get_num_sectors(filedes);
175 "last_lba(): I don't know how to handle files with mode %x\n",
180 return sectors ? sectors - 1 : 0;
185 read_lastoddsector(int fd, void *buffer, size_t count)
188 struct blkdev_ioctl_param ioctl_param;
190 if (!buffer) return 0;
192 ioctl_param.block = 0; /* read the last sector */
193 ioctl_param.content_length = count;
194 ioctl_param.block_contents = buffer;
196 rc = ioctl(fd, BLKGETLASTSECT, &ioctl_param);
197 if (rc == -1) perror("read failed");
203 read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
205 int sector_size = get_sector_size(fd);
206 off_t offset = lba * sector_size;
210 if (lseek(fd, offset, SEEK_SET) < 0)
212 bytesread = read(fd, buffer, bytes);
214 lastlba = last_lba(fd);
218 /* Kludge. This is necessary to read/write the last
219 block of an odd-sized disk, until Linux 2.5.x kernel fixes.
220 This is only used by gpt.c, and only to read
221 one sector, so we don't have to be fancy.
223 if (!bytesread && !(lastlba & 1) && lba == lastlba) {
224 bytesread = read_lastoddsector(fd, buffer, bytes);
230 * alloc_read_gpt_entries(): reads partition entries from disk
231 * @fd is an open file descriptor to the whole disk
232 * @gpt is a buffer into which the GPT will be put
233 * Description: Returns ptes on success, NULL on error.
234 * Allocates space for PTEs based on information found in @gpt.
235 * Notes: remember to free pte when you're done!
238 alloc_read_gpt_entries(int fd, gpt_header * gpt)
241 size_t count = __le32_to_cpu(gpt->num_partition_entries) *
242 __le32_to_cpu(gpt->sizeof_partition_entry);
244 if (!count) return NULL;
246 if (aligned_malloc((void **)&pte, get_sector_size(fd), &count))
248 memset(pte, 0, count);
250 if (!read_lba(fd, __le64_to_cpu(gpt->partition_entry_lba), pte,
259 * alloc_read_gpt_header(): Allocates GPT header, reads into it from disk
260 * @fd is an open file descriptor to the whole disk
261 * @lba is the Logical Block Address of the partition table
263 * Description: returns GPT header on success, NULL on error. Allocates
264 * and fills a GPT header starting at @ from @bdev.
265 * Note: remember to free gpt when finished with it.
268 alloc_read_gpt_header(int fd, uint64_t lba)
271 size_t size = sizeof (gpt_header);
272 if (aligned_malloc((void **)&gpt, get_sector_size(fd), &size))
274 memset(gpt, 0, size);
275 if (!read_lba(fd, lba, gpt, size)) {
284 * is_gpt_valid() - tests one GPT header and PTEs for validity
285 * @fd is an open file descriptor to the whole disk
286 * @lba is the logical block address of the GPT header to test
287 * @gpt is a GPT header ptr, filled on return.
288 * @ptes is a PTEs ptr, filled on return.
290 * Description: returns 1 if valid, 0 on error.
291 * If valid, returns pointers to newly allocated GPT header and PTEs.
294 is_gpt_valid(int fd, uint64_t lba,
295 gpt_header ** gpt, gpt_entry ** ptes)
297 int rc = 0; /* default to not valid */
298 uint32_t crc, origcrc;
302 if (!(*gpt = alloc_read_gpt_header(fd, lba)))
305 /* Check the GUID Partition Table signature */
306 if (__le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) {
308 printf("GUID Partition Table Header signature is wrong: %" PRIx64" != %" PRIx64 "\n",
309 __le64_to_cpu((*gpt)->signature), GUID_PT_HEADER_SIGNATURE);
316 /* Check the GUID Partition Table Header CRC */
317 origcrc = __le32_to_cpu((*gpt)->header_crc32);
318 (*gpt)->header_crc32 = 0;
319 crc = efi_crc32(*gpt, __le32_to_cpu((*gpt)->header_size));
320 if (crc != origcrc) {
321 // printf( "GPTH CRC check failed, %x != %x.\n", origcrc, crc);
322 (*gpt)->header_crc32 = __cpu_to_le32(origcrc);
327 (*gpt)->header_crc32 = __cpu_to_le32(origcrc);
329 /* Check that the my_lba entry points to the LBA
330 * that contains the GPT we read */
331 if (__le64_to_cpu((*gpt)->my_lba) != lba) {
333 printf( "my_lba % PRIx64 "x != lba %"PRIx64 "x.\n",
334 __le64_to_cpu((*gpt)->my_lba), lba);
341 /* Check that sizeof_partition_entry has the correct value */
342 if (__le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) {
343 // printf("GUID partition entry size check failed.\n");
349 if (!(*ptes = alloc_read_gpt_entries(fd, *gpt))) {
355 /* Check the GUID Partition Entry Array CRC */
356 crc = efi_crc32(*ptes,
357 __le32_to_cpu((*gpt)->num_partition_entries) *
358 __le32_to_cpu((*gpt)->sizeof_partition_entry));
359 if (crc != __le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
360 // printf("GUID Partitition Entry Array CRC check failed.\n");
368 /* We're done, all's well */
372 * compare_gpts() - Search disk for valid GPT headers and PTEs
373 * @pgpt is the primary GPT header
374 * @agpt is the alternate GPT header
375 * @lastlba is the last LBA number
376 * Description: Returns nothing. Sanity checks pgpt and agpt fields
377 * and prints warnings on discrepancies.
381 compare_gpts(gpt_header *pgpt, gpt_header *agpt, uint64_t lastlba)
386 if (__le64_to_cpu(pgpt->my_lba) != __le64_to_cpu(agpt->alternate_lba)) {
389 "GPT:Primary header LBA != Alt. header alternate_lba\n");
391 fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n",
392 __le64_to_cpu(pgpt->my_lba),
393 __le64_to_cpu(agpt->alternate_lba));
396 if (__le64_to_cpu(pgpt->alternate_lba) != __le64_to_cpu(agpt->my_lba)) {
399 "GPT:Primary header alternate_lba != Alt. header my_lba\n");
401 fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n",
402 __le64_to_cpu(pgpt->alternate_lba),
403 __le64_to_cpu(agpt->my_lba));
406 if (__le64_to_cpu(pgpt->first_usable_lba) !=
407 __le64_to_cpu(agpt->first_usable_lba)) {
409 fprintf(stderr, "GPT:first_usable_lbas don't match.\n");
411 fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n",
412 __le64_to_cpu(pgpt->first_usable_lba),
413 __le64_to_cpu(agpt->first_usable_lba));
416 if (__le64_to_cpu(pgpt->last_usable_lba) !=
417 __le64_to_cpu(agpt->last_usable_lba)) {
419 fprintf(stderr, "GPT:last_usable_lbas don't match.\n");
421 fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n",
422 __le64_to_cpu(pgpt->last_usable_lba),
423 __le64_to_cpu(agpt->last_usable_lba));
426 if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) {
428 fprintf(stderr, "GPT:disk_guids don't match.\n");
430 if (__le32_to_cpu(pgpt->num_partition_entries) !=
431 __le32_to_cpu(agpt->num_partition_entries)) {
433 fprintf(stderr, "GPT:num_partition_entries don't match: "
435 __le32_to_cpu(pgpt->num_partition_entries),
436 __le32_to_cpu(agpt->num_partition_entries));
438 if (__le32_to_cpu(pgpt->sizeof_partition_entry) !=
439 __le32_to_cpu(agpt->sizeof_partition_entry)) {
442 "GPT:sizeof_partition_entry values don't match: "
444 __le32_to_cpu(pgpt->sizeof_partition_entry),
445 __le32_to_cpu(agpt->sizeof_partition_entry));
447 if (__le32_to_cpu(pgpt->partition_entry_array_crc32) !=
448 __le32_to_cpu(agpt->partition_entry_array_crc32)) {
451 "GPT:partition_entry_array_crc32 values don't match: "
453 __le32_to_cpu(pgpt->partition_entry_array_crc32),
454 __le32_to_cpu(agpt->partition_entry_array_crc32));
456 if (__le64_to_cpu(pgpt->alternate_lba) != lastlba) {
459 "GPT:Primary header thinks Alt. header is not at the end of the disk.\n");
461 fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n",
462 __le64_to_cpu(pgpt->alternate_lba), lastlba);
466 if (__le64_to_cpu(agpt->my_lba) != lastlba) {
469 "GPT:Alternate GPT header not at the end of the disk.\n");
471 fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n",
472 __le64_to_cpu(agpt->my_lba), lastlba);
478 "GPT: Use GNU Parted to correct GPT errors.\n");
483 * find_valid_gpt() - Search disk for valid GPT headers and PTEs
484 * @fd is an open file descriptor to the whole disk
485 * @gpt is a GPT header ptr, filled on return.
486 * @ptes is a PTEs ptr, filled on return.
487 * Description: Returns 1 if valid, 0 on error.
488 * If valid, returns pointers to newly allocated GPT header and PTEs.
489 * Validity depends on finding either the Primary GPT header and PTEs valid,
490 * or the Alternate GPT header and PTEs valid, and the PMBR valid.
493 find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes)
495 int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
496 gpt_header *pgpt = NULL, *agpt = NULL;
497 gpt_entry *pptes = NULL, *aptes = NULL;
498 legacy_mbr *legacymbr = NULL;
499 size_t size = sizeof(legacy_mbr);
504 if (!(lastlba = last_lba(fd)))
506 good_pgpt = is_gpt_valid(fd, GPT_PRIMARY_PARTITION_TABLE_LBA,
509 good_agpt = is_gpt_valid(fd,
510 __le64_to_cpu(pgpt->alternate_lba),
513 good_agpt = is_gpt_valid(fd, lastlba,
518 good_agpt = is_gpt_valid(fd, lastlba,
522 /* The obviously unsuccessful case */
523 if (!good_pgpt && !good_agpt) {
527 /* This will be added to the EFI Spec. per Intel after v1.02. */
528 if (aligned_malloc((void **)&legacymbr, get_sector_size(fd),
530 memset(legacymbr, 0, size);
531 read_lba(fd, 0, (uint8_t *) legacymbr, size);
532 good_pmbr = is_pmbr_valid(legacymbr);
537 /* Failure due to bad PMBR */
538 if ((good_pgpt || good_agpt) && !good_pmbr && !force_gpt) {
540 " Warning: Disk has a valid GPT signature "
541 "but invalid PMBR.\n"
542 " Assuming this disk is *not* a GPT disk anymore.\n"
543 " Use gpt kernel option to override. "
544 "Use GNU Parted to correct disk.\n");
548 /* Would fail due to bad PMBR, but force GPT anyhow */
549 if ((good_pgpt || good_agpt) && !good_pmbr && force_gpt) {
551 " Warning: Disk has a valid GPT signature but "
553 " Use GNU Parted to correct disk.\n"
554 " gpt option taken, disk treated as GPT.\n");
557 compare_gpts(pgpt, agpt, lastlba);
560 if (good_pgpt && (good_pmbr || force_gpt)) {
563 if (agpt) { free(agpt); agpt = NULL; }
564 if (aptes) { free(aptes); aptes = NULL; }
567 "Alternate GPT is invalid, "
568 "using primary GPT.\n");
572 else if (good_agpt && (good_pmbr || force_gpt)) {
575 if (pgpt) { free(pgpt); pgpt = NULL; }
576 if (pptes) { free(pptes); pptes = NULL; }
578 "Primary GPT is invalid, using alternate GPT.\n");
583 if (pgpt) { free(pgpt); pgpt=NULL; }
584 if (agpt) { free(agpt); agpt=NULL; }
585 if (pptes) { free(pptes); pptes=NULL; }
586 if (aptes) { free(aptes); aptes=NULL; }
595 * @all - slice with start/size of whole disk
597 * 0 if this isn't our partition table
598 * number of partitions if successful
602 read_gpt_pt (int fd, __attribute__((unused)) struct slice all,
603 struct slice *sp, unsigned int ns)
605 gpt_header *gpt = NULL;
606 gpt_entry *ptes = NULL;
609 int last_used_index=-1;
610 int sector_size_mul = get_sector_size(fd)/512;
612 if (!find_valid_gpt (fd, &gpt, &ptes) || !gpt || !ptes) {
620 for (i = 0; i < __le32_to_cpu(gpt->num_partition_entries) && i < ns; i++) {
621 if (!efi_guidcmp (NULL_GUID, ptes[i].partition_type_guid)) {
626 sp[n].start = sector_size_mul *
627 __le64_to_cpu(ptes[i].starting_lba);
628 sp[n].size = sector_size_mul *
629 (__le64_to_cpu(ptes[i].ending_lba) -
630 __le64_to_cpu(ptes[i].starting_lba) + 1);
637 return last_used_index+1;