Ejemplo n.º 1
0
int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
				disk_partition_t * info)
{
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
	gpt_entry *gpt_pte = NULL;

	/* "part" argument must be at least 1 */
	if (!dev_desc || !info || part < 1) {
		printf("%s: Invalid Argument(s)\n", __func__);
		return -1;
	}

	/* This function validates AND fills in the GPT header and PTE */
	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
			gpt_head, &gpt_pte) != 1) {
		printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
		if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
				 gpt_head, &gpt_pte) != 1) {
			printf("%s: *** ERROR: Invalid Backup GPT ***\n",
			       __func__);
			return -1;
		} else {
			printf("%s: ***        Using Backup GPT ***\n",
			       __func__);
		}
	}

	if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
	    !is_pte_valid(&gpt_pte[part - 1])) {
		debug("%s: *** ERROR: Invalid partition number %d ***\n",
			__func__, part);
		free(gpt_pte);
		return -1;
	}

	/* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */
	info->start = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].starting_lba);
	/* The ending LBA is inclusive, to calculate size, add 1 to it */
	info->size = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1
		     - info->start;
	info->blksz = dev_desc->blksz;

	sprintf((char *)info->name, "%s",
			print_efiname(&gpt_pte[part - 1]));
	sprintf((char *)info->type, "U-Boot");
	info->bootable = is_bootable(&gpt_pte[part - 1]);
#ifdef CONFIG_PARTITION_UUIDS
	uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid,
			UUID_STR_FORMAT_GUID);
