diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c index 6fa3df0..7fdbf53 100644 --- a/drivers/partition/partition.c +++ b/drivers/partition/partition.c @@ -105,6 +105,57 @@ return 0; } +static int load_mbr_entry(uintptr_t image_handle, mbr_entry_t *mbr_entry, + int part_number) +{ + size_t bytes_read; + uintptr_t offset; + int result; + + assert(mbr_entry != NULL); + /* MBR partition table is in LBA0. */ + result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET); + if (result != 0) { + WARN("Failed to seek (%i)\n", result); + return result; + } + result = io_read(image_handle, (uintptr_t)&mbr_sector, + PARTITION_BLOCK_SIZE, &bytes_read); + if (result != 0) { + WARN("Failed to read data (%i)\n", result); + return result; + } + + /* Check MBR boot signature. */ + if ((mbr_sector[PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) || + (mbr_sector[PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) { + return -ENOENT; + } + offset = (uintptr_t)&mbr_sector + + MBR_PRIMARY_ENTRY_OFFSET + + MBR_PRIMARY_ENTRY_SIZE * part_number; + memcpy(mbr_entry, (void *)offset, sizeof(mbr_entry_t)); + + return 0; +} + +static int load_mbr_entries(uintptr_t image_handle) +{ + mbr_entry_t mbr_entry; + int i; + + list.entry_count = MBR_PRIMARY_ENTRY_NUMBER; + + for (i = 0; i < list.entry_count; i++) { + load_mbr_entry(image_handle, &mbr_entry, i); + list.list[i].start = mbr_entry.first_lba * 512; + list.list[i].length = mbr_entry.sector_nums * 512; + list.list[i].name[0] = mbr_entry.type; + } + + return 0; +} + static int load_gpt_entry(uintptr_t image_handle, gpt_entry_t *entry) { size_t bytes_read; @@ -175,11 +226,9 @@ assert(result == 0); result = verify_partition_gpt(image_handle); } else { - /* MBR type isn't supported yet. */ - result = -EINVAL; - goto exit; + result = load_mbr_entries(image_handle); } -exit: + io_close(image_handle); return result; }