From c9d57639c167f9ab5f5345ea42c4eae6d8473392 Mon Sep 17 00:00:00 2001 From: antifallobst Date: Mon, 8 May 2023 00:19:36 +0200 Subject: [PATCH] feature (GPT): implemented basic GPT decoding --- inc/drivers/ahci.h | 20 ++++++------ inc/drivers/fs/gpt.h | 47 +++++++++++++++++++++++++++++ inc/drivers/fs/mbr.h | 6 ++-- src/drivers/ahci.c | 72 ++++++++++++++++++++++++++++++++++---------- src/drivers/fs/gpt.c | 9 ++++++ 5 files changed, 126 insertions(+), 28 deletions(-) create mode 100644 inc/drivers/fs/gpt.h create mode 100644 src/drivers/fs/gpt.c diff --git a/inc/drivers/ahci.h b/inc/drivers/ahci.h index fe0cd35..5e5baa1 100644 --- a/inc/drivers/ahci.h +++ b/inc/drivers/ahci.h @@ -227,16 +227,18 @@ typedef struct { ahci_hba_memory_T* abar; } ahci_controller_T; -ahci_controller_T* ahci_controller_alloc (pci_device_T* pci_device); -void ahci_controller_destruct (ahci_controller_T* controller); +ahci_controller_T* ahci_controller_alloc (pci_device_T* pci_device); +void ahci_controller_destruct (ahci_controller_T* controller); -void ahci_port_init (ahci_port_T* port); -void ahci_port_destruct (ahci_port_T* port); -ahci_device_type_E ahci_port_get_type (ahci_hba_port_T* port); -void ahci_port_command_stop (ahci_port_T* port); -void ahci_port_command_start (ahci_port_T* port); -bool ahci_port_read (ahci_port_T* port, uint64_t sector, uint32_t num_sectors, void* buffer_out); -bool ahci_port_write (ahci_port_T* port, uint64_t sector, uint32_t num_sectors, void* buffer_in); +void ahci_port_init (ahci_port_T* port); +void ahci_port_init_partitions_mbr (ahci_port_T* port); +void ahci_port_init_partitions_gpt (ahci_port_T* port); +void ahci_port_destruct (ahci_port_T* port); +ahci_device_type_E ahci_port_get_type (ahci_hba_port_T* port); +void ahci_port_command_stop (ahci_port_T* port); +void ahci_port_command_start (ahci_port_T* port); +bool ahci_port_read (ahci_port_T* port, uint64_t sector, uint32_t num_sectors, void* buffer_out); +bool ahci_port_write (ahci_port_T* port, uint64_t sector, uint32_t num_sectors, void* buffer_in); extern string_t g_ahci_device_type_strings[AHCI_DEVICE_TYPE_END_OF_ENUM]; diff --git a/inc/drivers/fs/gpt.h b/inc/drivers/fs/gpt.h new file mode 100644 index 0000000..1ee0a35 --- /dev/null +++ b/inc/drivers/fs/gpt.h @@ -0,0 +1,47 @@ +// This file is part of noxos and licensed under the MIT open source license + +#ifndef NOXOS_GPT_H +#define NOXOS_GPT_H + +#include "utils/stdtypes.h" + +#define GPT_PARTITION_TYPE_GUID_MATCH(g, t) ((g[0] == g_gpt_partition_type_guides[t][0]) && (g[1] == g_gpt_partition_type_guides[t][1])) + +typedef enum { + GPT_PARTITION_GUID_UNUSED, + GPT_PARTITION_GUID_BASIC_DATA, + GPT_PARTITION_GUID_EFI_SYSTEM, + + GPT_PARTITION_GUID_ENUM_END +} gpt_partition_type_guids_E; + +typedef struct { + uint8_t signature [8]; + uint32_t revision; + uint32_t header_size; + uint32_t checksum_crc32; + uint32_t reserved; + uint64_t current_lba; + uint64_t backup_lba; + uint64_t first_usable_lba; + uint64_t last_usable_lba; + uint64_t disk_guid [2]; + uint64_t starting_lba; + uint32_t num_partitions; + uint32_t partition_entry_size; + uint32_t partition_entry_crc32; + uint8_t reserved2 [0x1A4]; +}__attribute__((packed)) gpt_table_header_T; + +typedef struct { + uint64_t partition_type_guid [2]; + uint64_t partition_guid [2]; + uint64_t starting_lba; + uint64_t ending_lba; + uint64_t attributes; + uint8_t name [72]; +}__attribute__((packed)) gpt_partition_entry_T; + +extern uint64_t g_gpt_partition_type_guides[GPT_PARTITION_GUID_ENUM_END][2]; + +#endif //NOXOS_GPT_H diff --git a/inc/drivers/fs/mbr.h b/inc/drivers/fs/mbr.h index fa13f9c..3cf7f10 100644 --- a/inc/drivers/fs/mbr.h +++ b/inc/drivers/fs/mbr.h @@ -1,7 +1,7 @@ // This file is part of noxos and licensed under the MIT open source license -#ifndef KERNEL_MBR_H -#define KERNEL_MBR_H +#ifndef NOXOS_MBR_H +#define NOXOS_MBR_H #include "utils/stdtypes.h" #include "utils/string.h" @@ -37,4 +37,4 @@ typedef struct { string_t mbr_partition_type_to_string(mbr_partition_types_E type); -#endif //KERNEL_MBR_H +#endif //NOXOS_MBR_H diff --git a/src/drivers/ahci.c b/src/drivers/ahci.c index 41d355c..d0ce1b1 100644 --- a/src/drivers/ahci.c +++ b/src/drivers/ahci.c @@ -2,6 +2,7 @@ #include "drivers/ahci.h" #include "drivers/fs/mbr.h" +#include "drivers/fs/gpt.h" #include "utils/memory.h" #include "utils/logger.h" #include "mm/page_map.h" @@ -51,22 +52,6 @@ ahci_controller_T* ahci_controller_alloc(pci_device_T* pci_device) { for (int i = 0; i < controller->num_ports; i++) { log(LOG_INFO, " %s", g_ahci_device_type_strings[controller->ports[i].type]); ahci_port_init(&controller->ports[i]); - - uint8_t* addr = memory_allocate(512 + PFRAME_SIZE); - void* buffer = (void*)CEIL_TO((uint64_t)addr, PFRAME_SIZE); - - if (ahci_port_read(&controller->ports[i], 0, 1, buffer)) { - mbr_header_T* mbr = (mbr_header_T*)buffer; - - log(LOG_INFO, " MBR:"); - for (int j = 0; j < 4; j++) { - mbr_partition_types_E type = mbr->partitions[j].partition_type; - if (type == MBR_PARTITION_TYPE_UNUSED) continue; - log(LOG_INFO, " p%d: 0x%xb - %s", j, type, mbr_partition_type_to_string(type)); - } - } - - memory_free(addr); } return controller; @@ -108,6 +93,61 @@ void ahci_port_init(ahci_port_T* port) { } ahci_port_command_start(port); + + ahci_port_init_partitions_mbr(port); +} + +void ahci_port_init_partitions_mbr(ahci_port_T* port) { + uint8_t* addr = memory_allocate(512 + PFRAME_SIZE); + void* buffer = (void*)CEIL_TO((uint64_t)addr, PFRAME_SIZE); + + if (ahci_port_read(port, 0, 1, buffer)) { + mbr_header_T* mbr = (mbr_header_T*)buffer; + + log(LOG_INFO, " MBR:"); + for (int i = 0; i < 4; i++) { + mbr_partition_types_E type = mbr->partitions[i].partition_type; + if (type == MBR_PARTITION_TYPE_UNUSED) continue; + + log(LOG_INFO, " p%d: 0x%xb - %d - %s", i, type, mbr->partitions[i].start_lba, mbr_partition_type_to_string(type)); + + if (type == MBR_PARTITION_TYPE_GPT) { + ahci_port_init_partitions_gpt(port); + break; + } + } + } + + memory_free(addr); +} + +void ahci_port_init_partitions_gpt(ahci_port_T* port) { + uint8_t* addr_header = memory_allocate(512 + PFRAME_SIZE); + void* buffer_header = (void*)CEIL_TO((uint64_t)addr_header, PFRAME_SIZE); + + if (ahci_port_read(port, 1, 1, buffer_header)) { + gpt_table_header_T* gpt = (gpt_table_header_T*)buffer_header; + + uint32_t num_sectors = CEIL_TO(gpt->num_partitions, 4) / 4; + + uint8_t* addr_entries = memory_allocate((512 * num_sectors) + PFRAME_SIZE); + void* buffer_entries = (void*)CEIL_TO((uint64_t)addr_entries, PFRAME_SIZE); + + if (ahci_port_read(port, 2, num_sectors, buffer_entries)) { + gpt_partition_entry_T* entries = (gpt_partition_entry_T*)buffer_entries; + + log(LOG_INFO, " GPT:"); + for (int i = 0; i < gpt->num_partitions; i++) { + gpt_partition_entry_T* entry = &entries[i]; + if (GPT_PARTITION_TYPE_GUID_MATCH(entry->partition_type_guid, GPT_PARTITION_GUID_UNUSED)) continue; + log(LOG_INFO, " p%d: %x%x", i, entry->partition_type_guid[0], entry->partition_type_guid[1]); + } + } + + memory_free(addr_entries); + } + + memory_free(addr_header); } void ahci_port_destruct(ahci_port_T* port) { diff --git a/src/drivers/fs/gpt.c b/src/drivers/fs/gpt.c new file mode 100644 index 0000000..fd485f0 --- /dev/null +++ b/src/drivers/fs/gpt.c @@ -0,0 +1,9 @@ +// This file is part of noxos and licensed under the MIT open source license + +#include "drivers/fs/gpt.h" + +uint64_t g_gpt_partition_type_guides[GPT_PARTITION_GUID_ENUM_END][2] = { + {0x0000000000000000, 0x0000000000000000}, + {0x11D2F81FC12A7328, 0x3BC93EC9A0004BBA}, + {0x28732AC11FF8D211, 0xBA4B00A0C93EC93B} +}; \ No newline at end of file