#endif

	debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__,
	      info->start, info->size, info->name);

	/* Remember to free pte */
	free(gpt_pte);
	return 0;
}
Ejemplo n.º 2
0
void print_part_efi(block_dev_desc_t * dev_desc)
{
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
	gpt_entry *gpt_pte = NULL;
	int i = 0;
	char uuid[37];
	unsigned char *uuid_bin;

	if (!dev_desc) {
		printf("%s: Invalid Argument(s)\n", __func__);
		return;
	}
	/* This function validates AND fills in the GPT header and PTE */
	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
			 gpt_head, &gpt_pte) != 1) {
		printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
		if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
				 gpt_head, &gpt_pte) != 1) {
			printf("%s: *** ERROR: Invalid Backup GPT ***\n",
			       __func__);
			return;
		} else {
			printf("%s: ***        Using Backup GPT ***\n",
			       __func__);
		}
	}

	debug("%s: gpt-entry at %p\n", __func__, gpt_pte);

	printf("Part\tStart LBA\tEnd LBA\t\tName\n");
	printf("\tAttributes\n");
	printf("\tType GUID\n");
	printf("\tPartition GUID\n");

	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
		/* Stop at the first non valid PTE */
		if (!is_pte_valid(&gpt_pte[i]))
			break;

		printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"\n", (i + 1),
			le64_to_cpu(gpt_pte[i].starting_lba),
			le64_to_cpu(gpt_pte[i].ending_lba),
			print_efiname(&gpt_pte[i]));
		printf("\tattrs:\t0x%016llx\n", gpt_pte[i].attributes.raw);
		uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b;
		uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
		printf("\ttype:\t%s\n", uuid);
		uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b;
		uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
		printf("\tguid:\t%s\n", uuid);
	}

	/* Remember to free pte */
	free(gpt_pte);
	return;
}
Ejemplo n.º 3
0
int get_partition_info_efi_with_partnum(block_dev_desc_t * dev_desc, int part,
		disk_partition_t * info, unsigned long total, unsigned long sdidx, int sdpart, disk_partition_t *sdinfo)
{
	gpt_header gpt_head;
	gpt_entry *pgpt_pte = NULL;

	/* "part" argument must be at least 1 */
	if (!dev_desc || !info || part < 1) {
		printf("%s: Invalid Argument(s)\n", __FUNCTION__);
		return -1;
	}

	/* This function validates AND fills in the GPT header and PTE */
	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
			&(gpt_head), &pgpt_pte) != 1) {
		printf("%s: *** ERROR: Invalid Main GPT ***\n", __FUNCTION__);
		if(is_gpt_valid(dev_desc, dev_desc->lba -1, &(gpt_head), &pgpt_pte) != 1){
			printf("%s: *** ERROR: Invalid alternate GPT ***\n", __FUNCTION__);
			return -1;

		}
	}

	/* The ulong casting limits the maximum disk size to 2 TB */
	info->start = (ulong) le64_to_int((pgpt_pte)[part - 1].starting_lba);
	/* The ending LBA is inclusive, to calculate size, add 1 to it */
	info->size = ((ulong)le64_to_int((pgpt_pte)[part - 1].ending_lba) + 1)
		     - info->start;
	info->blksz = GPT_BLOCK_SIZE;

	sprintf((char *)info->name, "%s%d", GPT_ENTRY_NAME, part);
	sprintf((char *)info->type, "U-Boot");

	debug("%s: start 0x%lX, size 0x%lX, name %s", __FUNCTION__,
		info->start, info->size, info->name);

	/* copy sd info */
	if (sdidx < (le32_to_int(gpt_head.num_partition_entries))) {
		sdinfo->start = (ulong) le64_to_int((pgpt_pte)[sdpart - 1].starting_lba);
		sdinfo->size = ((ulong)le64_to_int((pgpt_pte)[sdpart - 1].ending_lba) + 1) - sdinfo->start;
	}

	/* Remember to free pte */
	if (pgpt_pte != NULL) {
		debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
		free(pgpt_pte);
	}

	if (total == 0)
		return 0;
	else if (total != le32_to_int(gpt_head.num_partition_entries))
		return -1;
	else
		return 0;
}
Ejemplo n.º 4
0
int get_partition_num_efi(block_dev_desc_t *dev_desc)
{
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
	gpt_entry *gpt_pte = NULL;
	int i;

	if (!dev_desc) {
		printf("%s: Invalid Argument(s)\n", __func__);
		return 0;
	}
	/* This function validates AND fills in the GPT header and PTE */
	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
			 gpt_head, &gpt_pte) != 1) {
		printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
		return 0;
	}

	for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++)
		if (!is_pte_valid(&gpt_pte[i]))
			break;

	/* Remember to free pte */
	free(gpt_pte);
	return i;
}
Ejemplo n.º 5
0
int find_part_efi(block_dev_desc_t * dev_desc, char *name, disk_partition_t * info)
{
    ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
    gpt_entry *gpt_pte = NULL;
    int i = 0, pos = 0;

    /* "part" argument must be at least 1 */
    if (!dev_desc || !info ) {
        printf("%s: Invalid Argument(s)\n", __func__);
        return -1;
    }

    /* This function validates AND fills in the GPT header and PTE */
    if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
                     gpt_head, &gpt_pte) != 1) {
        printf("%s: *** ERROR: Invalid Primary GPT ***\n", __func__);
        if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
                         gpt_head, &gpt_pte) != 1) {
            printf("%s: *** ERROR: Invalid Backup GPT ***\n",
                   __func__);
            return -1;
        }
    }
    for (i = 0; i < le32_to_int(gpt_head->num_partition_entries); i++) {

        if (is_pte_valid(&gpt_pte[i]) && !(strcmp(name, print_efiname(&gpt_pte[i])))) {

            /* The ulong casting limits the maximum disk size to 2 TB */
            info->start = (ulong) le64_to_int(gpt_pte[i].starting_lba);
            /* The ending LBA is inclusive, to calculate size, add 1 to it */
            info->size = ((ulong)le64_to_int(gpt_pte[i].ending_lba) + 1) - info->start;
            info->blksz = GPT_BLOCK_SIZE;

            sprintf((char *)info->name, "%s",
                    print_efiname(&gpt_pte[i]));
            sprintf((char *)info->type, "U-Boot");
            pos = i + 1;
        }
    }

    /* Remember to free pte */
    free(gpt_pte);
    return pos;
}
Ejemplo n.º 6
0
int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
                           disk_partition_t * info)
{
    ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
    gpt_entry *gpt_pte = NULL;

    /* "part" argument must be at least 1 */
    if (!dev_desc || !info || part < 1) {
        printf("%s: Invalid Argument(s)\n", __func__);
        return -1;
    }

    /* This function validates AND fills in the GPT header and PTE */
    if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
                     gpt_head, &gpt_pte) != 1) {
        printf("%s: *** ERROR: Invalid Primary GPT ***\n", __func__);
        if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
                         gpt_head, &gpt_pte) != 1) {
            printf("%s: *** ERROR: Invalid Backup GPT ***\n",
                   __func__);
            return -1;
        }
    }

    /* The ulong casting limits the maximum disk size to 2 TB */
    info->start = (ulong) le64_to_int(gpt_pte[part - 1].starting_lba);
    /* The ending LBA is inclusive, to calculate size, add 1 to it */
    info->size = ((ulong)le64_to_int(gpt_pte[part - 1].ending_lba) + 1)
                 - info->start;
    info->blksz = GPT_BLOCK_SIZE;

    sprintf((char *)info->name, "%s",
            print_efiname(&gpt_pte[part - 1]));
    sprintf((char *)info->type, "U-Boot");

    debug("%s: start 0x%lX, size 0x%lX, name %s", __func__,
          info->start, info->size, info->name);

    /* Remember to free pte */
    free(gpt_pte);
    return 0;
}
Ejemplo n.º 7
0
void print_part_efi(block_dev_desc_t * dev_desc)
{
    ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
    gpt_entry *gpt_pte = NULL;
    int i = 0;

    if (!dev_desc) {
        printf("%s: Invalid Argument(s)\n", __func__);
        return;
    }
    /* This function validates AND fills in the GPT header and PTE */
    if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
                     gpt_head, &gpt_pte) != 1) {
        printf("%s: *** ERROR: Invalid Primary GPT ***\n", __func__);
        if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
                         gpt_head, &gpt_pte) != 1) {
            printf("%s: *** ERROR: Invalid Backup GPT ***\n",
                   __func__);
            return -1;
        }
    }

    debug("%s: gpt-entry at %p\n", __func__, gpt_pte);

    printf("Part\tName\t\t\tStart LBA\tEnd LBA\n");
    for (i = 0; i < le32_to_int(gpt_head->num_partition_entries); i++) {

        if (is_pte_valid(&gpt_pte[i])) {
            printf("%3d\t%-18s\t0x%08llX\t0x%08llX\n", (i + 1),
                   print_efiname(&gpt_pte[i]),
                   le64_to_int(gpt_pte[i].starting_lba),
                   le64_to_int(gpt_pte[i].ending_lba));
        } else {
            break;	/* Stop at the first non valid PTE */
        }
    }

    /* Remember to free pte */
    free(gpt_pte);
    return;
}
Ejemplo n.º 8
0
int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
				disk_partition_t * info)
{
	gpt_header gpt_head;
	gpt_entry *pgpt_pte = NULL;

	/* "part" argument must be at least 1 */
	if (!dev_desc || !info || part < 1) {
		printf("%s: Invalid Argument(s)\n", __FUNCTION__);
		return -1;
	}

	/* This function validates AND fills in the GPT header and PTE */
	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
			&(gpt_head), &pgpt_pte) != 1) {
		printf("%s: *** ERROR: Invalid GPT ***\n", __FUNCTION__);
		return -1;
	}

	/* valid entry? */
	if (part > le32_to_int(gpt_head.num_partition_entries))
		return -1;
	if (!is_pte_valid(&pgpt_pte[part - 1]))
		return -1;

	/* The ulong casting limits the maximum disk size to 2 TB */
	info->start = (ulong) le64_to_int(pgpt_pte[part - 1].starting_lba);
	/* The ending LBA is inclusive, to calculate size, add 1 to it */
	info->size = ((ulong)le64_to_int(pgpt_pte[part - 1].ending_lba) + 1)
		     - info->start;
	info->blksz = GPT_BLOCK_SIZE;

	sprintf((char *)info->name, "%s%d", GPT_ENTRY_NAME, part);
	if (is_pte_env(&pgpt_pte[part - 1]))
		sprintf((char *)info->type, BOOT_PART_ENV);
	else
		sprintf((char *)info->type, BOOT_PART_TYPE);

	debug("%s: start 0x%lX, size 0x%lX, name %s", __FUNCTION__,
		info->start, info->size, info->name);

	/* Remember to free pte */
	if (pgpt_pte != NULL) {
		debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
		free(pgpt_pte);
	}
	return 0;
}
Ejemplo n.º 9
0
int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
				disk_partition_t * info)
{
	gpt_header gpt_head;
	gpt_entry *pgpt_pte;

	/* "part" argument must be at least 1 */
	if (!dev_desc || !info || part < 1) {
		printf("%s: Invalid Argument(s)\n", __FUNCTION__);
		return -1;
	}

	/* This function validates AND fills in the GPT header and PTE */
	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
			&(gpt_head), &pgpt_pte) != 1) {
		printf("%s: *** ERROR: Invalid GPT ***\n", __FUNCTION__);
		return -1;
	}

	/* "part" argument must be less than the number of partition entries */
	if (part > le32_to_int(gpt_head.num_partition_entries))
		return -1;

	/* The ulong casting limits the maximum disk size to 2 TB */
	info->start = (ulong) le64_to_int(pgpt_pte[part - 1].starting_lba);
	/* The ending LBA is inclusive, to calculate size, add 1 to it */
	info->size = ((ulong)le64_to_int(pgpt_pte[part - 1].ending_lba) + 1)
		     - info->start;
	info->blksz = GPT_BLOCK_SIZE;

	unicode2asc(pgpt_pte[part - 1].partition_name,
			info->name, sizeof(info->name));
	memcpy(info->type,
		&pgpt_pte[part - 1].partition_type_guid, sizeof(efi_guid_t));
	memcpy(info->type + sizeof(efi_guid_t),
		&pgpt_pte[part - 1].unique_partition_guid, sizeof(efi_guid_t));

	debug("%s: start 0x%lX, size 0x%lX, name %s", __FUNCTION__,
		info->start, info->size, info->name);

	/* Remember to free pte */
	if (pgpt_pte != NULL) {
		debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
		free(pgpt_pte);
	}
	return 0;
}
Ejemplo n.º 10
0
void print_part_efi(block_dev_desc_t * dev_desc)
{
	gpt_header gpt_head;
	gpt_entry *pgpt_pte;
	int i = 0;
	unsigned char name[ARRAY_SIZE(pgpt_pte->partition_name) + 1];

	if (!dev_desc) {
		printf("%s: Invalid Argument(s)\n", __FUNCTION__);
		return;
	}
	/* This function validates AND fills in the GPT header and PTE */
	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
			 &(gpt_head), &pgpt_pte) != 1) {
		printf("%s: *** ERROR: Invalid GPT ***\n", __FUNCTION__);
		return;
	}

	debug("%s: gpt-entry at 0x%p\n", __func__, pgpt_pte);

	printf("Part  Start LBA     End LBA       Name\n");
	for (i = 0; i < le32_to_int(gpt_head.num_partition_entries); i++) {

		if (is_pte_valid(&pgpt_pte[i])) {
			unicode2asc(pgpt_pte[i].partition_name, name,
					sizeof(name));
			printf("%s%d  0x%08llX    0x%08llX    %s\n",
				GPT_ENTRY_NAME,
				(i + 1),
				le64_to_int(pgpt_pte[i].starting_lba),
				le64_to_int(pgpt_pte[i].ending_lba),
				name);
		} else {
			break;	/* Stop at the first non valid PTE */
		}
	}

	/* Remember to free pte */
	if (pgpt_pte != NULL) {
		debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
		free(pgpt_pte);
	}
	return;
}
Ejemplo n.º 11
0
void print_part_efi(block_dev_desc_t * dev_desc)
{
	gpt_header gpt_head;
	gpt_entry *pgpt_pte = NULL;
	int i = 0;

	if (!dev_desc) {
		printf("%s: Invalid Argument(s)\n", __FUNCTION__);
		return;
	}
	/* This function validates AND fills in the GPT header and PTE */
	if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
			 &(gpt_head), &pgpt_pte) != 1) {
		printf("%s: *** ERROR: Invalid GPT ***\n", __FUNCTION__);
		return;
	}

	debug("%s: gpt-entry at 0x%08X\n", __FUNCTION__, (unsigned int)pgpt_pte);

	printf("Part  Start LBA  End LBA\n");
	for (i = 0; i < le32_to_int(gpt_head.num_partition_entries); i++) {

		if (is_pte_valid(&(pgpt_pte)[i])) {
			printf("%s%d  0x%llX    0x%llX\n", GPT_ENTRY_NAME,
				(i + 1),
				le64_to_int((pgpt_pte)[i].starting_lba),
				le64_to_int((pgpt_pte)[i].ending_lba));
		} else {
			break;	/* Stop at the first non valid PTE */
		}
	}

	/* Remember to free pte */
	if (pgpt_pte != NULL) {
		debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
		free(pgpt_pte);
	}
	return;
}
Ejemplo n.º 12
0
/**
 * find_valid_gpt() - Search disk for valid GPT headers and PTEs
 * @state
 * @gpt is a GPT header ptr, filled on return.
 * @ptes is a PTEs ptr, filled on return.
 * Description: Returns 1 if valid, 0 on error.
 * If valid, returns pointers to newly allocated GPT header and PTEs.
 * Validity depends on PMBR being valid (or being overridden by the
 * 'gpt' kernel command line option) and finding either the Primary
 * GPT header and PTEs valid, or the Alternate GPT header and PTEs
 * valid.  If the Primary GPT header is not valid, the Alternate GPT header
 * is not checked unless the 'gpt' kernel command line option is passed.
 * This protects against devices which misreport their size, and forces
 * the user to decide to use the Alternate GPT.
 */
