From 257999f0fef01f9e3c9d6a8ccfb4a568ffa39916 Mon Sep 17 00:00:00 2001 From: antifallobst Date: Wed, 8 Mar 2023 18:25:20 +0100 Subject: [PATCH] feature (syscalls): implemented syscall arguments and return value --- kernel/inc/platform/syscall.h | 47 +++++++++++++++++++++++++---- kernel/inc/utils/status.h | 38 +++++++++++++++++++++++ kernel/src/kmain.c | 30 +++++++++--------- kernel/src/platform/syscall.c | 39 +++++++++++++++++++----- kernel/src/platform/x86/syscall.asm | 11 +++++++ kernel/src/proc/scheduler.c | 2 +- kernel/src/utils/status.c | 31 +++++++++++++++++++ 7 files changed, 167 insertions(+), 31 deletions(-) create mode 100644 kernel/inc/utils/status.h create mode 100644 kernel/src/utils/status.c diff --git a/kernel/inc/platform/syscall.h b/kernel/inc/platform/syscall.h index 0fddc61..33b1713 100644 --- a/kernel/inc/platform/syscall.h +++ b/kernel/inc/platform/syscall.h @@ -25,19 +25,54 @@ #define NOX_SYSCALL_H #include "platform/cpu.h" +#include "utils/status.h" typedef enum { - SYSCALLS_MISC = 0x00, - SYSCALLS_FILE = 0x01, - SYSCALLS_PROC = 0x02, - SYSCALLS_KERNEL = 0xFF, + SYSCALLS_FILES = 0x00, + SYSCALLS_MEMORY = 0x01, + SYSCALLS_PROC = 0x02, + SYSCALLS_RUNTIME_LINKER = 0x02, + SYSCALLS_COMPATABILITY = 0x02, + + SYSCALLS_KERNEL = 0xFF }syscall_group_E; typedef enum { - SYSCALL_KERNEL_SCHEDULER_START = 0xFF00 + SYSCALL_FILES_OPEN = 0x0101, + SYSCALL_FILES_CLOSE = 0x0102, + SYSCALL_FILES_READ = 0x0103, + SYSCALL_FILES_WRITE = 0x0104, + SYSCALL_FILES_DELETE = 0x0105, + SYSCALL_FILES_LIST = 0x0106, + 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_LABEL = 0x0203, + SYSCALL_MEMORY_RANGE = 0x0204, + SYSCALL_MEMORY_ACCESS = 0x0205, + + SYSCALL_PROCESS_CREATE = 0x0301, + SYSCALL_PROCESS_ENVFILE = 0x0302, + SYSCALL_PROCESS_START = 0x0303, + SYSCALL_PROCESS_SIGNAL = 0x0304, + + SYSCALL_RUNTIME_LINKER_OPEN = 0x0401, + SYSCALL_RUNTIME_LINKER_CLOSE = 0x0402, + SYSCALL_RUNTIME_LINKER_LOAD_SYMBOL = 0x0403, + SYSCALL_RUNTIME_LINKER_STATUS = 0x0404, + SYSCALL_RUNTIME_LINKER_STANDARD_MOD = 0x0405, + + SYSCALL_COMPATABILITY_ABI_TYPE = 0x0501, + SYSCALL_COMPATABILITY_ABI_VERSION = 0x0502, + SYSCALL_COMPATABILITY_ACTION = 0x0503, + + SYSCALL_KERNEL_SCHEDULER_START = 0xFF00, + SYSCALL_KERNEL_PANIC = 0xFF01 } syscall_E; -extern void syscall_perform(syscall_E id); +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); diff --git a/kernel/inc/utils/status.h b/kernel/inc/utils/status.h new file mode 100644 index 0000000..c36bfc1 --- /dev/null +++ b/kernel/inc/utils/status.h @@ -0,0 +1,38 @@ +/* + * Copyright 2023 Antifallobst + * + * 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_STATUS_H +#define NOX_STATUS_H + +#include "string.h" + +typedef enum { + STATUS_SUCCESS, + + STATUS_PERMISSION_DENIED, + STATUS_RESOURCE_NOT_AVAILABLE +} status_E; + +extern string_t g_status_code_strings[3]; + +#endif //NOX_STATUS_H diff --git a/kernel/src/kmain.c b/kernel/src/kmain.c index aaf5c84..f947e5e 100644 --- a/kernel/src/kmain.c +++ b/kernel/src/kmain.c @@ -35,7 +35,7 @@ #include "drivers/fs/vfs.h" #include "proc/scheduler.h" -#include "utils/io.h" +#include "platform/syscall.h" void limine_terminal_print(boot_info_T* boot_info, string_t string) { boot_info->terminal->write(boot_info->terminal->terminals[0], string, string_length(string)); @@ -72,23 +72,21 @@ void kmain(boot_info_T boot_info) { log(LOG_INFO, "!=====[ Kernel Initialized ]=====!\n"); - page_map_dump_info(g_kernel_page_map); + status_E status = syscall_perform(SYSCALL_FILES_OPEN, (uint64_t)"/initrd/test.txt", 0, 0, 0); - vfs_node_T* node = vfs_resolve_path(&g_root_fs, "/initrd/test.elf"); - void* buffer = memory_allocate(node->size); - vfs_file_read(node, 0, node->size, buffer); + log(LOG_DEBUG, "syscall returned status: %s", g_status_code_strings[status]); - elf_executable_T* exec = elf_executable_create(buffer); - - pid_t process = process_spawn(PROCESS_KERNEL, "test 1", exec, buffer); - void* func = (void*)symbol_resolve_from_name(scheduler_get_process(process)->executable->symbols, - scheduler_get_process(process)->executable->num_symbols, - "_start")->address + MEM_REGION_PROCESS_EXEC; - thread_start(thread_spawn(process, func)); - - while (1){ - io_out_byte(0x3F8, 'B'); - } +// vfs_node_T* node = vfs_resolve_path(&g_root_fs, "/initrd/test.elf"); +// void* buffer = memory_allocate(node->size); +// vfs_file_read(node, 0, node->size, buffer); +// +// elf_executable_T* exec = elf_executable_create(buffer); +// +// pid_t process = process_spawn(PROCESS_KERNEL, "test 1", exec, buffer); +// void* func = (void*)symbol_resolve_from_name(scheduler_get_process(process)->executable->symbols, +// scheduler_get_process(process)->executable->num_symbols, +// "_start")->address + MEM_REGION_PROCESS_EXEC; +// thread_start(thread_spawn(process, func)); // scheduler_dump_info(scheduler_get_process(PROCESS_KERNEL), 0); diff --git a/kernel/src/platform/syscall.c b/kernel/src/platform/syscall.c index cbf4036..136d715 100644 --- a/kernel/src/platform/syscall.c +++ b/kernel/src/platform/syscall.c @@ -24,30 +24,53 @@ #include "platform/syscall.h" #include "utils/logger.h" #include "proc/scheduler.h" +#include "drivers/fs/vfs.h" cpu_state_T* syscall_handle(cpu_state_T* state) { cpu_state_T* return_state = state; syscall_group_E group_id = (state->rax & 0xFF00) >> 8; -// if (group_id == SYSCALLS_KERNEL && -// scheduler_is_initialized() && -// scheduler_get_current_process() != PROC_KERNEL) -// { -// log(LOG_WARNING, "non kernel process[%d:%d] tried to perform a kernel syscall (permission denied)", scheduler_get_current_process(), scheduler_get_current_thread()); -// return return_state; -// } + if (group_id == SYSCALLS_KERNEL && + scheduler_is_initialized() && + scheduler_get_current_process()->id != PROCESS_KERNEL) + { + log(LOG_WARNING, "non kernel process[%d:%d] tried to perform a kernel syscall (permission denied)", scheduler_get_current_process(), scheduler_get_current_thread()); + return return_state; + } + + // read arguments + uint64_t arg1 = state->rdi; + uint64_t arg2 = state->rsi; + uint64_t arg3 = state->rdx; + uint64_t arg4 = state->rcx; + uint64_t ret = STATUS_SUCCESS; switch (state->rax) { + case SYSCALL_FILES_OPEN: { + vfs_node_T* node = vfs_resolve_path(&g_root_fs, (string_t)arg1); + if (node == NULL) { + ret = STATUS_RESOURCE_NOT_AVAILABLE; + break; + } + + log(LOG_DEBUG, "resolved file '%s' -> 0x%x", arg1, node); + + break; + } + case SYSCALL_KERNEL_SCHEDULER_START: { return_state = scheduler_start(state); break; } default: { - log(LOG_WARNING, "Unhandled syscall: 0x%xw RAX[0x%x]", state->rax, state->rax); + log(LOG_WARNING, "unhandled syscall: 0x%xw", state->rax); break; } } + // apply return value + state->rax = ret; + return return_state; } \ No newline at end of file diff --git a/kernel/src/platform/x86/syscall.asm b/kernel/src/platform/x86/syscall.asm index bb36e04..db24054 100644 --- a/kernel/src/platform/x86/syscall.asm +++ b/kernel/src/platform/x86/syscall.asm @@ -20,7 +20,18 @@ ; OTHER DEALINGS IN THE SOFTWARE. syscall_perform: + ; set the interrupt ID mov rax, rdi + + ; set the arguments + mov rdi, rsi + mov rsi, rdx + mov rdx, rcx + mov rcx, r8 + int 0x80 + + ; the return value is already set in RAX + ret GLOBAL syscall_perform \ No newline at end of file diff --git a/kernel/src/proc/scheduler.c b/kernel/src/proc/scheduler.c index f9dd957..d89af4f 100644 --- a/kernel/src/proc/scheduler.c +++ b/kernel/src/proc/scheduler.c @@ -78,7 +78,7 @@ void scheduler_init(boot_info_T* boot_info) { process_kernel_spawn(elf_executable_create(boot_info->kernel_file->address)); - syscall_perform(SYSCALL_KERNEL_SCHEDULER_START); + syscall_perform(SYSCALL_KERNEL_SCHEDULER_START, 0, 0, 0, 0); } cpu_state_T* scheduler_start(cpu_state_T* state) { diff --git a/kernel/src/utils/status.c b/kernel/src/utils/status.c new file mode 100644 index 0000000..6a8ca8d --- /dev/null +++ b/kernel/src/utils/status.c @@ -0,0 +1,31 @@ +/* + * Copyright 2023 Antifallobst + * + * 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 "utils/status.h" + +string_t g_status_code_strings[3] = { + "Success", + + "Permission Denied", + "Resource Not Available" +}; \ No newline at end of file