feature (syscalls): implemented syscalls (nx_mmap, nx_munmap)

This commit is contained in:
antifallobst 2023-04-20 18:53:01 +02:00
parent 1b7be49c34
commit 2544dc2346
4 changed files with 93 additions and 7 deletions

View File

@ -13,8 +13,9 @@
#define MEM_REGION_PROCESS 0x0000000000000000
#define MEM_REGION_PROCESS_EXEC 0x0000010000000000
#define MEM_REGION_PROCESS_THREAD_BASE 0x0000010100000000
#define MEM_REGION_PROCESS_USABLE 0x0000080000000000
#define MEM_REGION_KERNEL 0xFFFF800000000000
#define MEM_REGION_KERNEL 0x0000800000000000
#define MEM_REGION_KERNEL_STACK_DUMMY 0xFFFFF00000000000 // size 0x4000
#define MEM_REGION_KERNEL_HEAP 0xFFFFF80000000000
#define MEM_REGION_KERNEL_THREAD_BASE 0xFFFFFF0000000000

View File

@ -26,8 +26,8 @@ typedef enum {
SYSCALL_FILES_FOLLOW = 0x0107, // Warning: nx_follow will probably be kicked out of the ABI
SYSCALL_FILES_INFO = 0x0108,
SYSCALL_MEMORY_ALLOC = 0x0201,
SYSCALL_MEMORY_FREE = 0x0202,
SYSCALL_MEMORY_MAP = 0x0201,
SYSCALL_MEMORY_UNMAP = 0x0202,
SYSCALL_MEMORY_LABEL = 0x0203,
SYSCALL_MEMORY_RANGE = 0x0204,
SYSCALL_MEMORY_ACCESS = 0x0205,
@ -51,6 +51,11 @@ typedef enum {
SYSCALL_KERNEL_PANIC = 0xFF01
} syscall_E;
typedef enum {
SYSCALL_NX_MMAP_FLAG_WRITE,
SYSCALL_NX_MMAP_FLAG_NO_EXEC
} syscall_nx_mmap_flags_E;
extern status_E syscall_perform(syscall_E id, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4);
cpu_state_T* syscall_handle(cpu_state_T* state);

View File

@ -57,10 +57,23 @@ void kmain(boot_info_T boot_info) {
log(LOG_INFO, "!=====[ Kernel Initialized ]=====!\n");
char buffer[64];
uint32_t needed_mem = 0;
syscall_perform(SYSCALL_FILES_LIST, (uint64_t)"/initrd/", 0, buffer, &needed_mem);
memory_hexdump(buffer, 64);
log(LOG_DEBUG, "0x0000080000000000 --[check]--> %?", page_map_check_memory(g_kernel_page_map, 0x0000080000000000));
log(LOG_DEBUG, "0x0000080000001000 --[check]--> %?", page_map_check_memory(g_kernel_page_map, 0x0000080000001000));
log(LOG_DEBUG, "0x0000080000002000 --[check]--> %?", page_map_check_memory(g_kernel_page_map, 0x0000080000002000));
log(LOG_DEBUG, "0x0000080000003000 --[check]--> %?", page_map_check_memory(g_kernel_page_map, 0x0000080000003000));
syscall_perform(SYSCALL_MEMORY_MAP, 0x0000080000000000, 4, 0, 0);
log(LOG_DEBUG, "performed 'nx_mmap'");
log(LOG_DEBUG, "0x0000080000000000 --[check]--> %?", page_map_check_memory(g_kernel_page_map, 0x0000080000000000));
log(LOG_DEBUG, "0x0000080000001000 --[check]--> %?", page_map_check_memory(g_kernel_page_map, 0x0000080000001000));
log(LOG_DEBUG, "0x0000080000002000 --[check]--> %?", page_map_check_memory(g_kernel_page_map, 0x0000080000002000));
log(LOG_DEBUG, "0x0000080000003000 --[check]--> %?", page_map_check_memory(g_kernel_page_map, 0x0000080000003000));
syscall_perform(SYSCALL_MEMORY_UNMAP, 0x0000080000000000, 4, 0, 0);
log(LOG_DEBUG, "performed 'nx_munmap'");
log(LOG_DEBUG, "0x0000080000000000 --[check]--> %?", page_map_check_memory(g_kernel_page_map, 0x0000080000000000));
log(LOG_DEBUG, "0x0000080000001000 --[check]--> %?", page_map_check_memory(g_kernel_page_map, 0x0000080000001000));
log(LOG_DEBUG, "0x0000080000002000 --[check]--> %?", page_map_check_memory(g_kernel_page_map, 0x0000080000002000));
log(LOG_DEBUG, "0x0000080000003000 --[check]--> %?", page_map_check_memory(g_kernel_page_map, 0x0000080000003000));
// vfs_node_T* node = vfs_resolve_path(&g_root_fs, "/initrd/test.elf");
// void* buffer = memory_allocate(node->size);

View File

@ -6,6 +6,8 @@
#include "utils/memory.h"
#include "proc/scheduler.h"
#include "drivers/fs/vfs.h"
#include "mm/page_frame.h"
#include "mm/region.h"
void syscall_handle_nx_fopen(cpu_state_T* state) {
string_t path = (string_t)state->rdi; // arg1
@ -105,6 +107,61 @@ void syscall_handle_nx_flist(cpu_state_T* state) {
}
void syscall_handle_nx_mmap(cpu_state_T* state) {
uint8_t* addr = (uint8_t*)state->rdi; // arg1
uint64_t n = state->rsi; // arg2
uint64_t flags = (uint64_t)state->rdx; // arg3
if ((uint64_t)&addr[n * PFRAME_SIZE] > MEM_REGION_KERNEL ||
(uint64_t)addr < MEM_REGION_PROCESS_USABLE) {
state->rax = STATUS_PERMISSION_DENIED;
return;
}
uint64_t map_flags = 0;
if (flags & (1 << SYSCALL_NX_MMAP_FLAG_WRITE)) map_flags |= PM_FLAG_READ_WRITE;
if (flags & (1 << SYSCALL_NX_MMAP_FLAG_NO_EXEC)) map_flags |= PM_FLAG_NO_EXECUTE;
page_map_T* page_map = scheduler_get_current_process()->page_map;
for (int i = 0; i < n; i++) {
// check if the page is already mapped
if (page_map_check_memory(page_map, &addr[i * PFRAME_SIZE])) {
// unmap all the already mapped pages
for (int j = 0; j < i; j++) {
pframe_free(page_map_get_physical_address(page_map, &addr[j * PFRAME_SIZE]));
page_map_unmap_memory(page_map, &addr[j * PFRAME_SIZE]);
}
state->rax = STATUS_RESOURCE_NOT_AVAILABLE;
return;
}
page_map_map_memory(page_map, &addr[i * PFRAME_SIZE], pframe_request(), map_flags);
}
state->rax = STATUS_SUCCESS;
}
void syscall_handle_nx_munmap(cpu_state_T* state) {
void* addr = (void*)state->rdi; // arg1
uint64_t n = state->rsi; // arg2
if ((uint64_t)&addr[n * PFRAME_SIZE] > MEM_REGION_KERNEL ||
(uint64_t)addr < MEM_REGION_PROCESS_USABLE) {
state->rax = STATUS_PERMISSION_DENIED;
return;
}
page_map_T* page_map = scheduler_get_current_process()->page_map;
for (int i = 0; i < n; i++) {
pframe_free(page_map_get_physical_address(page_map, &addr[i * PFRAME_SIZE]));
page_map_unmap_memory(page_map, &addr[i * PFRAME_SIZE]);
}
state->rax = STATUS_SUCCESS;
}
cpu_state_T* syscall_handle(cpu_state_T* state) {
cpu_state_T* return_state = state;
syscall_group_E group_id = (state->rax & 0xFF00) >> 8;
@ -143,6 +200,16 @@ cpu_state_T* syscall_handle(cpu_state_T* state) {
}
case SYSCALLS_MEMORY: {
switch (state->rax) {
case SYSCALL_MEMORY_MAP: {
syscall_handle_nx_mmap(state);
break;
}
case SYSCALL_MEMORY_UNMAP: {
syscall_handle_nx_munmap(state);
break;
}
}
break;
}