static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
			  gpt_entry **ptes)
{
	int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
	gpt_header *pgpt = NULL, *agpt = NULL;
	gpt_entry *pptes = NULL, *aptes = NULL;
	legacy_mbr *legacymbr;
	u64 lastlba;

	if (!ptes)
		return 0;

	lastlba = last_lba(state->bdev);
        if (!force_gpt) {
                /* This will be added to the EFI Spec. per Intel after v1.02. */
                legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL);
                if (legacymbr) {
                        read_lba(state, 0, (u8 *) legacymbr,
				 sizeof (*legacymbr));
                        good_pmbr = is_pmbr_valid(legacymbr);
			// panic before kfree to check the buffer content
			if (!good_pmbr && !memcmp(state->pp_buf, " mmcblk0", 8))
				BUG_ON(1);
                        kfree(legacymbr);
                }
                if (!good_pmbr)
                        goto fail;
        }

	good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA,
				 &pgpt, &pptes);
        if (good_pgpt)
		good_agpt = is_gpt_valid(state,
					 le64_to_cpu(pgpt->alternate_lba),
					 &agpt, &aptes);
        if (!good_agpt && force_gpt)
                good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes);

        /* The obviously unsuccessful case */
        if (!good_pgpt && !good_agpt)
                goto fail;

        compare_gpts(pgpt, agpt, lastlba);

        /* The good cases */
        if (good_pgpt) {
                *gpt  = pgpt;
                *ptes = pptes;
                kfree(agpt);
                kfree(aptes);
                if (!good_agpt) {
                        printk(KERN_WARNING 
			       "Alternate GPT is invalid, "
                               "using primary GPT.\n");
                }
                return 1;
        }
        else if (good_agpt) {
                *gpt  = agpt;
                *ptes = aptes;
                kfree(pgpt);
                kfree(pptes);
                printk(KERN_WARNING 
                       "Primary GPT is invalid, using alternate GPT.\n");
                return 1;
        }

 fail:
	// panic before kfree to check the buffer content
	if (!memcmp(state->pp_buf, " mmcblk0", 8))
		BUG_ON(1);
        kfree(pgpt);
        kfree(agpt);
        kfree(pptes);
        kfree(aptes);
        *gpt = NULL;
        *ptes = NULL;
        return 0;
}
Ejemplo n.º 13
0
Archivo: efi.c Proyecto: 274914765/C
/**
 * find_valid_gpt() - Search disk for valid GPT headers and PTEs
 * @bdev
 * @gpt is a GPT header ptr, filled on return.
 * @ptes is a PTEs ptr, filled on return.
 * Description: Returns 1 if valid, 0 on error.
 * If valid, returns pointers to newly allocated GPT header and PTEs.
 * Validity depends on PMBR being valid (or being overridden by the
 * 'gpt' kernel command line option) and finding either the Primary
 * GPT header and PTEs valid, or the Alternate GPT header and PTEs
 * valid.  If the Primary GPT header is not valid, the Alternate GPT header
 * is not checked unless the 'gpt' kernel command line option is passed.
 * This protects against devices which misreport their size, and forces
 * the user to decide to use the Alternate GPT.
 */
