kernel: begin work on re-adding module loading

This commit is contained in:
K. Lange 2021-06-03 21:01:57 +09:00
parent efe72fa8ab
commit 826006692a
3 changed files with 101 additions and 18 deletions

View File

@ -28,7 +28,7 @@ KERNEL_ASMOBJS = $(filter-out kernel/symbols.o,$(patsubst %.S,%.o,$(wildcard ke
KERNEL_SOURCES = $(wildcard kernel/*.c) $(wildcard kernel/*/*.c) $(wildcard kernel/${ARCH}/*/*.c)
KERNEL_SOURCES += $(wildcard kernel/arch/${ARCH}/*.S)
MODULES = $(patsubst %.c,%.ko,$(wildcard modules/*.c))
MODULES = $(patsubst modules/%.c,$(BASE)/mod/%.ko,$(wildcard modules/*.c))
# Configs you can override.
SMP ?= 1
@ -84,8 +84,8 @@ LC = $(BASE)/lib/libc.so $(GCC_SHARED) $(LIBSTDCXX)
all: system
system: misaka-kernel $(MODULES) ramdisk.igz
%.ko: %.c
${CC} -c ${KERNEL_CFLAGS} -o $@ $<
$(BASE)/mod/%.ko: modules/%.c | dirs
${CC} -c ${KERNEL_CFLAGS} -mcmodel=large -o $@ $<
ramdisk.igz: $(wildcard $(BASE)/* $(BASE)/*/* $(BASE)/*/*/*) $(APPS_X) $(LIBS_X) $(KRK_MODS_X) $(BASE)/bin/kuroko $(BASE)/lib/ld.so $(APPS_KRK_X) $(KRK_MODS)
python3 util/createramdisk.py
@ -182,6 +182,8 @@ $(BASE)/cdrom:
mkdir -p $@
$(BASE)/var:
mkdir -p $@
$(BASE)/mod:
mkdir -p $@
$(BASE)/lib/kuroko:
mkdir -p $@
$(BASE)/usr/lib:
@ -192,7 +194,7 @@ cdrom:
mkdir -p $@
.make:
mkdir -p .make
dirs: $(BASE)/dev $(BASE)/tmp $(BASE)/proc $(BASE)/bin $(BASE)/lib $(BASE)/cdrom $(BASE)/usr/lib $(BASE)/lib/kuroko cdrom $(BASE)/var fatbase/efi/boot .make
dirs: $(BASE)/dev $(BASE)/tmp $(BASE)/proc $(BASE)/bin $(BASE)/lib $(BASE)/cdrom $(BASE)/usr/lib $(BASE)/lib/kuroko cdrom $(BASE)/var fatbase/efi/boot .make $(BASE)/mod
ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include ${APPS_Y}

View File

@ -22,23 +22,99 @@ static Elf64_Shdr * elf_getSection(Elf64_Header * this, Elf64_Word index) {
return (Elf64_Shdr*)((uintptr_t)this + this->e_shoff + index * this->e_shentsize);
}
void elf_parseModuleFromMemory(void * atAddress) {
struct Elf64_Header * elfHeader = atAddress;
static const char * sectionHeaderTypeToStr(Elf64_Word type) {
static char buf[64];
switch (type) {
case SHT_NULL: return "NULL";
case SHT_PROGBITS: return "PROGBITS";
case SHT_SYMTAB: return "SYMTAB";
case SHT_STRTAB: return "STRTAB";
case SHT_RELA: return "RELA";
case SHT_HASH: return "HASH";
case SHT_DYNAMIC: return "DYNAMIC";
case SHT_NOTE: return "NOTE";
case SHT_NOBITS: return "NOBITS";
case SHT_REL: return "REL";
case SHT_SHLIB: return "SHLIB";
case SHT_DYNSYM: return "DYNSYM";
if (elfHeader->e_ident[0] != ELFMAG0 ||
elfHeader->e_ident[1] != ELFMAG1 ||
elfHeader->e_ident[2] != ELFMAG2 ||
elfHeader->e_ident[3] != ELFMAG3) {
printf("(Not an elf)\n");
return;
case 0xE: return "INIT_ARRAY";
case 0xF: return "FINI_ARRAY";
case 0x6ffffff6: return "GNU_HASH";
case 0x6ffffffe: return "VERNEED";
case 0x6fffffff: return "VERSYM";
default:
snprintf(buf, 63, "(%x)", type);
return buf;
}
if (elfHeader->e_ident[EI_CLASS] != ELFCLASS64) {
}
int elf_module(const char * path) {
Elf64_Header header;
fs_node_t * file = kopen(path,0);
if (!file) {
return -ENOENT;
}
read_fs(file, 0, sizeof(Elf64_Header), (uint8_t*)&header);
if (header.e_ident[0] != ELFMAG0 ||
header.e_ident[1] != ELFMAG1 ||
header.e_ident[2] != ELFMAG2 ||
header.e_ident[3] != ELFMAG3) {
printf("Invalid file: Bad header.\n");
close_fs(file);
return -EINVAL;
}
if (header.e_ident[EI_CLASS] != ELFCLASS64) {
printf("(Wrong Elf class)\n");
return;
return -EINVAL;
}
if (elfHeader->e_type != ET_REL) {
if (header.e_type != ET_REL) {
printf("(Not a relocatable object)\n");
return;
return -EINVAL;
}
printf("Loading module...\n");
/**
* Load the section string table, we'll want this for debugging, mostly.
*/
Elf64_Shdr shstr_hdr;
read_fs(file, header.e_shoff + header.e_shentsize * header.e_shstrndx, sizeof(Elf64_Shdr), (uint8_t*)&shstr_hdr);
char * stringTable = malloc(shstr_hdr.sh_size);
read_fs(file, shstr_hdr.sh_offset, shstr_hdr.sh_size, (uint8_t*)stringTable);
/**
* Modules are relocatable objects, so we have to link them by sections,
* not by PHDRs - they don't have those. We'll generally see a lot more
* relocations but usually of a smaller set.
*/
printf("\nSection Headers:\n");
printf(" [Nr] Name Type Address Offset\n");
printf(" Size EntSize Flags Link Info Align\n");
for (unsigned int i = 0; i < header.e_shnum; ++i) {
Elf64_Shdr sectionHeader;
read_fs(file, header.e_shoff + header.e_shentsize * i, sizeof(Elf64_Shdr), (uint8_t*)&sectionHeader);
if (sectionHeader.sh_type == SHT_PROGBITS) {
printf("progbits: %s\n", stringTable + sectionHeader.sh_name);
} else if (sectionHeader.sh_type == SHT_NOBITS) {
printf("nobits: %s\n", stringTable + sectionHeader.sh_name);
}
#if 0
printf(" [%2d] %-17.17s %-16.16s %016lx %08lx\n",
i, stringTable + sectionHeader.sh_name, sectionHeaderTypeToStr(sectionHeader.sh_type),
sectionHeader.sh_addr, sectionHeader.sh_offset);
printf(" %016lx %016lx %4ld %6d %5d %5ld\n",
sectionHeader.sh_size, sectionHeader.sh_entsize, sectionHeader.sh_flags,
sectionHeader.sh_link, sectionHeader.sh_info, sectionHeader.sh_addralign);
#endif
}
/**
@ -51,6 +127,7 @@ void elf_parseModuleFromMemory(void * atAddress) {
/**
* First, we're going to check sections and update their addresses.
*/
#if 0
for (unsigned int i = 0; i < elfHeader->e_shnum; ++i) {
Elf64_Shdr * shdr = elf_getSection(elfHeader, i);
if (shdr->sh_type == SHT_NOBITS) {
@ -63,6 +140,9 @@ void elf_parseModuleFromMemory(void * atAddress) {
shdr->sh_addr = (uintptr_t)atAddress + shdr->sh_offset;
}
}
#endif
return 0;
}
int elf_exec(const char * path, fs_node_t * file, int argc, const char *const argv[], const char *const env[], int interp) {

View File

@ -51,6 +51,8 @@ static long sys_sbrk(ssize_t size) {
return (long)out;
}
extern int elf_module(const char * path);
static long sys_sysfunc(long fn, char ** args) {
/* FIXME: Most of these should be top-level, many are hacks/broken in Misaka */
switch (fn) {
@ -76,8 +78,7 @@ static long sys_sysfunc(long fn, char ** args) {
return -EINVAL;
case TOARU_SYS_FUNC_INSMOD:
/* FIXME: Load module */
printf("insmod: not implemented\n");
return -EINVAL;
return elf_module(args[0]);
/* Begin unpriv */
case TOARU_SYS_FUNC_SETHEAP: {
volatile process_t * volatile proc = this_core->current_process;