[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