Compare commits

...

1 Commits

Author SHA1 Message Date
K. Lange
d53a5420a1 aarch64: (wip) support kernel modules 2022-02-14 09:38:21 +09:00
3 changed files with 31 additions and 8 deletions

View File

@ -699,9 +699,23 @@ void * mmu_map_mmio_region(uintptr_t physical_address, size_t size) {
return out;
}
static uintptr_t module_base_address = MODULE_BASE_START;
void * mmu_map_module(size_t size) {
printf("attempt to map module\n");
return NULL;
if (size & PAGE_LOW_MASK) {
size += (PAGE_LOW_MASK + 1) - (size & PAGE_LOW_MASK);
}
spin_lock(module_space_lock);
void * out = (void*)module_base_address;
for (size_t i = 0; i < size; i += PAGE_SIZE) {
union PML * p = mmu_get_page(module_base_address + i, MMU_GET_MAKE);
mmu_frame_allocate(p, MMU_FLAG_KERNEL | MMU_FLAG_WRITABLE);
}
module_base_address += size;
spin_unlock(module_space_lock);
return out;
}
void mmu_unmap_module(uintptr_t start_address, size_t size) {
@ -837,5 +851,5 @@ void mmu_init(uintptr_t memaddr, size_t memsize, uintptr_t firstFreePage, uintpt
heapStart = (char*)KERNEL_HEAP_START + bytesOfFrames;
lowest_available = (firstFreePage + bytesOfFrames) - memaddr;
module_base_address = endOfRamDisk + MODULE_BASE_START;
}

View File

@ -99,6 +99,11 @@ int elf_module(char ** args) {
memset((void*)sectionHeader->sh_addr, 0, sectionHeader->sh_size);
} else {
sectionHeader->sh_addr = (uintptr_t)(module_load_address + sectionHeader->sh_offset);
if (sectionHeader->sh_addralign &&
(sectionHeader->sh_addr & (sectionHeader->sh_addralign -1))) {
dprintf("mod: probably not aligned correctly: %#zx %ld\n",
sectionHeader->sh_addr, sectionHeader->sh_addralign);
}
}
}
@ -125,8 +130,12 @@ int elf_module(char ** args) {
if (symTable[sym].st_shndx > 0 && symTable[sym].st_shndx < SHN_LOPROC) {
Elf64_Shdr * sh_hdr = (Elf64_Shdr*)(module_load_address + header.e_shoff + header.e_shentsize * symTable[sym].st_shndx);
symTable[sym].st_value = symTable[sym].st_value + sh_hdr->sh_addr;
dprintf("mod: bind local symbol '%s' to %#zx\n",
symTable[sym].st_name ? (symNames + symTable[sym].st_name) : "(unnamed)", symTable[sym].st_value);
} else if (symTable[sym].st_shndx == SHN_UNDEF) {
symTable[sym].st_value = (uintptr_t)ksym_lookup(symNames + symTable[sym].st_name);
dprintf("mod: bind kernel symbol '%s' to %#zx\n",
symTable[sym].st_name ? (symNames + symTable[sym].st_name) : "(unnamed)", symTable[sym].st_value);
}
if (symTable[sym].st_name && !strcmp(symNames + symTable[sym].st_name, "metadata")) {
@ -156,6 +165,7 @@ int elf_module(char ** args) {
for (unsigned int rela = 0; rela < sectionHeader->sh_size / sizeof(Elf64_Rela); ++rela) {
uintptr_t target = table[rela].r_offset + targetSection->sh_addr;
switch (ELF64_R_TYPE(table[rela].r_info)) {
#if defined(__x86_64__)
case R_X86_64_64:
*(uint64_t*)target = symbolTable[ELF64_R_SYM(table[rela].r_info)].st_value + table[rela].r_addend;
break;
@ -165,13 +175,16 @@ int elf_module(char ** args) {
case R_X86_64_PC32:
*(uint32_t*)target = symbolTable[ELF64_R_SYM(table[rela].r_info)].st_value + table[rela].r_addend - target;
break;
#endif
default:
dprintf("mod: unsupported relocation %ld found\n", ELF64_R_TYPE(table[rela].r_info));
error = EINVAL;
goto _unmap_module;
}
}
}
if (error) goto _unmap_module;
if (hashmap_has(_modules_table, moduleData->name)) {
error = EEXIST;
goto _unmap_module;

View File

@ -107,10 +107,6 @@ long sys_sysfunc(long fn, char ** args) {
case TOARU_SYS_FUNC_INSMOD:
/* Linux has init_module as a system call? */
if (this_core->current_process->user != 0) return -EACCES;
#if defined(__aarch64__)
/* TODO: Most modules are not right for this and we are missing relocations */
return -EINVAL;
#endif
PTR_VALIDATE(args);
if (!args) return -EFAULT;
PTR_VALIDATE(args[0]);