From 2a7baf11848f1fa8f7de0454041b6b76f6c5a288 Mon Sep 17 00:00:00 2001 From: Ruslan Isaev Date: Sun, 6 Jul 2025 22:49:05 +0300 Subject: [PATCH] syscalls: start adding fork syscall, not done yet --- include/paging.h | 1 + include/stdio.h | 2 +- include/task.h | 2 ++ src/kernel/kernel.c | 2 +- src/mm/page_alloc.c | 2 +- src/mm/paging.c | 59 ++++++++++++++++++++++++++++++++++++++++++ src/tasking/syscalls.c | 27 +++++++++++++++++++ src/tasking/task.c | 2 -- 8 files changed, 92 insertions(+), 5 deletions(-) diff --git a/include/paging.h b/include/paging.h index 2d0c359..ce99975 100644 --- a/include/paging.h +++ b/include/paging.h @@ -40,6 +40,7 @@ void set_page_dir(uint32_t new_page_dir); uint32_t phys_to_virt(uint32_t phys); uint32_t* create_page_dir(); void destroy_page_dir(uint32_t* page_dir); +uint32_t* copy_page_dir(uint32_t* page_dir_virt); static inline uint32_t virt_to_phys(void* virt) { return (uint32_t)virt - 0xC0000000; diff --git a/include/stdio.h b/include/stdio.h index 7ee13e2..40bc973 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -14,7 +14,7 @@ int printf(const char* __restrict, ...); int putchar(int); int puts(const char*); -//#define KATAU_DEBUG +#define KATAU_DEBUG #ifdef KATAU_DEBUG #define debug_log printf diff --git a/include/task.h b/include/task.h index 0a51790..b01b03c 100644 --- a/include/task.h +++ b/include/task.h @@ -17,6 +17,8 @@ #define MAX_OPEN_FILES 32 +#define KSTACKSIZE 4096 + typedef enum TaskState { Ready, diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 225ff1c..eddcb7e 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -218,7 +218,7 @@ void kmain(unsigned int magic, unsigned int info) printf("huy1 points to: 0x%X huy2 points to:0x%X\n", huy, huy2); printf("huy1: %s\nhuy2: %s", huy, huy2); - exec_from_file("/ebalo/aaa"); + exec_from_file("/ebalo/forktest"); while(1) { diff --git a/src/mm/page_alloc.c b/src/mm/page_alloc.c index 4995a07..b57e9b3 100644 --- a/src/mm/page_alloc.c +++ b/src/mm/page_alloc.c @@ -61,7 +61,7 @@ void* alloc_page() { if(page_num == 0) continue; - debug_log("allocating page %X\n", page_num * PAGE_SIZE); + //debug_log("allocating page %X\n", page_num * PAGE_SIZE); page_bitmap[i] |= (1 << j); // Помечаем как занятый return (void*)(page_num * PAGE_SIZE); diff --git a/src/mm/paging.c b/src/mm/paging.c index 8c68ddd..626e5bc 100644 --- a/src/mm/paging.c +++ b/src/mm/paging.c @@ -188,4 +188,63 @@ void destroy_page_dir(uint32_t* page_dir_virt) { // We need its physical address to pass to the physical memory manager. debug_log("freeing PD page %X\n", virt_to_phys(page_dir_virt)); free_page((void*)virt_to_phys(page_dir_virt)); +} + +uint32_t* copy_page_dir(uint32_t* page_dir_virt) +{ + if(page_dir_virt == NULL) + return 0; + + uint32_t* new_pagedir = create_page_dir(); + + for(int i = 0; i < 768; i++) + { + uint32_t pde = page_dir_virt[i]; + + if(pde & PAGE_PRESENT) + { + debug_log("PDE %X present\n", pde); + uint32_t* new_page_table = (uint32_t*)alloc_page(); + if(new_page_table == NULL) { + return NULL; + } + + // Get original page table (physical address from PDE) + uint32_t* orig_page_table = (uint32_t*)phys_to_virt(pde & ~0xFFF); + + for(int j = 0; j < 1024; j++) + { + uint32_t pte = orig_page_table[j]; + if(pte & PAGE_PRESENT) + { + void* new_phys_page = alloc_page(); + if(!new_phys_page) + { + return NULL; + } + + void* orig_phys_page = (void*)(pte & ~0xFFF); + + debug_log("copying %X to %X...", orig_phys_page, new_phys_page); + memcpy(new_phys_page, orig_phys_page, PAGE_SIZE); + debug_log("done\n"); + new_page_table[j] = (uint32_t)new_phys_page | (pte & 0xFFF); + } + else + { + new_page_table[j] = pte; + } + } + + + // Set the new PDE in the child's page directory + new_pagedir[i] = (uint32_t)virt_to_phys(new_page_table) | (pde & 0xFFF); + } + else + { + new_pagedir[i] = pde; + } + } + debug_log("ENDENDENDEND\n"); + return new_pagedir; } \ No newline at end of file diff --git a/src/tasking/syscalls.c b/src/tasking/syscalls.c index 654720b..0c9bf87 100644 --- a/src/tasking/syscalls.c +++ b/src/tasking/syscalls.c @@ -2,6 +2,8 @@ #include #include "../include/stdio.h" #include "../include/liballoc.h" +#include "../include/paging.h" +#include "../include/string.h" #define STDIN_FILENO 0 #define STDOUT_FILENO 1 @@ -56,6 +58,23 @@ int sys_exit(TrapFrame *tf) return error_code; } +int sys_fork(TrapFrame *tf) +{ + debug_log("FORKFORKFORKFORK\n"); + + uint32_t* new_pd = copy_page_dir(current->pagedir); + + Process* child = task_create(0, 0, 3, new_pd); + + memcpy(child, current, sizeof(Process)); + memcpy(child->kstack, current->kstack, KSTACKSIZE); + + child->tf->eax = 0; + tf->eax = child->pid; + + return child->pid; +} + int sys_read(TrapFrame *tf) { if(tf->ebx < 3) @@ -145,6 +164,7 @@ int sys_close(TrapFrame *tf) void handle_syscall(TrapFrame *tf) { + asm("cli"); /* debug_log("EAX: %X ", tf->eax); debug_log("EBX: %X ", tf->ebx); @@ -157,6 +177,12 @@ void handle_syscall(TrapFrame *tf) int r = sys_exit(tf); tf->eax = r; } + + if(tf->eax == 2) + { + int r = sys_fork(tf); + tf->eax = r; + } if(tf->eax == 3)//read { @@ -179,4 +205,5 @@ void handle_syscall(TrapFrame *tf) int r = sys_close(tf); tf->eax = r; } + asm("sti"); } \ No newline at end of file diff --git a/src/tasking/task.c b/src/tasking/task.c index ac26ab9..e1e9ff0 100644 --- a/src/tasking/task.c +++ b/src/tasking/task.c @@ -13,8 +13,6 @@ uint32_t irq_disable_counter = 0; uint32_t pid_counter; uint32_t task_count; -#define KSTACKSIZE 4096 - extern void trapret(void); extern void switchProcess(Process* next);