[U-Boot] [PATCH] disk: generate GUID Partiton Tables
Donghwa Lee
dh09.lee at samsung.com
Wed May 2 03:34:02 CEST 2012
This patch manipulates GUID Papartition Tables.
I send this patch on behalf of Gwuieon Jin.
Signed-off-by: Gwuieon Jin <ge.jin at samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
---
disk/part_efi.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
disk/part_efi.h | 2 +
include/part.h | 2 +
3 files changed, 111 insertions(+), 0 deletions(-)
diff --git a/disk/part_efi.c b/disk/part_efi.c
index b6cda57..ce25ad5 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -433,4 +433,111 @@ static int is_pte_valid(gpt_entry * pte)
return 1;
}
}
+
+void set_gpt_table(block_dev_desc_t *dev_desc, unsigned int part_start_lba,
+ int parts, unsigned int *blocks, unsigned int *part_offset)
+{
+ legacy_mbr protective_mbr;
+ gpt_header p_gpt_head, s_gpt_head;
+ gpt_entry p_gpt_entry[GPT_ENTRY_NUMBERS],
+ s_gpt_entry[GPT_ENTRY_NUMBERS];
+ efi_guid_t disk_uuid, part_uuid;
+ unsigned long crc32_tmp, tmp_val;
+ unsigned int size = 0;
+ unsigned int offset = part_start_lba;
+ int i;
+
+ memset(&protective_mbr, 0, sizeof(legacy_mbr));
+ memset(&p_gpt_head, 0, sizeof(gpt_header));
+ memset(&s_gpt_head, 0, sizeof(gpt_header));
+ memset(p_gpt_entry, 0, GPT_ENTRY_NUMBERS * sizeof(gpt_entry));
+ memset(s_gpt_entry, 0, GPT_ENTRY_NUMBERS * sizeof(gpt_entry));
+
+ /* protective MBR (LBA0) */
+ *(unsigned short *) protective_mbr.signature = MSDOS_MBR_SIGNATURE;
+ protective_mbr.partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
+ tmp_val = 1UL;
+ memcpy(protective_mbr.partition_record[0].start_sect, &tmp_val, 4);
+ tmp_val = (unsigned long) (dev_desc->lba - 1);
+ memcpy(protective_mbr.partition_record[0].nr_sects, &tmp_val, 4);
+ dev_desc->block_write(dev_desc->dev, 0, 1, &protective_mbr);
+
+ /* primary GPT header (LBA1) */
+ *(unsigned long long *) p_gpt_head.signature = GPT_HEADER_SIGNATURE;
+ *(unsigned long *) p_gpt_head.revision = GPT_HEADER_REVISION_V1;
+ *(unsigned long *) p_gpt_head.header_size = sizeof(gpt_header);
+ *(unsigned long long *) p_gpt_head.my_lba = 1;
+ *(unsigned long long *) p_gpt_head.alternate_lba = dev_desc->lba - 1;
+ *(unsigned long long *) p_gpt_head.first_usable_lba = 34;
+ *(unsigned long long *) p_gpt_head.last_usable_lba = dev_desc->lba - 34;
+ *(unsigned long long *) p_gpt_head.partition_entry_lba = 2;
+ *(unsigned long *) p_gpt_head.num_partition_entries = GPT_ENTRY_NUMBERS;
+ *(unsigned long *) p_gpt_head.sizeof_partition_entry = GPT_ENTRY_SIZE;
+ *(unsigned long *) p_gpt_head.header_crc32 = 0;
+ *(unsigned long *) p_gpt_head.partition_entry_array_crc32 = 0;
+
+ /* primary partition entrys (LBA2-33) */
+ for (i = 0; i < parts; i++) {
+ memcpy(p_gpt_entry[i].partition_type_guid.b,
+ &PARTITION_BASIC_DATA_GUID, 16);
+
+ *(unsigned long long *) p_gpt_entry[i].starting_lba = offset;
+ /* allocate remaining memory in last partition */
+ if (i != parts - 1)
+ *(unsigned long long *) p_gpt_entry[i].ending_lba =
+ offset + blocks[i] - 1;
+ else
+ *(unsigned long long *) p_gpt_entry[i].ending_lba =
+ dev_desc->lba - 33;
+ memset(&p_gpt_entry[i].attributes, 0,
+ sizeof(gpt_entry_attributes));
+ part_offset[i] = offset;
+ offset += blocks[i];
+ }
+
+ crc32_tmp = efi_crc32((const unsigned char *)p_gpt_entry,
+ le32_to_int(p_gpt_head.num_partition_entries) *
+ le32_to_int(p_gpt_head.sizeof_partition_entry));
+ memcpy(p_gpt_head.partition_entry_array_crc32, &crc32_tmp,
+ sizeof(crc32_tmp));
+
+ crc32_tmp = efi_crc32((const unsigned char *)&p_gpt_head,
+ le32_to_int(p_gpt_head.header_size));
+ memcpy(p_gpt_head.header_crc32, &crc32_tmp, sizeof(crc32_tmp));
+
+ dev_desc->block_write(dev_desc->dev, 1, 1, &p_gpt_head);
+ dev_desc->block_write(dev_desc->dev, 2, 32, p_gpt_entry);
+
+ /* secondary partition entrys */
+ memcpy(s_gpt_entry, p_gpt_entry,
+ GPT_ENTRY_NUMBERS * sizeof(gpt_entry));
+
+ /* secondary gpt header */
+ memcpy(&s_gpt_head, &p_gpt_head, sizeof(gpt_header));
+ *(unsigned long long *) s_gpt_head.my_lba =
+ le64_to_int(p_gpt_head.alternate_lba);
+ *(unsigned long long *) s_gpt_head.alternate_lba =
+ le64_to_int(p_gpt_head.my_lba);
+ *(unsigned long long *) s_gpt_head.partition_entry_lba =
+ le64_to_int(p_gpt_head.last_usable_lba) + 1;
+ *(unsigned long *) s_gpt_head.header_crc32 = 0;
+ *(unsigned long *) s_gpt_head.partition_entry_array_crc32 = 0;
+
+ crc32_tmp = efi_crc32((const unsigned char *)s_gpt_entry,
+ le32_to_int(s_gpt_head.num_partition_entries) *
+ le32_to_int(s_gpt_head.sizeof_partition_entry));
+ memcpy(s_gpt_head.partition_entry_array_crc32, &crc32_tmp,
+ sizeof(unsigned long));
+
+ crc32_tmp = efi_crc32((const unsigned char *)&s_gpt_head,
+ le32_to_int(s_gpt_head.header_size));
+ memcpy(s_gpt_head.header_crc32, &crc32_tmp, sizeof(unsigned long));
+
+ dev_desc->block_write(dev_desc->dev,
+ le64_to_int(s_gpt_head.partition_entry_lba),
+ 32, s_gpt_entry);
+ dev_desc->block_write(dev_desc->dev,
+ le64_to_int(s_gpt_head.partition_entry_lba) + 32,
+ 1, &s_gpt_head);
+}
#endif
diff --git a/disk/part_efi.h b/disk/part_efi.h
index 5903e7c..ddc2a7f 100644
--- a/disk/part_efi.h
+++ b/disk/part_efi.h
@@ -41,6 +41,8 @@
#define GPT_HEADER_REVISION_V1 0x00010000
#define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
#define GPT_ENTRY_NAME "gpt"
+#define GPT_ENTRY_NUMBERS 128
+#define GPT_ENTRY_SIZE 128
#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
((efi_guid_t) \
diff --git a/include/part.h b/include/part.h
index 1827767..32c3295 100644
--- a/include/part.h
+++ b/include/part.h
@@ -161,6 +161,8 @@ int test_part_amiga (block_dev_desc_t *dev_desc);
int get_partition_info_efi (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
void print_part_efi (block_dev_desc_t *dev_desc);
int test_part_efi (block_dev_desc_t *dev_desc);
+void set_gpt_table(block_dev_desc_t *dev_desc, unsigned int part_start_lba,
+ int parts, unsigned int *blocks, unsigned int *part_offset);
#endif
#endif /* _PART_H */
--
1.7.4.1
More information about the U-Boot
mailing list