
This patch manipulates GUID Papartition Tables. I send this patch on behalf of Gwuieon Jin.
Signed-off-by: Gwuieon Jin ge.jin@samsung.com Signed-off-by: Kyungmin Park kyungmin.park@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 */