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); }
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; }