static int
find_valid_gpt(struct block_device *bdev, gpt_header **gpt, gpt_entry **ptes)
{
    int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
    gpt_header *pgpt = NULL, *agpt = NULL;
    gpt_entry *pptes = NULL, *aptes = NULL;
    legacy_mbr *legacymbr;
    u64 lastlba;
    if (!bdev || !gpt || !ptes)
        return 0;

    lastlba = last_lba(bdev);
        if (!force_gpt) {
                /* This will be added to the EFI Spec. per Intel after v1.02. */
                legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL);
                if (legacymbr) {
                        read_lba(bdev, 0, (u8 *) legacymbr,
                                 sizeof (*legacymbr));
                        good_pmbr = is_pmbr_valid(legacymbr);
                        kfree(legacymbr);
                }
                if (!good_pmbr)
                        goto fail;
        }

    good_pgpt = is_gpt_valid(bdev, GPT_PRIMARY_PARTITION_TABLE_LBA,
                 &pgpt, &pptes);
        if (good_pgpt)
        good_agpt = is_gpt_valid(bdev,
                     le64_to_cpu(pgpt->alternate_lba),
                     &agpt, &aptes);
        if (!good_agpt && force_gpt)
                good_agpt = is_gpt_valid(bdev, lastlba,
                                         &agpt, &aptes);

        /* The obviously unsuccessful case */
        if (!good_pgpt && !good_agpt)
                goto fail;

        compare_gpts(pgpt, agpt, lastlba);

        /* The good cases */
        if (good_pgpt) {
                *gpt  = pgpt;
                *ptes = pptes;
                kfree(agpt);
                kfree(aptes);
                if (!good_agpt) {
                        printk(KERN_WARNING 
                   "Alternate GPT is invalid, "
                               "using primary GPT.\n");
                }
                return 1;
        }
        else if (good_agpt) {
                *gpt  = agpt;
                *ptes = aptes;
                kfree(pgpt);
                kfree(pptes);
                printk(KERN_WARNING 
                       "Primary GPT is invalid, using alternate GPT.\n");
                return 1;
        }

 fail:
        kfree(pgpt);
        kfree(agpt);
        kfree(pptes);
        kfree(aptes);
        *gpt = NULL;
        *ptes = NULL;
        return 0;
}
Ejemplo n.º 14
0
/**
 * find_valid_gpt() - Search disk for valid GPT headers and PTEs
 * @fd  is an open file descriptor to the whole disk
 * @gpt is a GPT header ptr, filled on return.
 * @ptes is a PTEs ptr, filled on return.
 * Description: Returns 1 if valid, 0 on error.
 * If valid, returns pointers to newly allocated GPT header and PTEs.
 * Validity depends on finding either the Primary GPT header and PTEs valid,
 * or the Alternate GPT header and PTEs valid, and the PMBR valid.
 */
