Fastbootd: improved operations on gpt
Change-Id: Ieabdcb1c52094d7408b169681e073ebf6613af20
This commit is contained in:
parent
aa4a3228f0
commit
bc7cbfd4e3
|
@ -56,7 +56,7 @@
|
|||
#define ALIGN_DOWN(x, y) ((y) * ((x) / (y)))
|
||||
|
||||
|
||||
const uint16_t partition_type_uuid[16] = {
|
||||
const uint8_t partition_type_uuid[16] = {
|
||||
0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44,
|
||||
0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7,
|
||||
};
|
||||
|
@ -422,7 +422,7 @@ void GPT_sync(struct GPT_entry_table *table)
|
|||
|
||||
table->header->header_checksum = 0;
|
||||
crc = crc32(0, Z_NULL, 0);
|
||||
crc = crc32(crc, (void*) table->header, sizeof(*table->header));
|
||||
crc = crc32(crc, (void*) table->header, table->header->header_size);
|
||||
table->header->header_checksum = crc;
|
||||
|
||||
//sync secondary partion
|
||||
|
@ -526,7 +526,7 @@ static int add_key_value(const char *key, const char *value, struct GPT_entry_ra
|
|||
if (*endptr != '\0') goto error;
|
||||
}
|
||||
else if (!strcmp(key, "flags")) {
|
||||
entry->flags = strtoul(value, &endptr, 10);
|
||||
entry->flags = strtoul(value, &endptr, 16);
|
||||
if (*endptr != '\0') goto error;
|
||||
}
|
||||
else if (!strcmp(key, "name")) {
|
||||
|
@ -558,25 +558,31 @@ int GPT_parse_entry(char *string, struct GPT_entry_raw *entry)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void entry_set_guid(int n, uint8_t *guid)
|
||||
void entry_set_guid(int n, uint8_t *guid)
|
||||
{
|
||||
guid[0] = (uint8_t) (n + 1);
|
||||
int fd;
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
read(fd, &guid[1], 15);
|
||||
close(fd);
|
||||
|
||||
//rfc4122
|
||||
guid[8] = (guid[8] & 0x3F) | 0x80;
|
||||
guid[7] = (guid[7] & 0x0F) | 0x40;
|
||||
}
|
||||
|
||||
void GPT_default_content(struct GPT_content *content, struct GPT_entry_table *table)
|
||||
{
|
||||
if (table != NULL) {
|
||||
memcpy(&content->header, table->header, sizeof(content->header));
|
||||
content->header.header_size = sizeof(content->header);
|
||||
content->header.entry_size = sizeof(struct GPT_entry_raw);
|
||||
}
|
||||
else {
|
||||
D(WARN, "Could not locate old gpt table, using default values");
|
||||
memset(&content->header, 0, sizeof(content->header) / sizeof(int));
|
||||
content->header = (struct GPT_header) {
|
||||
.revision = 0x0100,
|
||||
.revision = 0x10000,
|
||||
.header_size = sizeof(content->header),
|
||||
.header_checksum = 0,
|
||||
.reserved_zeros = 0,
|
||||
|
@ -586,7 +592,7 @@ void GPT_default_content(struct GPT_content *content, struct GPT_entry_table *ta
|
|||
.partition_array_checksum = 0
|
||||
};
|
||||
strncpy((char *)content->header.signature, "EFI PART", 8);
|
||||
entry_set_guid(0, content->header.disk_guid);
|
||||
strncpy((char *)content->header.disk_guid, "ANDROID MMC DISK", 16);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,6 +613,27 @@ static int get_config_uint64(cnode *node, uint64_t *ptr, const char *name)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int get_config_string(cnode *node, char *ptr, int max_len, const char *name)
|
||||
{
|
||||
size_t begin, end;
|
||||
const char *value = config_str(node, name, NULL);
|
||||
if (!value)
|
||||
return -1;
|
||||
|
||||
begin = strcspn(value, "\"") + 1;
|
||||
end = strcspn(&value[begin], "\"");
|
||||
|
||||
if ((int) end > max_len) {
|
||||
D(WARN, "Identifier \"%s\" too long", value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(ptr, &value[begin], end);
|
||||
if((int) end < max_len)
|
||||
ptr[end] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void GPT_parse_header(cnode *node, struct GPT_content *content)
|
||||
{
|
||||
get_config_uint64(node, &content->header.current_lba, "header_lba");
|
||||
|
@ -614,17 +641,21 @@ static void GPT_parse_header(cnode *node, struct GPT_content *content)
|
|||
get_config_uint64(node, &content->header.first_usable_lba, "first_lba");
|
||||
get_config_uint64(node, &content->header.last_usable_lba, "last_lba");
|
||||
get_config_uint64(node, &content->header.entries_lba, "entries_lba");
|
||||
get_config_string(node, (char *) content->header.disk_guid, 16, "guid");
|
||||
}
|
||||
|
||||
static int GPT_parse_partitions(cnode *node, struct GPT_content *content)
|
||||
{
|
||||
cnode *current;
|
||||
int i;
|
||||
int ret;
|
||||
uint64_t partition_size;
|
||||
struct GPT_entry_raw *entry;
|
||||
for (i = 0, current = node->first_child; current; current = current->next, ++i) {
|
||||
entry = &content->entries[i];
|
||||
entry_set_guid(i, content->entries[i].partition_guid);
|
||||
memcpy(&content->entries[i].type_guid, partition_type_uuid, 16);
|
||||
if (get_config_uint64(current, &content->entries[i].first_lba, "first_lba")) {
|
||||
if (get_config_uint64(current, &entry->first_lba, "first_lba")) {
|
||||
D(ERR, "first_lba not specified");
|
||||
return 1;
|
||||
}
|
||||
|
@ -632,6 +663,19 @@ static int GPT_parse_partitions(cnode *node, struct GPT_content *content)
|
|||
D(ERR, "partition_size not specified");
|
||||
return 1;
|
||||
}
|
||||
if (config_str(current, "system", NULL)) {
|
||||
entry->flags |= GPT_FLAG_SYSTEM;
|
||||
}
|
||||
if (config_str(current, "bootable", NULL)) {
|
||||
entry->flags |= GPT_FLAG_BOOTABLE;
|
||||
}
|
||||
if (config_str(current, "readonly", NULL)) {
|
||||
entry->flags |= GPT_FLAG_READONLY;
|
||||
}
|
||||
if (config_str(current, "automount", NULL)) {
|
||||
entry->flags |= GPT_FLAG_DOAUTOMOUNT;
|
||||
}
|
||||
|
||||
get_config_uint64(current, &content->entries[i].flags, "flags");
|
||||
content->entries[i].last_lba = content->entries[i].first_lba + partition_size - 1;
|
||||
GPT_to_UTF16(content->entries[i].name, current->name, 16);
|
||||
|
@ -721,7 +765,7 @@ int GPT_write_content(const char *device, struct GPT_content *content)
|
|||
memcpy(maptable->entries, content->entries,
|
||||
content->header.entries_count * sizeof(*maptable->entries));
|
||||
|
||||
//GPT_sync(maptable);
|
||||
GPT_sync(maptable);
|
||||
GPT_release_device(maptable);
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -38,6 +38,11 @@
|
|||
#define GPT_ENTRIES 128
|
||||
#define GPT_NAMELEN 36
|
||||
|
||||
#define GPT_FLAG_SYSTEM (1ULL << 0)
|
||||
#define GPT_FLAG_BOOTABLE (1ULL << 2)
|
||||
#define GPT_FLAG_READONLY (1ULL << 60)
|
||||
#define GPT_FLAG_DOAUTOMOUNT (1ULL << 63)
|
||||
|
||||
// it should be passed in little endian order
|
||||
struct GPT_entry_raw {
|
||||
uint8_t type_guid[16];
|
||||
|
|
|
@ -197,12 +197,16 @@ void configPrintGPT(struct GPT_entry_table *table) {
|
|||
struct GPT_entry_raw *entry = table->entries;
|
||||
unsigned n, m;
|
||||
char name[GPT_NAMELEN + 1];
|
||||
char temp_guid[17];
|
||||
temp_guid[16] = 0;
|
||||
|
||||
printf("header_lba %lld\n", table->header->current_lba);
|
||||
printf("backup_lba %lld\n", table->header->backup_lba);
|
||||
printf("first_lba %lld\n", table->header->first_usable_lba);
|
||||
printf("last_lba %lld\n", table->header->last_usable_lba);
|
||||
printf("entries_lba %lld\n", table->header->entries_lba);
|
||||
snprintf(temp_guid, 17, "%s", table->header->disk_guid);
|
||||
printf("guid \"%s\"", temp_guid);
|
||||
|
||||
printf("\npartitions {\n");
|
||||
|
||||
|
@ -217,10 +221,18 @@ void configPrintGPT(struct GPT_entry_table *table) {
|
|||
name[m] = 0;
|
||||
|
||||
printf(" %s {\n", name);
|
||||
snprintf(temp_guid, 17, "%s", entry->partition_guid);
|
||||
printf(" guid \"%s\"\n", temp_guid);
|
||||
printf(" first_lba %lld\n", entry->first_lba);
|
||||
printf(" partition_size %lld\n", size);
|
||||
if (entry->flags != 0)
|
||||
printf(" flags %lld\n", entry->flags);
|
||||
if (entry->flags & GPT_FLAG_SYSTEM)
|
||||
printf(" system\n");
|
||||
if (entry->flags & GPT_FLAG_BOOTABLE)
|
||||
printf(" bootable\n");
|
||||
if (entry->flags & GPT_FLAG_READONLY)
|
||||
printf(" readonly\n");
|
||||
if (entry->flags & GPT_FLAG_DOAUTOMOUNT)
|
||||
printf(" automount\n");
|
||||
printf(" }\n\n");
|
||||
}
|
||||
printf("}\n");
|
||||
|
|
Loading…
Reference in New Issue