kernel: begin work on re-adding module loading
This commit is contained in:
parent
efe72fa8ab
commit
826006692a
10
Makefile
10
Makefile
@ -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/*.c) $(wildcard kernel/*/*.c) $(wildcard kernel/${ARCH}/*/*.c)
|
||||||
KERNEL_SOURCES += $(wildcard kernel/arch/${ARCH}/*.S)
|
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.
|
# Configs you can override.
|
||||||
SMP ?= 1
|
SMP ?= 1
|
||||||
@ -84,8 +84,8 @@ LC = $(BASE)/lib/libc.so $(GCC_SHARED) $(LIBSTDCXX)
|
|||||||
all: system
|
all: system
|
||||||
system: misaka-kernel $(MODULES) ramdisk.igz
|
system: misaka-kernel $(MODULES) ramdisk.igz
|
||||||
|
|
||||||
%.ko: %.c
|
$(BASE)/mod/%.ko: modules/%.c | dirs
|
||||||
${CC} -c ${KERNEL_CFLAGS} -o $@ $<
|
${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)
|
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
|
python3 util/createramdisk.py
|
||||||
@ -182,6 +182,8 @@ $(BASE)/cdrom:
|
|||||||
mkdir -p $@
|
mkdir -p $@
|
||||||
$(BASE)/var:
|
$(BASE)/var:
|
||||||
mkdir -p $@
|
mkdir -p $@
|
||||||
|
$(BASE)/mod:
|
||||||
|
mkdir -p $@
|
||||||
$(BASE)/lib/kuroko:
|
$(BASE)/lib/kuroko:
|
||||||
mkdir -p $@
|
mkdir -p $@
|
||||||
$(BASE)/usr/lib:
|
$(BASE)/usr/lib:
|
||||||
@ -192,7 +194,7 @@ cdrom:
|
|||||||
mkdir -p $@
|
mkdir -p $@
|
||||||
.make:
|
.make:
|
||||||
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)))
|
ifeq (,$(findstring clean,$(MAKECMDGOALS)))
|
||||||
-include ${APPS_Y}
|
-include ${APPS_Y}
|
||||||
|
@ -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);
|
return (Elf64_Shdr*)((uintptr_t)this + this->e_shoff + index * this->e_shentsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf_parseModuleFromMemory(void * atAddress) {
|
static const char * sectionHeaderTypeToStr(Elf64_Word type) {
|
||||||
struct Elf64_Header * elfHeader = atAddress;
|
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 ||
|
case 0xE: return "INIT_ARRAY";
|
||||||
elfHeader->e_ident[1] != ELFMAG1 ||
|
case 0xF: return "FINI_ARRAY";
|
||||||
elfHeader->e_ident[2] != ELFMAG2 ||
|
case 0x6ffffff6: return "GNU_HASH";
|
||||||
elfHeader->e_ident[3] != ELFMAG3) {
|
case 0x6ffffffe: return "VERNEED";
|
||||||
printf("(Not an elf)\n");
|
case 0x6fffffff: return "VERSYM";
|
||||||
return;
|
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");
|
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");
|
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*)§ionHeader);
|
||||||
|
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.
|
* First, we're going to check sections and update their addresses.
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
for (unsigned int i = 0; i < elfHeader->e_shnum; ++i) {
|
for (unsigned int i = 0; i < elfHeader->e_shnum; ++i) {
|
||||||
Elf64_Shdr * shdr = elf_getSection(elfHeader, i);
|
Elf64_Shdr * shdr = elf_getSection(elfHeader, i);
|
||||||
if (shdr->sh_type == SHT_NOBITS) {
|
if (shdr->sh_type == SHT_NOBITS) {
|
||||||
@ -63,6 +140,9 @@ void elf_parseModuleFromMemory(void * atAddress) {
|
|||||||
shdr->sh_addr = (uintptr_t)atAddress + shdr->sh_offset;
|
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) {
|
int elf_exec(const char * path, fs_node_t * file, int argc, const char *const argv[], const char *const env[], int interp) {
|
||||||
|
@ -51,6 +51,8 @@ static long sys_sbrk(ssize_t size) {
|
|||||||
return (long)out;
|
return (long)out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int elf_module(const char * path);
|
||||||
|
|
||||||
static long sys_sysfunc(long fn, char ** args) {
|
static long sys_sysfunc(long fn, char ** args) {
|
||||||
/* FIXME: Most of these should be top-level, many are hacks/broken in Misaka */
|
/* FIXME: Most of these should be top-level, many are hacks/broken in Misaka */
|
||||||
switch (fn) {
|
switch (fn) {
|
||||||
@ -76,8 +78,7 @@ static long sys_sysfunc(long fn, char ** args) {
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
case TOARU_SYS_FUNC_INSMOD:
|
case TOARU_SYS_FUNC_INSMOD:
|
||||||
/* FIXME: Load module */
|
/* FIXME: Load module */
|
||||||
printf("insmod: not implemented\n");
|
return elf_module(args[0]);
|
||||||
return -EINVAL;
|
|
||||||
/* Begin unpriv */
|
/* Begin unpriv */
|
||||||
case TOARU_SYS_FUNC_SETHEAP: {
|
case TOARU_SYS_FUNC_SETHEAP: {
|
||||||
volatile process_t * volatile proc = this_core->current_process;
|
volatile process_t * volatile proc = this_core->current_process;
|
||||||
|
Loading…
Reference in New Issue
Block a user