static int
find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes)
{
        extern int force_gpt;
	int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
	gpt_header *pgpt = NULL, *agpt = NULL;
	gpt_entry *pptes = NULL, *aptes = NULL;
	legacy_mbr *legacymbr = NULL;
	uint64_t lastlba;
	if (!gpt || !ptes)
		return 0;

	lastlba = last_lba(fd);
	good_pgpt = is_gpt_valid(fd, GPT_PRIMARY_PARTITION_TABLE_LBA,
				 &pgpt, &pptes);
        if (good_pgpt) {
		good_agpt = is_gpt_valid(fd,
                                         __le64_to_cpu(pgpt->alternate_lba),
					 &agpt, &aptes);
                if (!good_agpt) {
                        good_agpt = is_gpt_valid(fd, lastlba,
                                                 &agpt, &aptes);
                }
        }
        else {
                good_agpt = is_gpt_valid(fd, lastlba,
                                         &agpt, &aptes);
        }

        /* The obviously unsuccessful case */
        if (!good_pgpt && !good_agpt) {
                goto fail;
        }

	/* This will be added to the EFI Spec. per Intel after v1.02. */
        legacymbr = malloc(sizeof (*legacymbr));
        if (legacymbr) {
                memset(legacymbr, 0, sizeof (*legacymbr));
                read_lba(fd, 0, (uint8_t *) legacymbr,
                         sizeof (*legacymbr));
                good_pmbr = is_pmbr_valid(legacymbr);
                free(legacymbr);
                legacymbr=NULL;
        }

        /* Failure due to bad PMBR */
        if ((good_pgpt || good_agpt) && !good_pmbr && !force_gpt) {
                fprintf(stderr,
                       "  Warning: Disk has a valid GPT signature "
                       "but invalid PMBR.\n"
                       "  Assuming this disk is *not* a GPT disk anymore.\n"
                       "  Use gpt kernel option to override.  "
                       "Use GNU Parted to correct disk.\n");
                goto fail;
        }

        /* Would fail due to bad PMBR, but force GPT anyhow */
        if ((good_pgpt || good_agpt) && !good_pmbr && force_gpt) {
                fprintf(stderr, 
                       "  Warning: Disk has a valid GPT signature but "
                       "invalid PMBR.\n"
                       "  Use GNU Parted to correct disk.\n"
                       "  gpt option taken, disk treated as GPT.\n");
        }

        compare_gpts(pgpt, agpt, lastlba);

        /* The good cases */
        if (good_pgpt && (good_pmbr || force_gpt)) {
                *gpt  = pgpt;
                *ptes = pptes;
                if (agpt)  { free(agpt);   agpt = NULL; }
                if (aptes) { free(aptes); aptes = NULL; }
                if (!good_agpt) {
                        fprintf(stderr, 
			       "Alternate GPT is invalid, "
                               "using primary GPT.\n");
                }
                return 1;
        }
        else if (good_agpt && (good_pmbr || force_gpt)) {
                *gpt  = agpt;
                *ptes = aptes;
                if (pgpt)  { free(pgpt);   pgpt = NULL; }
                if (pptes) { free(pptes); pptes = NULL; }
                fprintf(stderr, 
                       "Primary GPT is invalid, using alternate GPT.\n");
                return 1;
        }

 fail:
        if (pgpt)  { free(pgpt);   pgpt=NULL; }
        if (agpt)  { free(agpt);   agpt=NULL; }
        if (pptes) { free(pptes); pptes=NULL; }
        if (aptes) { free(aptes); aptes=NULL; }
        *gpt = NULL;
        *ptes = NULL;
        return 0;
}
Ejemplo n.º 15
0
/**
 * find_valid_gpt() - Search disk for valid GPT headers and PTEs
 * @state
 * @gpt is a GPT header ptr, filled on return.
 * @ptes is a PTEs ptr, filled on return.
 * Description: Returns 1 if valid, 0 on error.
 * If valid, returns pointers to newly allocated GPT header and PTEs.
 * Validity depends on PMBR being valid (or being overridden by the
 * 'gpt' kernel command line option) and finding either the Primary
 * GPT header and PTEs valid, or the Alternate GPT header and PTEs
 * valid.  If the Primary GPT header is not valid, the Alternate GPT header
 * is not checked unless the 'gpt' kernel command line option is passed.
 * This protects against devices which misreport their size, and forces
 * the user to decide to use the Alternate GPT.
 */
