static EFI_STATUS _flash_gpt(VOID *data, UINTN size, logical_unit_t log_unit)
{
	struct gpt_bin_header *gb_hdr;
	struct gpt_bin_part *gb_part;
	EFI_STATUS ret;

	gb_hdr = data;
	gb_part = (struct gpt_bin_part *)&gb_hdr[1];

	if (size < sizeof(*gb_hdr) ||
	    gb_hdr->magic != GPT_BIN_MAGIC ||
	    size != sizeof(*gb_hdr) + (gb_hdr->npart * sizeof(*gb_part))) {
		error(L"Invalid gpt binary");
		return EFI_INVALID_PARAMETER;
	}

	ret = gpt_create(gb_hdr->start_lba, gb_hdr->npart, gb_part, log_unit);
	if (EFI_ERROR(ret))
		return ret;

	return (EFI_SUCCESS | REFRESH_PARTITION_VAR);
}
示例#2
0
文件: migrate.c 项目: ryo/netbsd-src
static int
migrate(gpt_t gpt, u_int parts, int force, int slice, int active)
{
	off_t last = gpt_last(gpt);
	map_t map;
	struct gpt_ent *ent;
	struct mbr *mbr;
	uint32_t start, size;
	unsigned int i;
	gpt_type_t type = GPT_TYPE_INVALID;

	map = map_find(gpt, MAP_TYPE_MBR);
	if (map == NULL || map->map_start != 0) {
		gpt_warnx(gpt, "No MBR in disk to convert");
		return -1;
	}

	mbr = map->map_data;

	if (gpt_create(gpt, last, parts, 0) == -1)
		return -1;

	ent = gpt->tbl->map_data;

	/* Mirror partitions. */
	for (i = 0; i < 4; i++) {
		start = le16toh(mbr->mbr_part[i].part_start_hi);
		start = (start << 16) + le16toh(mbr->mbr_part[i].part_start_lo);
		size = le16toh(mbr->mbr_part[i].part_size_hi);
		size = (size << 16) + le16toh(mbr->mbr_part[i].part_size_lo);

		if (gpt->verbose > 1)
			gpt_msg(gpt, "MBR partition %u type %s", i,
			    mbrptypename(mbr->mbr_part[i].part_typ));
		switch (mbr->mbr_part[i].part_typ) {
		case MBR_PTYPE_UNUSED:
			continue;

		case MBR_PTYPE_386BSD: /* FreeBSD */
			if (slice) {
				type = GPT_TYPE_FREEBSD;
				break;
			} else {
				ent = migrate_disklabel(gpt, start, ent,
				    freebsd_fstype_to_gpt_type);
				continue;
			}

		case MBR_PTYPE_NETBSD:	/* NetBSD */
			ent = migrate_disklabel(gpt, start, ent,
			    netbsd_fstype_to_gpt_type);
			continue;

		case MBR_PTYPE_EFI:
			type = GPT_TYPE_EFI;
			break;

		default:
			if (!force) {
				gpt_warnx(gpt, "unknown partition type (%d)",
				    mbr->mbr_part[i].part_typ);
				return -1;
			}
			continue;
		}
		gpt_uuid_create(type, ent->ent_type, ent->ent_name,
		    sizeof(ent->ent_name));
		ent->ent_lba_start = htole64((uint64_t)start);
		ent->ent_lba_end = htole64((uint64_t)(start + size - 1LL));
		ent++;
	}

	if (gpt_write_primary(gpt) == -1)
		return -1;

	if (gpt_write_backup(gpt) == -1)
		return -1;

	/*
	 * Turn the MBR into a Protective MBR.
	 */
	memset(mbr->mbr_part, 0, sizeof(mbr->mbr_part));
	gpt_create_pmbr_part(mbr->mbr_part, last, active);
	if (gpt_write(gpt, map) == -1) {
		gpt_warn(gpt, "Cant write PMBR");
		return -1;
	}
	return 0;
}