summaryrefslogtreecommitdiffstats
path: root/disk/part_efi.c
diff options
context:
space:
mode:
Diffstat (limited to 'disk/part_efi.c')
-rw-r--r--disk/part_efi.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/disk/part_efi.c b/disk/part_efi.c
index 2c77f29d45..338010e148 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -161,6 +161,8 @@ static void prepare_backup_gpt_header(gpt_header *gpt_h)
val = le64_to_cpu(gpt_h->my_lba);
gpt_h->my_lba = gpt_h->alternate_lba;
gpt_h->alternate_lba = cpu_to_le64(val);
+ gpt_h->partition_entry_lba =
+ cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1);
gpt_h->header_crc32 = 0;
calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
@@ -545,6 +547,97 @@ err:
free(gpt_h);
return ret;
}
+
+int is_valid_gpt_buf(block_dev_desc_t *dev_desc, void *buf)
+{
+ gpt_header *gpt_h;
+ gpt_entry *gpt_e;
+
+ /* determine start of GPT Header in the buffer */
+ gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA *
+ dev_desc->blksz);
+ if (validate_gpt_header(gpt_h, GPT_PRIMARY_PARTITION_TABLE_LBA,
+ dev_desc->lba))
+ return -1;
+
+ /* determine start of GPT Entries in the buffer */
+ gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) *
+ dev_desc->blksz);
+ if (validate_gpt_entries(gpt_h, gpt_e))
+ return -1;
+
+ return 0;
+}
+
+int write_mbr_and_gpt_partitions(block_dev_desc_t *dev_desc, void *buf)
+{
+ gpt_header *gpt_h;
+ gpt_entry *gpt_e;
+ int gpt_e_blk_cnt;
+ lbaint_t lba;
+ int cnt;
+
+ if (is_valid_gpt_buf(dev_desc, buf))
+ return -1;
+
+ /* determine start of GPT Header in the buffer */
+ gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA *
+ dev_desc->blksz);
+
+ /* determine start of GPT Entries in the buffer */
+ gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) *
+ dev_desc->blksz);
+ gpt_e_blk_cnt = BLOCK_CNT((le32_to_cpu(gpt_h->num_partition_entries) *
+ le32_to_cpu(gpt_h->sizeof_partition_entry)),
+ dev_desc);
+
+ /* write MBR */
+ lba = 0; /* MBR is always at 0 */
+ cnt = 1; /* MBR (1 block) */
+ if (dev_desc->block_write(dev_desc->dev, lba, cnt, buf) != cnt) {
+ printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
+ __func__, "MBR", cnt, lba);
+ return 1;
+ }
+
+ /* write Primary GPT */
+ lba = GPT_PRIMARY_PARTITION_TABLE_LBA;
+ cnt = 1; /* GPT Header (1 block) */
+ if (dev_desc->block_write(dev_desc->dev, lba, cnt, gpt_h) != cnt) {
+ printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
+ __func__, "Primary GPT Header", cnt, lba);
+ return 1;
+ }
+
+ lba = le64_to_cpu(gpt_h->partition_entry_lba);
+ cnt = gpt_e_blk_cnt;
+ if (dev_desc->block_write(dev_desc->dev, lba, cnt, gpt_e) != cnt) {
+ printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
+ __func__, "Primary GPT Entries", cnt, lba);
+ return 1;
+ }
+
+ prepare_backup_gpt_header(gpt_h);
+
+ /* write Backup GPT */
+ lba = le64_to_cpu(gpt_h->partition_entry_lba);
+ cnt = gpt_e_blk_cnt;
+ if (dev_desc->block_write(dev_desc->dev, lba, cnt, gpt_e) != cnt) {
+ printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
+ __func__, "Backup GPT Entries", cnt, lba);
+ return 1;
+ }
+
+ lba = le64_to_cpu(gpt_h->my_lba);
+ cnt = 1; /* GPT Header (1 block) */
+ if (dev_desc->block_write(dev_desc->dev, lba, cnt, gpt_h) != cnt) {
+ printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
+ __func__, "Backup GPT Header", cnt, lba);
+ return 1;
+ }
+
+ return 0;
+}
#endif
/*
OpenPOWER on IntegriCloud