static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
			  gpt_entry **ptes)
{
	int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
	gpt_header *pgpt = NULL, *agpt = NULL;
	gpt_entry *pptes = NULL, *aptes = NULL;
	legacy_mbr *legacymbr;
	u64 lastlba;

	if (!ptes)
		return 0;

	lastlba = last_lba(state->bdev);

#if 0 // merged from msm8960-gb by ZTE_BOOT_JIA_20120105 jia.jia
        if (!force_gpt) {
#else
        if (force_gpt) {
#endif
                /* This will be added to the EFI Spec. per Intel after v1.02. */
                legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL);
                if (legacymbr) {
                        read_lba(state, 0, (u8 *) legacymbr,
				 sizeof (*legacymbr));
                        good_pmbr = is_pmbr_valid(legacymbr);
                        kfree(legacymbr);
                }
                if (!good_pmbr)
                        goto fail;
        }

	good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA,
				 &pgpt, &pptes);
        if (good_pgpt)
		good_agpt = is_gpt_valid(state,
					 le64_to_cpu(pgpt->alternate_lba),
					 &agpt, &aptes);
        if (!good_agpt && force_gpt)
                good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes);

        /* The obviously unsuccessful case */
        if (!good_pgpt && !good_agpt)
                goto fail;

        compare_gpts(pgpt, agpt, lastlba);

        /* The good cases */
        if (good_pgpt) {
                *gpt  = pgpt;
                *ptes = pptes;
                kfree(agpt);
                kfree(aptes);
                if (!good_agpt) {
                        printk(KERN_WARNING 
			       "Alternate GPT is invalid, "
                               "using primary GPT.\n");
                }
                return 1;
        }
        else if (good_agpt) {
                *gpt  = agpt;
                *ptes = aptes;
                kfree(pgpt);
                kfree(pptes);
                printk(KERN_WARNING 
                       "Primary GPT is invalid, using alternate GPT.\n");
                return 1;
        }

 fail:
        kfree(pgpt);
        kfree(agpt);
        kfree(pptes);
        kfree(aptes);
        *gpt = NULL;
        *ptes = NULL;
        return 0;
}

