feature (drivers): started work on a driver handler / loader
This commit is contained in:
parent
7e53ab9e7c
commit
82af1f195b
|
@ -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 <utils/stdtypes.h>
|
||||||
|
#include <drivers/builtin/elf/elf.h>
|
||||||
|
|
||||||
|
#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
|
|
@ -4,16 +4,49 @@
|
||||||
#define NOXOS_DRIVER_H
|
#define NOXOS_DRIVER_H
|
||||||
|
|
||||||
#include <utils/stdtypes.h>
|
#include <utils/stdtypes.h>
|
||||||
|
#include <utils/bitmap.h>
|
||||||
#include <drivers/builtin/elf/elf.h>
|
#include <drivers/builtin/elf/elf.h>
|
||||||
|
|
||||||
|
#define DRIVER_MANAGER_CHUNK_SIZE 64
|
||||||
|
#define DRIVER_MEMORY_REGION_SIZE 0x100000000 // 4 GB
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DRIVER_TRANSPORT_PCI,
|
DRIVER_TRANSPORT_PCI,
|
||||||
DRIVER_TRANSPORT_USB,
|
DRIVER_TRANSPORT_USB,
|
||||||
DRIVER_TRANSPORT_FS
|
DRIVER_TRANSPORT_FS
|
||||||
} __attribute__((packed)) driver_transport_protocol_E;
|
} __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 {
|
typedef struct {
|
||||||
driver_transport_protocol_E transport_protocol:8;
|
driver_transport_protocol_E transport_protocol:8;
|
||||||
|
char name [0x80];
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
uint8_t specific_config [];
|
uint8_t specific_config [];
|
||||||
} __attribute__((packed)) driver_config_header_T;
|
} __attribute__((packed)) driver_config_header_T;
|
||||||
|
@ -45,15 +78,30 @@ typedef struct {
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
uint64_t id;
|
||||||
|
void* base;
|
||||||
|
elf_executable_T* executable;
|
||||||
} driver_T;
|
} 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;
|
} driver_manager_T;
|
||||||
|
|
||||||
void driver_manager_init ();
|
void driver_manager_init ();
|
||||||
driver_T* driver_register (driver_config_header_T* config, elf_executable_T* executable);
|
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_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_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_gpt (uint8_t guid[16]);
|
||||||
|
|
|
@ -16,10 +16,11 @@
|
||||||
#define MEM_REGION_PROCESS_USABLE 0x0000080000000000
|
#define MEM_REGION_PROCESS_USABLE 0x0000080000000000
|
||||||
|
|
||||||
#define MEM_REGION_KERNEL 0x0000800000000000
|
#define MEM_REGION_KERNEL 0x0000800000000000
|
||||||
#define MEM_REGION_KERNEL_STACK_DUMMY 0xFFFFF00000000000 // size 0x4000
|
#define MEM_REGION_KERNEL_DRIVERS 0xFFFFE80000000000 // size: up to 8 TB
|
||||||
#define MEM_REGION_KERNEL_HEAP 0xFFFFF80000000000
|
#define MEM_REGION_KERNEL_STACK_DUMMY 0xFFFFF00000000000 // size: 4 KB
|
||||||
#define MEM_REGION_KERNEL_THREAD_BASE 0xFFFFFF0000000000
|
#define MEM_REGION_KERNEL_HEAP 0xFFFFF80000000000 // size: up to 8 TB
|
||||||
#define MEM_REGION_KERNEL_EXEC 0xFFFFFFFF80000000
|
#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_start;
|
||||||
extern uint64_t _kernel_end;
|
extern uint64_t _kernel_end;
|
||||||
|
|
|
@ -76,20 +76,21 @@ void kmain(boot_info_T boot_info) {
|
||||||
|
|
||||||
log(LOG_INFO, "!=====[ Kernel Initialized ]=====!\n");
|
log(LOG_INFO, "!=====[ Kernel Initialized ]=====!\n");
|
||||||
|
|
||||||
pid_t pid;
|
// pid_t pid;
|
||||||
syscall_perform(SYSCALL_PROCESS_CREATE, (uint64_t)"/initrd/shell.elf", 0, (uint64_t)&pid, 0);
|
// 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);
|
vfs_node_T* node = vfs_resolve_path(&g_root_fs, "/initrd/test_driver.nxkm");
|
||||||
|
elf_executable_T* executable = elf_executable_create(node->cache->buffer);
|
||||||
scheduler_dump_info(scheduler_get_process(PROCESS_KERNEL), 0);
|
driver_register(executable, node->cache->buffer);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
CORE_HALT_FOREVER
|
CORE_HALT_FOREVER
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "utils/memory.h"
|
#include "utils/memory.h"
|
||||||
|
|
||||||
void elf_mapping_apply(elf_mapping_T* mapping, uint8_t* buffer, void* base, page_map_T* page_map) {
|
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);
|
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;
|
void* virtual_address = base + mapping->offset_virtual;
|
||||||
|
@ -28,10 +28,12 @@ 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);
|
memory_copy(&buffer[mapping->offset_file], virtual_address, mapping->length_file);
|
||||||
|
|
||||||
|
if (page_map != g_kernel_page_map) {
|
||||||
for (uint64_t i = 0; i < num_pages; i++) {
|
for (uint64_t i = 0; i < num_pages; i++) {
|
||||||
page_map_unmap_memory(g_kernel_page_map, virtual_address + (PFRAME_SIZE * i));
|
page_map_unmap_memory(g_kernel_page_map, virtual_address + (PFRAME_SIZE * i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void elf_mappings_apply(elf_mapping_T* mappings, uint64_t num_mappings, uint8_t* buffer, void* base, page_map_T* page_map) {
|
void elf_mappings_apply(elf_mapping_T* mappings, uint64_t num_mappings, uint8_t* buffer, void* base, page_map_T* page_map) {
|
||||||
for (uint64_t i = 0; i < num_mappings; i++) {
|
for (uint64_t i = 0; i < num_mappings; i++) {
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
// This file is part of noxos and licensed under the MIT open source license
|
||||||
|
|
||||||
|
#include <drivers/builtin/elf/relocation.h>
|
||||||
|
#include <utils/logger.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,30 @@
|
||||||
// This file is part of noxos and licensed under the MIT open source license
|
// This file is part of noxos and licensed under the MIT open source license
|
||||||
|
|
||||||
#include <drivers/driver.h>
|
#include <drivers/driver.h>
|
||||||
|
#include <drivers/builtin/elf/relocation.h>
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
|
#include <utils/memory.h>
|
||||||
|
#include <proc/scheduler.h>
|
||||||
|
#include <mm/region.h>
|
||||||
|
|
||||||
driver_manager_T g_driver_manager;
|
driver_manager_T g_driver_manager;
|
||||||
|
|
||||||
void driver_manager_init() {
|
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) {
|
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;
|
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;
|
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) {
|
driver_T* driver_lookup_pci_device(uint16_t vendor_id, uint16_t device_id) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue