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, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #define _FILE_OFFSET_BITS 64
33 #include <sys/ioctl.h>
42 #if BYTE_ORDER == LITTLE_ENDIAN
43 # define __le16_to_cpu(x) (x)
44 # define __le32_to_cpu(x) (x)
45 # define __le64_to_cpu(x) (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 * sector size, or 512.
125 ************************************************************/
127 get_sector_size(int filedes)
129 int rc, sector_size = 512;
131 rc = ioctl(filedes, BLKSSZGET, §or_size);
137 /************************************************************
140 * - filedes is an open file descriptor, suitable for reading
143 * Last LBA value on success
146 * Try getting BLKGETSIZE64 and BLKSSZGET first,
147 * then BLKGETSIZE if necessary.
148 * Kernels 2.4.15-2.4.18 and 2.5.0-2.5.3 have a broken BLKGETSIZE64
149 * which returns the number of 512-byte sectors, not the size of
150 * the disk in bytes. Fixed in kernels 2.4.18-pre8 and 2.5.4-pre3.
151 ************************************************************/
153 _get_num_sectors(int filedes)
158 rc = ioctl(filedes, BLKGETSIZE64, &bytes);
160 return bytes / get_sector_size(filedes);
165 /************************************************************
166 * last_lba(): return number of last logical block of device
170 * Description: returns Last LBA value on success, 0 on error.
171 * Notes: The value st_blocks gives the size of the file
172 * in 512-byte blocks, which is OK if
173 * EFI_BLOCK_SIZE_SHIFT == 9.
174 ************************************************************/
177 last_lba(int filedes)
180 uint64_t sectors = 0;
182 memset(&s, 0, sizeof (s));
183 rc = fstat(filedes, &s);
185 fprintf(stderr, "last_lba() could not stat: %s\n",
190 if (S_ISBLK(s.st_mode)) {
191 sectors = _get_num_sectors(filedes);
194 "last_lba(): I don't know how to handle files with mode %x\n",
199 return sectors ? sectors - 1 : 0;
204 read_lastoddsector(int fd, uint64_t lba, void *buffer, size_t count)
207 struct blkdev_ioctl_param ioctl_param;
209 if (!buffer) return 0;
211 ioctl_param.block = 0; /* read the last sector */
212 ioctl_param.content_length = count;
213 ioctl_param.block_contents = buffer;
215 rc = ioctl(fd, BLKGETLASTSECT, &ioctl_param);
216 if (rc == -1) perror("read failed");
222 read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
224 int sector_size = get_sector_size(fd);
225 off_t offset = lba * sector_size;
229 lseek(fd, offset, SEEK_SET);
230 bytesread = read(fd, buffer, bytes);
232 lastlba = last_lba(fd);
236 /* Kludge. This is necessary to read/write the last
237 block of an odd-sized disk, until Linux 2.5.x kernel fixes.
238 This is only used by gpt.c, and only to read
239 one sector, so we don't have to be fancy.
241 if (!bytesread && !(lastlba & 1) && lba == lastlba) {
242 bytesread = read_lastoddsector(fd, lba, buffer, bytes);
248 * alloc_read_gpt_entries(): reads partition entries from disk
249 * @fd is an open file descriptor to the whole disk
250 * @gpt is a buffer into which the GPT will be put
251 * Description: Returns ptes on success, NULL on error.
252 * Allocates space for PTEs based on information found in @gpt.
253 * Notes: remember to free pte when you're done!
256 alloc_read_gpt_entries(int fd, gpt_header * gpt)
259 size_t count = __le32_to_cpu(gpt->num_partition_entries) *
260 __le32_to_cpu(gpt->sizeof_partition_entry);
262 if (!count) return NULL;
264 pte = (gpt_entry *)malloc(count);
267 memset(pte, 0, count);
269 if (!read_lba(fd, __le64_to_cpu(gpt->partition_entry_lba), pte,
278 * alloc_read_gpt_header(): Allocates GPT header, reads into it from disk
279 * @fd is an open file descriptor to the whole disk
280 * @lba is the Logical Block Address of the partition table
282 * Description: returns GPT header on success, NULL on error. Allocates
283 * and fills a GPT header starting at @ from @bdev.
284 * Note: remember to free gpt when finished with it.
287 alloc_read_gpt_header(int fd, uint64_t lba)
291 malloc(sizeof (gpt_header));
294 memset(gpt, 0, sizeof (*gpt));
295 if (!read_lba(fd, lba, gpt, sizeof (gpt_header))) {
304 * is_gpt_valid() - tests one GPT header and PTEs for validity
305 * @fd is an open file descriptor to the whole disk
306 * @lba is the logical block address of the GPT header to test
307 * @gpt is a GPT header ptr, filled on return.
308 * @ptes is a PTEs ptr, filled on return.
310 * Description: returns 1 if valid, 0 on error.
311 * If valid, returns pointers to newly allocated GPT header and PTEs.
314 is_gpt_valid(int fd, uint64_t lba,
315 gpt_header ** gpt, gpt_entry ** ptes)
317 int rc = 0; /* default to not valid */
318 uint32_t crc, origcrc;
322 if (!(*gpt = alloc_read_gpt_header(fd, lba)))
325 /* Check the GUID Partition Table signature */
326 if (__le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) {
328 printf("GUID Partition Table Header signature is wrong: %" PRIx64" != %" PRIx64 "\n",
329 __le64_to_cpu((*gpt)->signature), GUID_PT_HEADER_SIGNATURE);
336 /* Check the GUID Partition Table Header CRC */
337 origcrc = __le32_to_cpu((*gpt)->header_crc32);
338 (*gpt)->header_crc32 = 0;
339 crc = efi_crc32(*gpt, __le32_to_cpu((*gpt)->header_size));
340 if (crc != origcrc) {
341 // printf( "GPTH CRC check failed, %x != %x.\n", origcrc, crc);
342 (*gpt)->header_crc32 = __cpu_to_le32(origcrc);
347 (*gpt)->header_crc32 = __cpu_to_le32(origcrc);
349 /* Check that the my_lba entry points to the LBA
350 * that contains the GPT we read */
351 if (__le64_to_cpu((*gpt)->my_lba) != lba) {
353 printf( "my_lba % PRIx64 "x != lba %"PRIx64 "x.\n",
354 __le64_to_cpu((*gpt)->my_lba), lba);
361 /* Check that sizeof_partition_entry has the correct value */
362 if (__le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) {
363 // printf("GUID partition entry size check failed.\n");
370 /* Check that sizeof_partition_entry has the correct value */
371 if (__le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) {
372 // printf("GUID partition entry size check failed.\n");
379 if (!(*ptes = alloc_read_gpt_entries(fd, *gpt))) {
385 /* Check the GUID Partition Entry Array CRC */
386 crc = efi_crc32(*ptes,
387 __le32_to_cpu((*gpt)->num_partition_entries) *
388 __le32_to_cpu((*gpt)->sizeof_partition_entry));
389 if (crc != __le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
390 // printf("GUID Partitition Entry Array CRC check failed.\n");
398 /* We're done, all's well */
402 * compare_gpts() - Search disk for valid GPT headers and PTEs
403 * @pgpt is the primary GPT header
404 * @agpt is the alternate GPT header
405 * @lastlba is the last LBA number
406 * Description: Returns nothing. Sanity checks pgpt and agpt fields
407 * and prints warnings on discrepancies.
411 compare_gpts(gpt_header *pgpt, gpt_header *agpt, uint64_t lastlba)
416 if (__le64_to_cpu(pgpt->my_lba) != __le64_to_cpu(agpt->alternate_lba)) {
419 "GPT:Primary header LBA != Alt. header alternate_lba\n");
421 fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n",
422 __le64_to_cpu(pgpt->my_lba),
423 __le64_to_cpu(agpt->alternate_lba));
426 if (__le64_to_cpu(pgpt->alternate_lba) != __le64_to_cpu(agpt->my_lba)) {
429 "GPT:Primary header alternate_lba != Alt. header my_lba\n");
431 fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n",
432 __le64_to_cpu(pgpt->alternate_lba),
433 __le64_to_cpu(agpt->my_lba));
436 if (__le64_to_cpu(pgpt->first_usable_lba) !=
437 __le64_to_cpu(agpt->first_usable_lba)) {
439 fprintf(stderr, "GPT:first_usable_lbas don't match.\n");
441 fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n",
442 __le64_to_cpu(pgpt->first_usable_lba),
443 __le64_to_cpu(agpt->first_usable_lba));
446 if (__le64_to_cpu(pgpt->last_usable_lba) !=
447 __le64_to_cpu(agpt->last_usable_lba)) {
449 fprintf(stderr, "GPT:last_usable_lbas don't match.\n");
451 fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n",
452 __le64_to_cpu(pgpt->last_usable_lba),
453 __le64_to_cpu(agpt->last_usable_lba));
456 if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) {
458 fprintf(stderr, "GPT:disk_guids don't match.\n");
460 if (__le32_to_cpu(pgpt->num_partition_entries) !=
461 __le32_to_cpu(agpt->num_partition_entries)) {
463 fprintf(stderr, "GPT:num_partition_entries don't match: "
465 __le32_to_cpu(pgpt->num_partition_entries),
466 __le32_to_cpu(agpt->num_partition_entries));
468 if (__le32_to_cpu(pgpt->sizeof_partition_entry) !=
469 __le32_to_cpu(agpt->sizeof_partition_entry)) {
472 "GPT:sizeof_partition_entry values don't match: "
474 __le32_to_cpu(pgpt->sizeof_partition_entry),
475 __le32_to_cpu(agpt->sizeof_partition_entry));
477 if (__le32_to_cpu(pgpt->partition_entry_array_crc32) !=
478 __le32_to_cpu(agpt->partition_entry_array_crc32)) {
481 "GPT:partition_entry_array_crc32 values don't match: "
483 __le32_to_cpu(pgpt->partition_entry_array_crc32),
484 __le32_to_cpu(agpt->partition_entry_array_crc32));
486 if (__le64_to_cpu(pgpt->alternate_lba) != lastlba) {
489 "GPT:Primary header thinks Alt. header is not at the end of the disk.\n");
491 fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n",
492 __le64_to_cpu(pgpt->alternate_lba), lastlba);
496 if (__le64_to_cpu(agpt->my_lba) != lastlba) {
499 "GPT:Alternate GPT header not at the end of the disk.\n");
501 fprintf(stderr, "GPT:%" PRIx64 " != %" PRIx64 "\n",
502 __le64_to_cpu(agpt->my_lba), lastlba);
508 "GPT: Use GNU Parted to correct GPT errors.\n");
513 * find_valid_gpt() - Search disk for valid GPT headers and PTEs
514 * @fd is an open file descriptor to the whole disk
515 * @gpt is a GPT header ptr, filled on return.
516 * @ptes is a PTEs ptr, filled on return.
517 * Description: Returns 1 if valid, 0 on error.
518 * If valid, returns pointers to newly allocated GPT header and PTEs.
519 * Validity depends on finding either the Primary GPT header and PTEs valid,
520 * or the Alternate GPT header and PTEs valid, and the PMBR valid.
523 find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes)
525 extern int force_gpt;
526 int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
527 gpt_header *pgpt = NULL, *agpt = NULL;
528 gpt_entry *pptes = NULL, *aptes = NULL;
529 legacy_mbr *legacymbr = NULL;
534 if (!(lastlba = last_lba(fd)))
536 good_pgpt = is_gpt_valid(fd, GPT_PRIMARY_PARTITION_TABLE_LBA,
539 good_agpt = is_gpt_valid(fd,
540 __le64_to_cpu(pgpt->alternate_lba),
543 good_agpt = is_gpt_valid(fd, lastlba,
548 good_agpt = is_gpt_valid(fd, lastlba,
552 /* The obviously unsuccessful case */
553 if (!good_pgpt && !good_agpt) {
557 /* This will be added to the EFI Spec. per Intel after v1.02. */
558 legacymbr = malloc(sizeof (*legacymbr));
560 memset(legacymbr, 0, sizeof (*legacymbr));
561 read_lba(fd, 0, (uint8_t *) legacymbr,
562 sizeof (*legacymbr));
563 good_pmbr = is_pmbr_valid(legacymbr);
568 /* Failure due to bad PMBR */
569 if ((good_pgpt || good_agpt) && !good_pmbr && !force_gpt) {
571 " Warning: Disk has a valid GPT signature "
572 "but invalid PMBR.\n"
573 " Assuming this disk is *not* a GPT disk anymore.\n"
574 " Use gpt kernel option to override. "
575 "Use GNU Parted to correct disk.\n");
579 /* Would fail due to bad PMBR, but force GPT anyhow */
580 if ((good_pgpt || good_agpt) && !good_pmbr && force_gpt) {
582 " Warning: Disk has a valid GPT signature but "
584 " Use GNU Parted to correct disk.\n"
585 " gpt option taken, disk treated as GPT.\n");
588 compare_gpts(pgpt, agpt, lastlba);
591 if (good_pgpt && (good_pmbr || force_gpt)) {
594 if (agpt) { free(agpt); agpt = NULL; }
595 if (aptes) { free(aptes); aptes = NULL; }
598 "Alternate GPT is invalid, "
599 "using primary GPT.\n");
603 else if (good_agpt && (good_pmbr || force_gpt)) {
606 if (pgpt) { free(pgpt); pgpt = NULL; }
607 if (pptes) { free(pptes); pptes = NULL; }
609 "Primary GPT is invalid, using alternate GPT.\n");
614 if (pgpt) { free(pgpt); pgpt=NULL; }
615 if (agpt) { free(agpt); agpt=NULL; }
616 if (pptes) { free(pptes); pptes=NULL; }
617 if (aptes) { free(aptes); aptes=NULL; }
626 * @all - slice with start/size of whole disk
628 * 0 if this isn't our partition table
629 * number of partitions if successful
633 read_gpt_pt (int fd, struct slice all, struct slice *sp, int ns)
635 gpt_header *gpt = NULL;
636 gpt_entry *ptes = NULL;
639 int last_used_index=-1;
640 int sector_size_mul = get_sector_size(fd)/512;
642 if (!find_valid_gpt (fd, &gpt, &ptes) || !gpt || !ptes) {
650 for (i = 0; i < __le32_to_cpu(gpt->num_partition_entries) && i < ns; i++) {
651 if (!efi_guidcmp (NULL_GUID, ptes[i].partition_type_guid)) {
656 sp[n].start = sector_size_mul *
657 __le64_to_cpu(ptes[i].starting_lba);
658 sp[n].size = sector_size_mul *
659 (__le64_to_cpu(ptes[i].ending_lba) -
660 __le64_to_cpu(ptes[i].starting_lba) + 1);
667 return last_used_index+1;