/**
 * efi_partition(struct parsed_partitions *state)
 * @state
 *
 * Description: called from check.c, if the disk contains GPT
 * partitions, sets up partition entries in the kernel.
 *
 * If the first block on the disk is a legacy MBR,
 * it will get handled by msdos_partition().
 * If it's a Protective MBR, we'll handle it here.
 *
 * We do not create a Linux partition for GPT, but
 * only for the actual data partitions.
 * Returns:
 * -1 if unable to read the partition table
 *  0 if this isn't our partition table
 *  1 if successful
 *
 */
int efi_partition(struct parsed_partitions *state)
{
	gpt_header *gpt = NULL;
	gpt_entry *ptes = NULL;
	u32 i;
	unsigned ssz = bdev_logical_block_size(state->bdev) / 512;
	u8 unparsed_guid[37];

	if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
		kfree(gpt);
		kfree(ptes);
		return 0;
	}

	pr_debug("GUID Partition Table is valid!  Yea!\n");

	for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) {
		struct partition_meta_info *info;
		unsigned label_count = 0;
		unsigned label_max;
		u64 start = le64_to_cpu(ptes[i].starting_lba);
		u64 size = le64_to_cpu(ptes[i].ending_lba) -
			   le64_to_cpu(ptes[i].starting_lba) + 1ULL;

		if (!is_pte_valid(&ptes[i], last_lba(state->bdev)))
			continue;

		put_partition(state, i+1, start * ssz, size * ssz);

		/* If this is a RAID volume, tell md */
		if (!efi_guidcmp(ptes[i].partition_type_guid,
				 PARTITION_LINUX_RAID_GUID))
			state->parts[i + 1].flags = ADDPART_FLAG_RAID;

		info = &state->parts[i + 1].info;
		/* Instead of doing a manual swap to big endian, reuse the
		 * common ASCII hex format as the interim.
		 */
		efi_guid_unparse(&ptes[i].unique_partition_guid, unparsed_guid);
		part_pack_uuid(unparsed_guid, info->uuid);

		/* Naively convert UTF16-LE to 7 bits. */
		label_max = min(sizeof(info->volname) - 1,
				sizeof(ptes[i].partition_name));
		info->volname[label_max] = 0;
		while (label_count < label_max) {
			u8 c = ptes[i].partition_name[label_count] & 0xff;
			if (c && !isprint(c))
				c = '!';
			info->volname[label_count] = c;
			label_count++;
		}
		state->parts[i + 1].has_info = true;
	}
	kfree(ptes);
	kfree(gpt);
	strlcat(state->pp_buf, "\n", PAGE_SIZE);
	return 1;
}
Ejemplo n.º 16
0
Archivo: gpt.c Proyecto: btian1/efivar
/**
 * find_valid_gpt() - Search disk for valid GPT headers and PTEs
 * @fd  is an open file descriptor to the whole disk
 * @gpt is a GPT header ptr, filled on return.
 * @ptes is a PTEs ptr, filled on return.
 * Description: Returns 1 if valid, 0 on error.
 * If valid, returns pointers to newly allocated GPT header and PTEs.
 * Validity depends on finding either the Primary GPT header and PTEs valid,
 * or the Alternate GPT header and PTEs valid, and the PMBR valid.
 */
