feature (ELF): implemented ELF loading / segment mapping
This commit is contained in:
parent
9cfa6b5d1e
commit
adb457de01
|
@ -26,12 +26,15 @@
|
||||||
|
|
||||||
#include "drivers/elf/header.h"
|
#include "drivers/elf/header.h"
|
||||||
#include "drivers/elf/section.h"
|
#include "drivers/elf/section.h"
|
||||||
|
#include "drivers/elf/mapping.h"
|
||||||
#include "utils/symbol.h"
|
#include "utils/symbol.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
elf_header_T header;
|
elf_header_T header;
|
||||||
uint64_t num_symbols;
|
uint64_t num_symbols;
|
||||||
symbol_T* symbols;
|
symbol_T* symbols;
|
||||||
|
uint64_t num_mappings;
|
||||||
|
elf_mapping_T* mappings;
|
||||||
void* string_table;
|
void* string_table;
|
||||||
} elf_executable_T;
|
} elf_executable_T;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 Antifallobst <antifallobst@systemausfall.org>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the “Software”), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NOX_MAPPING_H
|
||||||
|
#define NOX_MAPPING_H
|
||||||
|
|
||||||
|
#include "utils/stdtypes.h"
|
||||||
|
#include "mm/page_map.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t offset_file;
|
||||||
|
uint64_t offset_virtual;
|
||||||
|
uint64_t length_file;
|
||||||
|
uint64_t length_virtual;
|
||||||
|
uint64_t alignment;
|
||||||
|
} elf_mapping_T;
|
||||||
|
|
||||||
|
void elf_mappings_apply(elf_mapping_T* mappings, uint64_t num_mappings, uint8_t* buffer, void* base, page_map_T* page_map);
|
||||||
|
|
||||||
|
#endif //NOX_MAPPING_H
|
|
@ -36,7 +36,9 @@ typedef enum {
|
||||||
ELF_SECTION_HASH,
|
ELF_SECTION_HASH,
|
||||||
ELF_SECTION_DYNAMIC_LINK,
|
ELF_SECTION_DYNAMIC_LINK,
|
||||||
ELF_SECTION_NOTE,
|
ELF_SECTION_NOTE,
|
||||||
ELF_SECTION_NOBITS
|
ELF_SECTION_NOBITS,
|
||||||
|
|
||||||
|
ELF_SECTION_ENUM_END
|
||||||
} elf_section_type_E;
|
} elf_section_type_E;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -52,6 +54,6 @@ typedef struct {
|
||||||
uint64_t entry_size;
|
uint64_t entry_size;
|
||||||
} elf_section_T;
|
} elf_section_T;
|
||||||
|
|
||||||
extern string_t g_elf_section_type_strings[9];
|
extern string_t g_elf_section_type_strings[ELF_SECTION_ENUM_END+1];
|
||||||
|
|
||||||
#endif //NOX_SECTION_H
|
#endif //NOX_SECTION_H
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 Antifallobst <antifallobst@systemausfall.org>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the “Software”), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NOX_SEGMENT_H
|
||||||
|
#define NOX_SEGMENT_H
|
||||||
|
|
||||||
|
#include "utils/stdtypes.h"
|
||||||
|
#include "utils/string.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ELF_SEGMENT_NULL,
|
||||||
|
ELF_SEGMENT_LOAD,
|
||||||
|
ELF_SEGMENT_DYNAMIC,
|
||||||
|
ELF_SEGMENT_INTERPRETER,
|
||||||
|
ELF_SEGMENT_NOTE,
|
||||||
|
ELF_SEGMENT_PROGRAM_HEADER_TABLE,
|
||||||
|
ELF_SEGMENT_TLS,
|
||||||
|
|
||||||
|
ELF_SEGMENT_ENUM_END
|
||||||
|
} elf_segment_type_E;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t type;
|
||||||
|
uint32_t flags;
|
||||||
|
uint64_t offset;
|
||||||
|
uint64_t address_virtual;
|
||||||
|
uint64_t address_physical;
|
||||||
|
uint64_t length_file;
|
||||||
|
uint64_t length_memory;
|
||||||
|
uint64_t align;
|
||||||
|
} elf_segment_T;
|
||||||
|
|
||||||
|
extern string_t g_elf_segment_type_strings[ELF_SEGMENT_ENUM_END+1];
|
||||||
|
|
||||||
|
#endif //NOX_SEGMENT_H
|
|
@ -23,8 +23,10 @@
|
||||||
|
|
||||||
#include "drivers/elf/elf.h"
|
#include "drivers/elf/elf.h"
|
||||||
#include "drivers/elf/symbol.h"
|
#include "drivers/elf/symbol.h"
|
||||||
|
#include "drivers/elf/segment.h"
|
||||||
#include "utils/memory.h"
|
#include "utils/memory.h"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
|
#include "utils/math.h"
|
||||||
|
|
||||||
// TEMPORARY BLOCK BEGIN
|
// TEMPORARY BLOCK BEGIN
|
||||||
|
|
||||||
|
@ -123,7 +125,7 @@ elf_executable_T* elf_executable_create(uint8_t* buffer) {
|
||||||
|
|
||||||
for (int i = 0; i < executable_temp.executable->header.num_section_header_entries; i++) {
|
for (int i = 0; i < executable_temp.executable->header.num_section_header_entries; i++) {
|
||||||
string_t name = (string_t)&(&buffer[executable_temp.section_header_string_table->offset])[sections[i].name_offset];
|
string_t name = (string_t)&(&buffer[executable_temp.section_header_string_table->offset])[sections[i].name_offset];
|
||||||
log(LOG_INFO, " [%s] '%s'", g_elf_section_type_strings[sections[i].type], name);
|
log(LOG_INFO, " [%s] '%s'", g_elf_section_type_strings[MIN(sections[i].type, ELF_SECTION_ENUM_END)], name);
|
||||||
|
|
||||||
switch (sections[i].type) {
|
switch (sections[i].type) {
|
||||||
case ELF_SECTION_SYMBOL_TABLE: {
|
case ELF_SECTION_SYMBOL_TABLE: {
|
||||||
|
@ -141,6 +143,41 @@ elf_executable_T* elf_executable_create(uint8_t* buffer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log(LOG_INFO, "Program Headers:");
|
||||||
|
executable_temp.executable->num_mappings = 0;
|
||||||
|
|
||||||
|
elf_segment_T* segments = (elf_segment_T*)&buffer[executable_temp.executable->header.offset_program_header];
|
||||||
|
for (int i = 0; i < executable_temp.executable->header.num_program_header_entries; i++) {
|
||||||
|
log(LOG_INFO, " %s", g_elf_segment_type_strings[MIN(segments[i].type, ELF_SEGMENT_ENUM_END)]);
|
||||||
|
|
||||||
|
switch (segments[i].type) {
|
||||||
|
case ELF_SEGMENT_LOAD: {
|
||||||
|
executable_temp.executable->num_mappings++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
executable_temp.executable->mappings = memory_allocate(executable_temp.executable->num_mappings * sizeof(elf_mapping_T));
|
||||||
|
|
||||||
|
uint64_t mappings_index = 0;
|
||||||
|
segments = (elf_segment_T*)&buffer[executable_temp.executable->header.offset_program_header];
|
||||||
|
for (int i = 0; i < executable_temp.executable->header.num_program_header_entries; i++) {
|
||||||
|
switch (segments[i].type) {
|
||||||
|
case ELF_SEGMENT_LOAD: {
|
||||||
|
executable_temp.executable->mappings[mappings_index] = (elf_mapping_T){
|
||||||
|
.offset_file = segments[i].offset,
|
||||||
|
.offset_virtual = segments[i].address_virtual,
|
||||||
|
.length_file = segments[i].length_file,
|
||||||
|
.length_virtual = segments[i].length_memory,
|
||||||
|
.alignment = segments[i].align
|
||||||
|
};
|
||||||
|
mappings_index++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
elf_executable_extract_symbols(&executable_temp);
|
elf_executable_extract_symbols(&executable_temp);
|
||||||
|
|
||||||
return executable_temp.executable;
|
return executable_temp.executable;
|
||||||
|
@ -149,5 +186,6 @@ elf_executable_T* elf_executable_create(uint8_t* buffer) {
|
||||||
void elf_executable_destruct(elf_executable_T* executable) {
|
void elf_executable_destruct(elf_executable_T* executable) {
|
||||||
memory_free(executable->string_table);
|
memory_free(executable->string_table);
|
||||||
memory_free(executable->symbols);
|
memory_free(executable->symbols);
|
||||||
|
memory_free(executable->mappings);
|
||||||
memory_free(executable);
|
memory_free(executable);
|
||||||
}
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 Antifallobst <antifallobst@systemausfall.org>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the “Software”), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "drivers/elf/mapping.h"
|
||||||
|
#include "mm/page_frame.h"
|
||||||
|
#include "utils/math.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
#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;
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (uint64_t i = 0; i < num_pages; i++) {
|
||||||
|
void* physical_address = pframe_request();
|
||||||
|
page_map_map_memory(page_map, virtual_address + (PFRAME_SIZE * i), physical_address, PM_FLAG_READ_WRITE);
|
||||||
|
page_map_map_memory(g_kernel_page_map, virtual_address + (PFRAME_SIZE * i), physical_address, PM_FLAG_READ_WRITE);
|
||||||
|
log(LOG_INFO, " mapped 0x%x", virtual_address + (PFRAME_SIZE * i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapping->length_virtual > mapping->length_file) {
|
||||||
|
memory_set(virtual_address + mapping->length_file, 0, mapping->length_virtual - mapping->length_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
log(LOG_INFO, "Copying data 0x%x --[%d]-> 0x%x", &buffer[mapping->offset_file], mapping->length_file, virtual_address);
|
||||||
|
|
||||||
|
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));
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
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++) {
|
||||||
|
elf_mapping_apply(&mappings[i], buffer, base, page_map);
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "drivers/elf/section.h"
|
#include "drivers/elf/section.h"
|
||||||
|
|
||||||
string_t g_elf_section_type_strings[9] = {
|
string_t g_elf_section_type_strings[ELF_SECTION_ENUM_END+1] = {
|
||||||
"Null",
|
"Null",
|
||||||
"Program Data",
|
"Program Data",
|
||||||
"Symbol Table",
|
"Symbol Table",
|
||||||
|
@ -32,5 +32,7 @@ string_t g_elf_section_type_strings[9] = {
|
||||||
"Hash",
|
"Hash",
|
||||||
"Dynamic Linker Info",
|
"Dynamic Linker Info",
|
||||||
"Note",
|
"Note",
|
||||||
"No Bits"
|
"No Bits",
|
||||||
|
|
||||||
|
"Unknown"
|
||||||
};
|
};
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 Antifallobst <antifallobst@systemausfall.org>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the “Software”), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "drivers/elf/segment.h"
|
||||||
|
|
||||||
|
string_t g_elf_segment_type_strings[ELF_SEGMENT_ENUM_END+1] = {
|
||||||
|
"Null",
|
||||||
|
"Loadable",
|
||||||
|
"Dynamic Linker Info",
|
||||||
|
"Interpreter Info",
|
||||||
|
"Note",
|
||||||
|
"Program Header Table",
|
||||||
|
"Thread Local Storage",
|
||||||
|
|
||||||
|
"Unknown"
|
||||||
|
};
|
|
@ -78,10 +78,6 @@ void kernel_init(boot_info_T* boot_info) {
|
||||||
limine_terminal_print(boot_info, " ok\n");
|
limine_terminal_print(boot_info, " ok\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void test() {
|
|
||||||
int test = 1 / 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void kmain(boot_info_T boot_info) {
|
void kmain(boot_info_T boot_info) {
|
||||||
|
|
||||||
limine_terminal_print(&boot_info, "Booting NoxOS...\n");
|
limine_terminal_print(&boot_info, "Booting NoxOS...\n");
|
||||||
|
@ -94,7 +90,16 @@ void kmain(boot_info_T boot_info) {
|
||||||
|
|
||||||
elf_init_kernel_exec(&boot_info);
|
elf_init_kernel_exec(&boot_info);
|
||||||
|
|
||||||
test();
|
vfs_node_T* node = vfs_resolve_path(&g_root_fs, "/initrd/test.elf");
|
||||||
|
|
||||||
|
elf_executable_T* exec = elf_executable_create(node->cache->buffer);
|
||||||
|
|
||||||
|
page_map_T* page_map = pframe_request();
|
||||||
|
elf_mappings_apply(exec->mappings, exec->num_mappings, node->cache->buffer, 0xFFFFFFFFFF000000, page_map);
|
||||||
|
|
||||||
|
int (*entry)() = (0xFFFFFFFFFF000000 + symbol_resolve_from_name(exec->symbols, exec->num_symbols, "_start")->address);
|
||||||
|
|
||||||
|
log(LOG_DEBUG, "ELF returned: %d", entry());
|
||||||
|
|
||||||
CORE_HALT_FOREVER
|
CORE_HALT_FOREVER
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
int _start() {
|
||||||
|
return 42;
|
||||||
|
}
|
Binary file not shown.
Loading…
Reference in New Issue