feature (drivers): implemented an infrastructure to link drivers into the kernel
This commit is contained in:
parent
3d4cea2060
commit
7d33377806
|
@ -31,6 +31,7 @@ typedef struct {
|
|||
int64_t addend;
|
||||
} elf_relocation_a_T;
|
||||
|
||||
void elf_relocate(elf_executable_T* executable, uint8_t* buffer, void* address);
|
||||
//void elf_relocate (elf_executable_T* executable, uint8_t* buffer, void* address);
|
||||
bool elf_relocate_driver(elf_executable_T* executable, uint8_t* buffer, void* load_address);
|
||||
|
||||
#endif //NOXOS_RELOCATION_H
|
||||
|
|
|
@ -16,6 +16,9 @@ typedef enum {
|
|||
ELF_SECTION_DYNAMIC,
|
||||
ELF_SECTION_NOTE,
|
||||
ELF_SECTION_NOBITS,
|
||||
ELF_SECTION_REL,
|
||||
ELF_SECTION_SHLIB,
|
||||
ELF_SECTION_DYNAMIC_SYMBOL_TABLE,
|
||||
|
||||
ELF_SECTION_ENUM_END
|
||||
} elf_section_type_E;
|
||||
|
|
|
@ -88,9 +88,14 @@ void kmain(boot_info_T boot_info) {
|
|||
//
|
||||
// syscall_perform(SYSCALL_PROCESS_SIGNAL, pid, PROCESS_SIGNAL_START, 0, 0);
|
||||
|
||||
vfs_node_T* node = vfs_resolve_path(&g_root_fs, "/initrd/test_driver.nxkm");
|
||||
vfs_node_T* node = vfs_resolve_path(&g_root_fs, "/initrd/test.nxkm");
|
||||
elf_executable_T* executable = elf_executable_create(node->cache->buffer);
|
||||
driver_register(executable, node->cache->buffer);
|
||||
driver_T* drv = driver_register(executable, node->cache->buffer);
|
||||
|
||||
void* entry = drv->base + symbol_resolve_from_name(executable->symbols, executable->num_symbols, "_start")->address;
|
||||
|
||||
void (*drv_test)() = entry;
|
||||
drv_test();
|
||||
|
||||
CORE_HALT_FOREVER
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
// This file is part of noxos and licensed under the MIT open source license
|
||||
|
||||
#include <utils/logger.h>
|
||||
|
||||
void nx_drv_init() {
|
||||
DEBUG("hello from the driver api");
|
||||
}
|
|
@ -1,26 +1,106 @@
|
|||
// This file is part of noxos and licensed under the MIT open source license
|
||||
|
||||
#include <drivers/builtin/elf/relocation.h>
|
||||
#include <drivers/builtin/elf/dynamic.h>
|
||||
#include <drivers/builtin/elf/symbol.h>
|
||||
#include <utils/logger.h>
|
||||
#include <utils/memory.h>
|
||||
#include <proc/scheduler.h>
|
||||
|
||||
void elf_relocate(elf_executable_T* executable, uint8_t* buffer, void* address) {
|
||||
//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];
|
||||
// elf_section_T* section_dynamic = NULL;
|
||||
// for (uint32_t i = 0; i < executable->header.num_section_header_entries; i++) {
|
||||
// if (sections[i].type != ELF_SECTION_DYNAMIC) continue;
|
||||
// section_dynamic = §ions[i];
|
||||
// DEBUG("Found DYNAMIC section %d", i);
|
||||
// break;
|
||||
// }
|
||||
// if (section_dynamic == NULL) {
|
||||
// log(LOG_ERROR, "Failed to relocate ELF executable (no .dynamic section found)");
|
||||
// return;
|
||||
// }
|
||||
// uint32_t num_dynamic_entries = section_dynamic->length / section_dynamic->entry_size;
|
||||
// elf_dynamic_T* dynamic_entries = (elf_dynamic_T*)&buffer[section_dynamic->offset];
|
||||
// uint32_t num_needed_libraries = 0;
|
||||
//
|
||||
// for (int i = 0; i < num_dynamic_entries; i++) {
|
||||
// switch (dynamic_entries[i].tag) {
|
||||
// case ELF_DYNAMIC_TAG_NEEDED: {
|
||||
// num_needed_libraries++;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// log(LOG_ERROR, "Failed to relocate executable (not implemented)");
|
||||
//
|
||||
//}
|
||||
|
||||
bool elf_relocate_driver(elf_executable_T* executable, uint8_t* buffer, void* load_address) {
|
||||
elf_section_T* sections = (elf_section_T*)&buffer[executable->header.offset_section_header];
|
||||
string_t section_names = (string_t)&buffer[sections[executable->header.string_section_index].offset];
|
||||
elf_section_T* section_dynamic = NULL;
|
||||
elf_section_T* section_dynstr = NULL;
|
||||
elf_section_T* section_dynsym = NULL;
|
||||
|
||||
for (uint32_t i = 0; i < executable->header.num_section_header_entries; i++) {
|
||||
if (sections[i].type != ELF_SECTION_DYNAMIC) continue;
|
||||
section_dynamic = §ions[i];
|
||||
DEBUG("Found DYNAMIC section %d", i);
|
||||
break;
|
||||
switch (sections[i].type) {
|
||||
case ELF_SECTION_DYNAMIC: {
|
||||
section_dynamic = §ions[i];
|
||||
break;
|
||||
}
|
||||
case ELF_SECTION_STRING_TABLE: {
|
||||
if (!string_compare(".dynstr", §ion_names[sections[i].name_offset])) break;
|
||||
section_dynstr = §ions[i];
|
||||
break;
|
||||
}
|
||||
case ELF_SECTION_DYNAMIC_SYMBOL_TABLE: {
|
||||
section_dynsym = §ions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (section_dynamic == NULL) {
|
||||
log(LOG_ERROR, "Failed to relocate ELF executable (no .dynamic section found)");
|
||||
return;
|
||||
log(LOG_ERROR, "Failed to relocate driver executable (no .dynamic section found)");
|
||||
return false;
|
||||
}
|
||||
if (section_dynstr == NULL) {
|
||||
log(LOG_ERROR, "Failed to relocate driver executable (no .dynstr section found)");
|
||||
return false;
|
||||
}
|
||||
if (section_dynsym == NULL) {
|
||||
log(LOG_ERROR, "Failed to relocate driver executable (no .dynsym section found)");
|
||||
return false;
|
||||
}
|
||||
|
||||
// elf_section_T* section_rela = ;
|
||||
//
|
||||
// uint32_t num_relocations = sections[i].length / sections[i].entry_size;
|
||||
// elf_section_T* related_section = §ions[sections[i].info];
|
||||
for (uint32_t i = 0; i < executable->header.num_section_header_entries; i++) {
|
||||
if (sections[i].type != ELF_SECTION_RELOCATION_A) continue;
|
||||
|
||||
// DEBUG("Found RELA section -> relocations: %d section: 0x%x", num_relocations, related_section);
|
||||
symbol_T* symbols = scheduler_get_process(PROCESS_KERNEL)->executable->symbols;
|
||||
uint64_t num_symbols = scheduler_get_process(PROCESS_KERNEL)->executable->num_symbols;
|
||||
|
||||
uint32_t num_relocations = sections[i].length / sections[i].entry_size;
|
||||
for (int j = 0; j < num_relocations; j++) {
|
||||
elf_relocation_a_T* relocation = &((elf_relocation_a_T*)&buffer[sections[i].offset])[j];
|
||||
uint64_t* relocation_offset = (uint64_t*)&((uint8_t*)load_address)[relocation->offset];
|
||||
elf_relocation_type_E relocation_type = ELF_RELOCATION_TYPE(relocation->info);
|
||||
elf_symbol_T* drv_symbol = &((elf_symbol_T*)&buffer[section_dynsym->offset])[ELF_RELOCATION_SYMBOL(relocation->info)];
|
||||
string_t drv_symbol_name = (string_t)&buffer[section_dynstr->offset + drv_symbol->name_offset];
|
||||
symbol_T* k_symbol = symbol_resolve_from_name(symbols, num_symbols, drv_symbol_name);
|
||||
if (k_symbol == NULL) {
|
||||
log(LOG_ERROR, "Failed to relocate driver (symbol '%s' not found in kernel)", drv_symbol_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (relocation_type) {
|
||||
case ELF_REL_JUMP_SLOT: {
|
||||
*relocation_offset = k_symbol->address;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -12,6 +12,9 @@ string_t g_elf_section_type_strings[ELF_SECTION_ENUM_END+1] = {
|
|||
"Dynamic Linker Info",
|
||||
"Note",
|
||||
"No Bits",
|
||||
"Relocation",
|
||||
"Unspecified Semantics (Not ABI Conform)",
|
||||
"Symbol Table (Dynamic)",
|
||||
|
||||
"Unknown"
|
||||
};
|
|
@ -74,9 +74,15 @@ driver_T* driver_register(elf_executable_T* executable, uint8_t* buffer) {
|
|||
|
||||
|
||||
elf_mappings_apply(executable->mappings, executable->num_mappings, buffer, driver->base, g_kernel_page_map);
|
||||
elf_relocate(executable, buffer, driver->base);
|
||||
bool status = elf_relocate_driver(executable, buffer, driver->base);
|
||||
if (!status) {
|
||||
bitmap_set(&chunk->drivers_bitmap, driver->id % DRIVER_MANAGER_CHUNK_SIZE, false);
|
||||
chunk->free_slots += 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
return driver;
|
||||
}
|
||||
|
||||
void driver_init(driver_T* driver, driver_config_header_T* conf) {
|
||||
|
|
Loading…
Reference in New Issue