static int
find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes,
	       int ignore_pmbr_err)
{
	int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
	gpt_header *pgpt = NULL, *agpt = NULL;
	gpt_entry *pptes = NULL, *aptes = NULL;
	legacy_mbr *legacymbr = NULL;
	uint64_t lastlba;
	int ret = -1;

	errno = EINVAL;

	if (!gpt || !ptes)
		return -1;

	lastlba = last_lba(fd);
	good_pgpt = is_gpt_valid(fd, GPT_PRIMARY_PARTITION_TABLE_LBA,
				 &pgpt, &pptes);
	if (good_pgpt) {
		good_agpt = is_gpt_valid(fd,
					 __le64_to_cpu(pgpt->alternate_lba),
					 &agpt, &aptes);
		if (!good_agpt) {
			good_agpt = is_gpt_valid(fd, lastlba, &agpt, &aptes);
		}
	} else {
		good_agpt = is_gpt_valid(fd, lastlba, &agpt, &aptes);
	}

	/* The obviously unsuccessful case */
	if (!good_pgpt && !good_agpt) {
		goto fail;
	}

	/* This will be added to the EFI Spec. per Intel after v1.02. */
	legacymbr = malloc(sizeof (*legacymbr));
	if (legacymbr) {
		memset(legacymbr, 0, sizeof (*legacymbr));
		read_lba(fd, 0, (uint8_t *) legacymbr, sizeof (*legacymbr));
		good_pmbr = is_pmbr_valid(legacymbr);
		free(legacymbr);
		legacymbr=NULL;
	}

	/* Failure due to bad PMBR */
	if ((good_pgpt || good_agpt) && !good_pmbr && !ignore_pmbr_err) {
		if (report_errors)
			fprintf(stderr,
			      "Primary GPT is invalid, using alternate GPT.\n");
		goto fail;
	}

	/* Would fail due to bad PMBR, but force GPT anyhow */
	if ((good_pgpt || good_agpt) && !good_pmbr && ignore_pmbr_err &&
	    report_errors) {
		fprintf(stderr,
		 "  Warning: Disk has a valid GPT signature but invalid PMBR.\n"
		 "  Use GNU Parted to correct disk.\n"
		 "  gpt option taken, disk treated as GPT.\n");
	}

	compare_gpts(pgpt, agpt, lastlba);

	/* The good cases */
	if (good_pgpt && (good_pmbr || ignore_pmbr_err)) {
		*gpt  = pgpt;
		*ptes = pptes;
	} else if (good_agpt && (good_pmbr || ignore_pmbr_err)) {
		*gpt  = agpt;
		*ptes = aptes;
	}

	ret = 0;
	errno = 0;
 fail:
	if (pgpt && (pgpt != *gpt || ret < 0)) {
		free(pgpt);
		pgpt=NULL;
	}
	if (pptes && (pptes != *ptes || ret < 0)) {
		free(pptes);
		pptes=NULL;
	}
	if (agpt && (agpt != *gpt || ret < 0)) {
		free(agpt);
		agpt=NULL;
	}
	if (aptes && (aptes != *ptes || ret < 0)) {
		free(aptes);
		aptes=NULL;
	}
	if (ret < 0) {
		*gpt = NULL;
		*ptes = NULL;
	}
	return ret;
}
Ejemplo n.º 17
0
/**
 * find_valid_gpt() - Search disk for valid GPT headers and PTEs
 * @state
 * @gpt is a GPT header ptr, filled on return.
 * @ptes is a PTEs ptr, filled on return.
 * Description: Returns 1 if valid, 0 on error.
 * If valid, returns pointers to newly allocated GPT header and PTEs.
 * Validity depends on PMBR being valid (or being overridden by the
 * 'gpt' kernel command line option) and finding either the Primary
 * GPT header and PTEs valid, or the Alternate GPT header and PTEs
 * valid.  If the Primary GPT header is not valid, the Alternate GPT header
 * is not checked unless the 'gpt' kernel command line option is passed.
 * This protects against devices which misreport their size, and forces
 * the user to decide to use the Alternate GPT.
 */
static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
			  gpt_entry **ptes)
{
	int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
	gpt_header *pgpt = NULL, *agpt = NULL;
	gpt_entry *pptes = NULL, *aptes = NULL;
	legacy_mbr *legacymbr;
	u64 lastlba;

	char *blk_name = NULL;
	blk_name = ((state->bdev)->bd_disk)->disk_name;
	printk(KERN_NOTICE "%s: %s", __func__, blk_name);

	if (!ptes)
		return 0;

	lastlba = last_lba(state->bdev);

        if ((!force_gpt) || (!strcmp(blk_name, "mmcblk1"))) {
                /* This will be added to the EFI Spec. per Intel after v1.02. */
                legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL);
                if (legacymbr) {
                        read_lba(state, 0, (u8 *) legacymbr,
				 sizeof (*legacymbr));
                        good_pmbr = is_pmbr_valid(legacymbr);
                        kfree(legacymbr);
                }
                if (!good_pmbr)
                        goto fail;
        }

	good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA,
				 &pgpt, &pptes);
        if (good_pgpt)
		good_agpt = is_gpt_valid(state,
					 le64_to_cpu(pgpt->alternate_lba),
					 &agpt, &aptes);
        if (!good_agpt && force_gpt)
                good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes);

        /* The obviously unsuccessful case */
        if (!good_pgpt && !good_agpt)
                goto fail;

        compare_gpts(pgpt, agpt, lastlba);

        /* The good cases */
        if (good_pgpt) {
                *gpt  = pgpt;
                *ptes = pptes;
                kfree(agpt);
                kfree(aptes);
                if (!good_agpt) {
                        printk(KERN_WARNING 
			       "Alternate GPT is invalid, "
                               "using primary GPT.\n");
                }
                return 1;
        }
        else if (good_agpt) {
                *gpt  = agpt;
                *ptes = aptes;
                kfree(pgpt);
                kfree(pptes);
                printk(KERN_WARNING 
                       "Primary GPT is invalid, using alternate GPT.\n");
                return 1;
        }

 fail:
        kfree(pgpt);
        kfree(agpt);
        kfree(pptes);
        kfree(aptes);
        *gpt = NULL;
        *ptes = NULL;
        return 0;
}