diff --git a/.vscode/settings.json b/.vscode/settings.json index 9ec63be..8b373fc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,6 +8,8 @@ "types.h": "c", "pit.h": "c", "stdlib.h": "c", - "taskio.h": "c" + "taskio.h": "c", + "syscall.h": "c", + "thread": "c" } } \ No newline at end of file diff --git a/cstdlib/includes/klib/syscall.h b/cstdlib/includes/klib/syscall.h new file mode 100644 index 0000000..6824f6c --- /dev/null +++ b/cstdlib/includes/klib/syscall.h @@ -0,0 +1,91 @@ +/** +* Defintions for the kernel system call usage in the Kernel related applications +*/ + +#pragma once + + +#define SYSCALL_ARGBUFF void* +#define SYSCALL_NOARGS ((void*)0) + +#ifndef SYSCALL_MODERN_INSTRUCTION +#define SYSCALL_INTERRUPT 0x80 +#endif + +#define SYSCALL_RESPONSE_SZ ACCEPTED + +/** + * The possible responses from a kernel syscall + */ +typedef enum syscall_response { + /** + * The syscall request was denied and wasn't executed. + */ + DENIED, + + /** + * The syscall request was denied and wasn't executed. + * The issuing process also will be killed as a result. + */ + DENIED_STRICT, + + /** + * The given syscall is invalid / incomplete + */ + INVALID_SYSCALL, + + /** + * The syscall request was accepted but couldn't be executed properly. + */ + ACCEPT_ERR, + + /** + * The syscall request was accepted and was executed sucessfully. + */ + ACCEPTED, + + UNDEFINED +} syscall_response; + + +/** + * The available system calls. +*/ +typedef enum syscall { + + /** + * Prints a message + */ + PRINT, + + /** + * Asks for either read or write rights on a specific IO port, + * The issuer task has to be considered as a driver task for the request to be considered. + */ + IOPORT_REQ, + + /** + * Requests to apply the driver status to the issuer process. This request will always fail if said task isn't + * internally spun by the kernel. + */ + DRIVERTASK_REQ, + + /** + * Kills a specified task. This request will fail if the permissions of the issuer aren't high enough (if a program tries closing another program and isn't privilleged). + */ + TASK_KILL, + + /** + * Spawns / creates a process. The request will fail if the issuer tries spawning a task that is either internal or requires higher permissions than what the issuer has. + */ + TASK_SPAWN + +} syscall; + +/** + * Requests a syscall to the kernel. + * @param call the systemcall to request + * @param args the syscall arguments, should be SYSCALL_NOARGS if no arguments + * @return a response to your syscall.s +*/ +syscall_response ksyscall(syscall call, SYSCALL_ARGBUFF args); \ No newline at end of file diff --git a/cstdlib/src/klib/syscall.c b/cstdlib/src/klib/syscall.c new file mode 100644 index 0000000..d39015c --- /dev/null +++ b/cstdlib/src/klib/syscall.c @@ -0,0 +1,22 @@ +#include +#include + +syscall_response ksyscall(syscall call, SYSCALL_ARGBUFF args) { + __asm__("mov %%al, al" : : "a" ((u8) call)); + __asm__("mov %%eax, ebx" : : "a" (args)); // MUST BE A POINTER + +#ifdef SYSCALL_MODERN_INSTRUCTION + __asm__("syscall"); +#else + __asm__("int 0x80"); +#endif + + u8 result; + __asm__("mov bl, %%al" : "=a" (result)); + + if(result < DENIED || result > SYSCALL_RESPONSE_SZ) { + return UNDEFINED; + } + + return (syscall_response) result; +} \ No newline at end of file diff --git a/drivers/src/ps2kbd.c b/drivers/src/ps2kbd.c index 3a8ab7e..cfdaac9 100644 --- a/drivers/src/ps2kbd.c +++ b/drivers/src/ps2kbd.c @@ -2,7 +2,7 @@ #include #include -#include +#include #include diff --git a/kernel/includes/io/ioports.h b/kernel/includes/io/ioports.h new file mode 100644 index 0000000..23221b6 --- /dev/null +++ b/kernel/includes/io/ioports.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +u8 port_is_allowed(u8 port); \ No newline at end of file diff --git a/kernel/includes/syscall/syscall.h b/kernel/includes/syscall/syscall.h new file mode 100644 index 0000000..ecf474f --- /dev/null +++ b/kernel/includes/syscall/syscall.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +syscall_response khandle_syscall(syscall call, SYSCALL_ARGBUFF argbuff); \ No newline at end of file diff --git a/kernel/includes/taskio.h b/kernel/includes/taskio.h deleted file mode 100644 index 181fcdc..0000000 --- a/kernel/includes/taskio.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * TaskIO definitions - */ - -#pragma once - -#include - -#ifndef TASKIO_PERTASK_STACK_SIZE -#define TASKIO_PERTASK_STACK_SIZE 256 -#endif - -/** - * Defines tasks that are fully 'internal', AKA tasks that do NOT need to be ticked - * trough the CPU timer interrupt - */ -typedef struct taskio_task_t__bundled { - char* name; - void *(*detatch)(); - - struct taskio_task_t__bundled* prev; - struct taskio_task_t__bundled* next; -} internal_task_t; - -/** - * Defines tasks that are ticked in the CPU timer interrupt - */ -typedef struct taskio_task_t { - char* name; - u32* stack; - - u32 esp, ebp, eip; - u32 eax, ebx, ecx, edx; - u32 esi, edi; - u32 eflags; - - struct taskio_task_t* prev; - struct taskio_task_t* next; -} task_t; - -/** - * @name create_task - * - * @param name the name of the task - * @param entry_point the entry point - */ -task_t* create_task(char* name, void (*entry_point)()); - -/** - * @name create_internal_task - * - * @param name the name of the internal task - * @param detach the function allowing to detach/kill the internal tasks - */ -internal_task_t* create_internal_task(char* name, void (*detach)()); \ No newline at end of file diff --git a/kernel/includes/taskio/taskio.h b/kernel/includes/taskio/taskio.h new file mode 100644 index 0000000..3e55cbb --- /dev/null +++ b/kernel/includes/taskio/taskio.h @@ -0,0 +1,118 @@ +/** + * TaskIO definitions + */ + +#pragma once + +#include + +#ifndef TASKIO_PERTASK_STACK_SIZE +#define TASKIO_PERTASK_STACK_SIZE 256 +#endif + +#define TASKIO_TASK_LIKELY_POINTER taskio_task_common_t* + +#define TASKIO_FINDTASK(name) find_task(name, taskio_task_queue) +#define TASKIO_FINDINTERNALTASK(name) find_task(name, taskio_internaltask_queue) + +#define TASKIO_FINDTASK_0(name) TASKIO_FINDTASK(name) +#define TASKIO_FINDTASK_1(name) TASKIO_FINDINTERNALTASK(name) + +#define TASKIO_KILLTASKBYNAME(name, result, type) \ + TASKIO_TASK_LIKELY_POINTER task = TASKIO_FINDTASK_##type(name); \ + result = (task != 0) ? taskthis_kill_instant(result, type) : 0x00; + +typedef enum task_type { + NORMAL, + DRIVER, + KERNEL_INTEGRATED +} task_type; + +/** + * Defines tasks that are fully 'internal', AKA tasks that do NOT need to be ticked + * trough the CPU timer interrupt + */ +typedef struct taskio_task_t__bundled { + char* name; + task_type type; + + struct taskio_task_t__bundled* prev; + struct taskio_task_t__bundled* next; + + void *(*detatch)(); + +} internal_task_t; + +/** + * Defines tasks that are ticked in the CPU timer interrupt + */ +typedef struct taskio_task_t { + char* name; + task_type type; + + struct taskio_task_t* prev; + struct taskio_task_t* next; + + u32* stack; + + u32 esp, ebp, eip; + u32 eax, ebx, ecx, edx; + u32 esi, edi; + u32 eflags; +} task_t; + +/** + * Common structures between task_t and internal_task_t +*/ +typedef struct taskio_task_common_t { + char* name; + task_type type; + + struct taskio_task_common_t* prev; + struct taskio_task_common_t* next; +} taskio_task_common_t; + +typedef void (*entry_point_t)(); +typedef void (*detach_point_t)(); + +/** + * @name create_task + * + * @param name the name of the task + * @param entry_point the entry point + */ +task_t* create_task(char* name, void (*entry_point)()); + +/** + * @name create_internal_task + * + * @param name the name of the internal task + * @param detach the function allowing to detach/kill the internal tasks + */ +internal_task_t* create_internal_task(char* name, void (*detach)()); + +/** + * @name find_task + * + * Finds a task based on the name of it. It is recomended to use the FINDTASK macros instead. + * + * @param name the name of the task + * @param tree the tree pointer of the tasks. +*/ +TASKIO_TASK_LIKELY_POINTER find_task(char* name, TASKIO_TASK_LIKELY_POINTER tree); + +/** + * @name taskthis_kill_instant + * + * Kills the task, skips every permission / authority check when killing the task, doesn't wait for the app to be ready. + * + * @param task the pointer of the task + * @param mode the mode, 0x00 if normal task, 0x01 if internal + * @return 0x00 if the task couldn't be killed, 0x01 if it was + */ +u8 task_kill_instant(TASKIO_TASK_LIKELY_POINTER task, u8 mode); + + +extern task_t* taskio_task_queue; +extern internal_task_t* taskio_internaltask_queue; +extern task_t* current_task; \ No newline at end of file diff --git a/kernel/src/io/ioports.c b/kernel/src/io/ioports.c new file mode 100644 index 0000000..e2155c8 --- /dev/null +++ b/kernel/src/io/ioports.c @@ -0,0 +1,6 @@ +#include + +u8 port_is_allowed(u8 port) { + if(port == 0x60 || port == 0x64) return 1; + return 0; +} \ No newline at end of file diff --git a/kernel/src/shell/kshell.c b/kernel/src/shell/kshell.c index 9d044ed..82e2665 100644 --- a/kernel/src/shell/kshell.c +++ b/kernel/src/shell/kshell.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/kernel/src/syscall/syscall.c b/kernel/src/syscall/syscall.c new file mode 100644 index 0000000..9961147 --- /dev/null +++ b/kernel/src/syscall/syscall.c @@ -0,0 +1,81 @@ +#include +#include +#include + +#include + +#include + +syscall_response khandle_syscall(syscall call, SYSCALL_ARGBUFF argbuff) { + + if(current_task == 0) { + return DENIED; + } + + switch(call) { + case PRINT: + return DENIED_STRICT; + + case IOPORT_REQ: + if(argbuff == SYSCALL_NOARGS) return INVALID_SYSCALL; + u8* ptr = (u8*) argbuff; + + u8 port = *ptr; + u8 mode = *(ptr + 1); + + if(port < 0) return INVALID_SYSCALL; + if(mode < 0 || mode > 1) return INVALID_SYSCALL; + + if(current_task->type < DRIVER) { + task_kill_instant(current_task, 0x00); + return DENIED_STRICT; + } + + if(!port_is_allowed(port)) return DENIED; + + break; + + case TASK_KILL: + if(argbuff == SYSCALL_NOARGS) return INVALID_SYSCALL; + u8* ptr = (u8*) argbuff; + + u8 task_type = *ptr; + char* task_name = (char*) (ptr + 1); + + if(task_type < 0 || task_type > 1) return INVALID_SYSCALL; + if(task_name == 0) return INVALID_SYSCALL; + + //TODO: add a permission check here + + if(task_kill_instant(task_name, task_type) == 0) return ACCEPT_ERR; + return ACCEPTED; + + case TASK_SPAWN: + if(argbuff == SYSCALL_NOARGS) return INVALID_SYSCALL; + u8* ptr = (u8*) argbuff; + + u8 mode = *(ptr); + u8* point = *((u8**)(ptr + 1)); + char* name = *((char**)(ptr + sizeof(u8*) + 1)); + + if(mode < 0 || mode > 1) return INVALID_SYSCALL; + if(point == 0 || name == 0) return INVALID_SYSCALL; + + if(current_task->type != KERNEL_INTEGRATED) return DENIED; + + if(mode == 0x00) { + task_t* task = create_task(name, (entry_point_t)(point)); + + if(task == 0) return ACCEPT_ERR; + return ACCEPTED; + } + + internal_task_t* task = create_internal_task(name, (detach_point_t)(point)); + + if(task == 0) return ACCEPT_ERR; + return ACCEPTED; + default: + return INVALID_SYSCALL; + + } +} \ No newline at end of file diff --git a/kernel/src/taskio.c b/kernel/src/taskio/taskio.c similarity index 65% rename from kernel/src/taskio.c rename to kernel/src/taskio/taskio.c index 30c29b5..7984650 100644 --- a/kernel/src/taskio.c +++ b/kernel/src/taskio/taskio.c @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -9,6 +9,8 @@ task_t* create_task(char* name, void (*entry_point)()) { task_t* task = kmallocs(sizeof(task_t), 1); task->stack = kmallocs(TASKIO_PERTASK_STACK_SIZE, 1); + task->type = NORMAL; + u32 top = (u32) task->stack + TASKIO_PERTASK_STACK_SIZE; #ifdef TASKIO_EMPTY_STACK @@ -40,6 +42,8 @@ internal_task_t* create_internal_task(char* name, void (*detach)()) { task->next = taskio_internaltask_queue; task->detatch = detach; + task->type = KERNEL_INTEGRATED; + if(!taskio_internaltask_queue) { taskio_internaltask_queue = task; task->next = 0; @@ -49,4 +53,28 @@ internal_task_t* create_internal_task(char* name, void (*detach)()) { task->next = taskio_internaltask_queue; taskio_internaltask_queue = task; } -} \ No newline at end of file +} + +TASKIO_TASK_LIKELY_POINTER find_task(char* name, TASKIO_TASK_LIKELY_POINTER tree) { + TASKIO_TASK_LIKELY_POINTER n = tree; + + while(n != 0) { + if(strcmp(n->name, name)) { + return (TASKIO_TASK_LIKELY_POINTER)n; + } + n = n->next; + } + + return 0; +} + +u8 task_kill_instant(TASKIO_TASK_LIKELY_POINTER task, u8 mode) { + if(task == 0) return 0x00; + + if(mode == 0x01) ((internal_task_t*)task)->detatch(); + + if(task->prev != 0) task->prev->next = task->next; + if(task->next != 0) task->next->prev = task->prev; + + return 0x01; +}