From 82af1f195b293910a58e8f89a014f12c3e5e70cf Mon Sep 17 00:00:00 2001 From: antifallobst Date: Tue, 30 May 2023 22:26:58 +0200 Subject: [PATCH] feature (drivers): started work on a driver handler / loader --- inc/drivers/builtin/elf/relocation.h | 36 +++++++++++++++ inc/drivers/driver.h | 66 ++++++++++++++++++++++++---- inc/mm/region.h | 9 ++-- src/boot/kmain.c | 27 ++++++------ src/drivers/builtin/elf/mapping.c | 8 ++-- src/drivers/builtin/elf/relocation.c | 17 +++++++ src/drivers/driver.c | 52 +++++++++++++++++++++- 7 files changed, 185 insertions(+), 30 deletions(-) create mode 100644 inc/drivers/builtin/elf/relocation.h create mode 100644 src/drivers/builtin/elf/relocation.c diff --git a/inc/drivers/builtin/elf/relocation.h b/inc/drivers/builtin/elf/relocation.h new file mode 100644 index 0000000..4f6190c --- /dev/null +++ b/inc/drivers/builtin/elf/relocation.h @@ -0,0 +1,36 @@ +// This file is part of noxos and licensed under the MIT open source license + +#ifndef NOXOS_RELOCATION_H +#define NOXOS_RELOCATION_H + +#include +#include + +#define ELF_RELOCATION_SYMBOL(i) ((i) >> 32) +#define ELF_RELOCATION_TYPE(i) ((i) & 0xFFFFFFFFL) +#define ELF_RELOCATION_INFO(s,t) (((s) << 32) + ((t) & 0xFFFFFFFFL)) + +#define ELF_RELOCATION_X86_64_PC32(s,a,p) (s + a - p) +#define ELF_RELOCATION_X86_64_PLT32(l,a,p) (l + a - p) + +typedef enum { + ELF_REL_NONE, + ELF_REL_64, + ELF_REL_PC32, + ELF_REL_GOT32, + ELF_REL_PLT32, + ELF_REL_COPY, + ELF_REL_GLOB_DAT, + ELF_REL_JUMP_SLOT, + ELF_REL_RELATIVE +} elf_relocation_type_E; + +typedef struct { + uint64_t offset; + uint64_t info; + int64_t addend; +} elf_relocation_a_T; + +void elf_relocate(elf_executable_T* executable, uint8_t* buffer, void* address); + +#endif //NOXOS_RELOCATION_H diff --git a/inc/drivers/driver.h b/inc/drivers/driver.h index b332952..47cfc0c 100644 --- a/inc/drivers/driver.h +++ b/inc/drivers/driver.h @@ -4,18 +4,51 @@ #define NOXOS_DRIVER_H #include +#include #include +#define DRIVER_MANAGER_CHUNK_SIZE 64 +#define DRIVER_MEMORY_REGION_SIZE 0x100000000 // 4 GB + typedef enum { DRIVER_TRANSPORT_PCI, DRIVER_TRANSPORT_USB, DRIVER_TRANSPORT_FS } __attribute__((packed)) driver_transport_protocol_E; +typedef enum { + + DRIVER_UNKNOWN = 0x0000, + DRIVER_RESERVED = 0x0001, + + // Specific Driver + + DRIVER_MASS_STORAGE = 0x0101, + DRIVER_FILESYSTEM = 0x0102, + DRIVER_GRAPHICS = 0x0103, + DRIVER_AUDIO = 0x0104, + + // Drivers which define the transmission of data but have multiple + // intended usages, such as USB for mass storage, input, etc.. + + DRIVER_TRANSMISSION = 0x0201, + DRIVER_USB_DEVICE = 0x0202, + DRIVER_PCI_DEVICE = 0x0203, + DRIVER_PCIE_DEVICE = 0x0204, + DRIVER_BLUETOOTH = 0x0205, + DRIVER_ETHERNET = 0x0206, + + // MISCELLANEOUS + + DRIVER_EMULATION = 0x7fff + +} driver_category_E; + typedef struct { driver_transport_protocol_E transport_protocol:8; + char name [0x80]; uint16_t length; - uint8_t specific_config[]; + uint8_t specific_config []; } __attribute__((packed)) driver_config_header_T; typedef struct { @@ -45,18 +78,33 @@ typedef struct { typedef struct { - + uint64_t id; + void* base; + elf_executable_T* executable; } driver_T; -typedef struct { +typedef struct driver_manager_chunk_T driver_manager_chunk_T; +struct driver_manager_chunk_T { + driver_T drivers [DRIVER_MANAGER_CHUNK_SIZE]; + bitmap_T drivers_bitmap; + uint32_t free_slots; + + driver_manager_chunk_T* prev; + driver_manager_chunk_T* next; +}; + +typedef struct { + driver_manager_chunk_T* driver_pool; } driver_manager_T; -void driver_manager_init (); -driver_T* driver_register (driver_config_header_T* config, elf_executable_T* executable); -driver_T* driver_lookup_pci_device (uint16_t vendor_id, uint16_t device_id); -driver_T* driver_lookup_usb_device (uint16_t vendor_id, uint16_t device_id); -driver_T* driver_lookup_fs_gpt (uint8_t guid[16]); -driver_T* driver_lookup_fs_mbr (uint8_t type); +void driver_manager_init (); +driver_manager_chunk_T* driver_manager_chunk_alloc(driver_manager_chunk_T* prev); +driver_T* driver_register (elf_executable_T* executable, uint8_t* buffer); +void driver_init (driver_T* driver, driver_config_header_T* conf); +driver_T* driver_lookup_pci_device (uint16_t vendor_id, uint16_t device_id); +driver_T* driver_lookup_usb_device (uint16_t vendor_id, uint16_t device_id); +driver_T* driver_lookup_fs_gpt (uint8_t guid[16]); +driver_T* driver_lookup_fs_mbr (uint8_t type); #endif //NOXOS_DRIVER_H diff --git a/inc/mm/region.h b/inc/mm/region.h index 2236259..f504798 100644 --- a/inc/mm/region.h +++ b/inc/mm/region.h @@ -16,10 +16,11 @@ #define MEM_REGION_PROCESS_USABLE 0x0000080000000000 #define MEM_REGION_KERNEL 0x0000800000000000 -#define MEM_REGION_KERNEL_STACK_DUMMY 0xFFFFF00000000000 // size 0x4000 -#define MEM_REGION_KERNEL_HEAP 0xFFFFF80000000000 -#define MEM_REGION_KERNEL_THREAD_BASE 0xFFFFFF0000000000 -#define MEM_REGION_KERNEL_EXEC 0xFFFFFFFF80000000 +#define MEM_REGION_KERNEL_DRIVERS 0xFFFFE80000000000 // size: up to 8 TB +#define MEM_REGION_KERNEL_STACK_DUMMY 0xFFFFF00000000000 // size: 4 KB +#define MEM_REGION_KERNEL_HEAP 0xFFFFF80000000000 // size: up to 8 TB +#define MEM_REGION_KERNEL_THREAD_BASE 0xFFFFFF0000000000 // size: up to 1022 GB +#define MEM_REGION_KERNEL_EXEC 0xFFFFFFFF80000000 // size: up to 2 GB extern uint64_t _kernel_start; extern uint64_t _kernel_end; diff --git a/src/boot/kmain.c b/src/boot/kmain.c index 33f1b6c..7b286bc 100644 --- a/src/boot/kmain.c +++ b/src/boot/kmain.c @@ -76,20 +76,21 @@ void kmain(boot_info_T boot_info) { log(LOG_INFO, "!=====[ Kernel Initialized ]=====!\n"); - pid_t pid; - syscall_perform(SYSCALL_PROCESS_CREATE, (uint64_t)"/initrd/shell.elf", 0, (uint64_t)&pid, 0); +// pid_t pid; +// syscall_perform(SYSCALL_PROCESS_CREATE, (uint64_t)"/initrd/shell.elf", 0, (uint64_t)&pid, 0); +// +// process_T* process = scheduler_get_process(pid); +// +// scheduler_dump_info(scheduler_get_process(PROCESS_KERNEL), 0); +// +// g_tty->output = &process->stdin; +// process->stdout = &g_tty->input; +// +// syscall_perform(SYSCALL_PROCESS_SIGNAL, pid, PROCESS_SIGNAL_START, 0, 0); - process_T* process = scheduler_get_process(pid); - - scheduler_dump_info(scheduler_get_process(PROCESS_KERNEL), 0); - - g_tty->output = &process->stdin; - process->stdout = &g_tty->input; - - syscall_perform(SYSCALL_PROCESS_SIGNAL, pid, PROCESS_SIGNAL_START, 0, 0); - - uint8_t digest[20]; - sha1_hash(digest, "test", 4); + vfs_node_T* node = vfs_resolve_path(&g_root_fs, "/initrd/test_driver.nxkm"); + elf_executable_T* executable = elf_executable_create(node->cache->buffer); + driver_register(executable, node->cache->buffer); CORE_HALT_FOREVER } diff --git a/src/drivers/builtin/elf/mapping.c b/src/drivers/builtin/elf/mapping.c index a91d382..ab092a4 100644 --- a/src/drivers/builtin/elf/mapping.c +++ b/src/drivers/builtin/elf/mapping.c @@ -7,7 +7,7 @@ #include "utils/memory.h" void elf_mapping_apply(elf_mapping_T* mapping, uint8_t* buffer, void* base, page_map_T* page_map) { - uint64_t num_pages = CEIL_TO(mapping->length_virtual, PFRAME_SIZE) / PFRAME_SIZE; + uint64_t num_pages = CEIL_TO(mapping->length_virtual + (mapping->offset_virtual % PFRAME_SIZE), PFRAME_SIZE) / PFRAME_SIZE; log(LOG_INFO, "Mapping: 0x%x -> 0x%x PAGES[%d]", mapping->offset_file, base + mapping->offset_virtual, num_pages); void* virtual_address = base + mapping->offset_virtual; @@ -28,8 +28,10 @@ void elf_mapping_apply(elf_mapping_T* mapping, uint8_t* buffer, void* base, page memory_copy(&buffer[mapping->offset_file], virtual_address, mapping->length_file); - for (uint64_t i = 0; i < num_pages; i++) { - page_map_unmap_memory(g_kernel_page_map, virtual_address + (PFRAME_SIZE * i)); + if (page_map != g_kernel_page_map) { + for (uint64_t i = 0; i < num_pages; i++) { + page_map_unmap_memory(g_kernel_page_map, virtual_address + (PFRAME_SIZE * i)); + } } } diff --git a/src/drivers/builtin/elf/relocation.c b/src/drivers/builtin/elf/relocation.c new file mode 100644 index 0000000..250542e --- /dev/null +++ b/src/drivers/builtin/elf/relocation.c @@ -0,0 +1,17 @@ +// This file is part of noxos and licensed under the MIT open source license + +#include +#include + +void elf_relocate(elf_executable_T* executable, uint8_t* buffer, void* address) { + elf_section_T* sections = (elf_section_T*)&buffer[executable->header.offset_section_header]; + for (uint32_t i = 0; i < executable->header.num_section_header_entries; i++) { + if (sections[i].type != ELF_SECTION_RELOCATION_A) continue; + + uint32_t num_relocations = sections[i].length / sections[i].entry_size; + elf_section_T* related_section = §ions[sections[i].info]; + + DEBUG("Found RELA section -> relocations: %d section: 0x%x", num_relocations, related_section); + + } +} diff --git a/src/drivers/driver.c b/src/drivers/driver.c index 40b0a46..0fa4be6 100644 --- a/src/drivers/driver.c +++ b/src/drivers/driver.c @@ -1,12 +1,30 @@ // This file is part of noxos and licensed under the MIT open source license #include +#include #include +#include +#include +#include driver_manager_T g_driver_manager; void driver_manager_init() { + g_driver_manager.driver_pool = driver_manager_chunk_alloc(NULL); +} +driver_manager_chunk_T* driver_manager_chunk_alloc(driver_manager_chunk_T* prev) { + driver_manager_chunk_T* chunk = memory_allocate(sizeof(driver_manager_chunk_T)); + + chunk->drivers_bitmap = bitmap_init(DRIVER_MANAGER_CHUNK_SIZE); + chunk->free_slots = DRIVER_MANAGER_CHUNK_SIZE; + chunk->prev = prev; + + if (chunk->prev != NULL) { + chunk->prev->next = chunk; + } + + return chunk; } driver_T* driver_find_pci_device(uint16_t vendor_id, uint16_t device_id) { @@ -29,10 +47,42 @@ driver_T* driver_find_fs_mbr(uint8_t type) { return NULL; } -driver_T* driver_register(driver_config_header_T* config, elf_executable_T* executable) { +driver_T* driver_register(elf_executable_T* executable, uint8_t* buffer) { + uint64_t chunk_id = 0; + driver_manager_chunk_T* chunk = g_driver_manager.driver_pool; + while (chunk->free_slots == 0) { + if (chunk->next == NULL) { + driver_manager_chunk_alloc(chunk); + } + chunk = chunk->next; + chunk_id++; + } + + driver_T* driver; + for (uint64_t i = 0; i < DRIVER_MANAGER_CHUNK_SIZE; i++) { + if (bitmap_get(&chunk->drivers_bitmap, i)) continue; + + bitmap_set(&chunk->drivers_bitmap, i, true); + chunk->free_slots -= 1; + driver = &chunk->drivers[i]; + driver->id = chunk_id + i; + break; + } + + driver->base = (void*)(MEM_REGION_KERNEL_DRIVERS + (driver->id * DRIVER_MEMORY_REGION_SIZE)); + driver->executable = executable; + + + elf_mappings_apply(executable->mappings, executable->num_mappings, buffer, driver->base, g_kernel_page_map); + elf_relocate(executable, buffer, driver->base); + return NULL; } +void driver_init(driver_T* driver, driver_config_header_T* conf) { + +} + driver_T* driver_lookup_pci_device(uint16_t vendor_id, uint16_t device_id) { return NULL; }