wip on fork

minimal example works
This commit is contained in:
2026-02-25 11:32:22 +01:00
parent 22ab2fb2a5
commit 8b271e2470
8 changed files with 64 additions and 18 deletions

View File

@@ -100,9 +100,9 @@ extern "C" int main() {
} }
Thread* thread_ptr = new Thread(false, (void*)0x4000000, (void*)0x4001000, 2); //Thread* thread_ptr = new Thread(false, (void*)0x4000000, (void*)0x4001000, 2);
g.vault().scheduler.ready(thread_ptr); //g.vault().scheduler.ready(thread_ptr);
g.vault().thread_list[thread_ptr->id] = thread_ptr; //g.vault().thread_list[thread_ptr->id] = thread_ptr;
//for(void* p=Multiboot::getModule(0)->getStartAddress(); p<Multiboot::getModule(0)->getEndAddress(); p=(void*)((uintptr_t)p+4096)){ //for(void* p=Multiboot::getModule(0)->getStartAddress(); p<Multiboot::getModule(0)->getEndAddress(); p=(void*)((uintptr_t)p+4096)){
// DBG << "module at: " << hex << p << endl; // DBG << "module at: " << hex << p << endl;

View File

@@ -231,6 +231,8 @@ void copy_pagetable(four_lvl_paging_t* parent_table, four_lvl_paging_t* child_ta
((uintptr_t)i3<<30) | ((uintptr_t)i3<<30) |
((uintptr_t)i2<<21) | ((uintptr_t)i2<<21) |
((uintptr_t)i1<<12) ; ((uintptr_t)i1<<12) ;
if(vaddr < 0x4000000)
continue;
if(!isMapped(vaddr, child_table)){ if(!isMapped(vaddr, child_table)){
//only copy if not part of basic pagetable //only copy if not part of basic pagetable
assert( (i3>0) || (i2>=32)); //assert user memory assert( (i3>0) || (i2>=32)); //assert user memory

View File

@@ -9,6 +9,7 @@
#include "../thread/scheduler.h" #include "../thread/scheduler.h"
#include "../memory/pageframealloc.h" #include "../memory/pageframealloc.h"
#include "../memory/pagetable.h" #include "../memory/pagetable.h"
#include "../arch/idt.h"
void *operator new(size_t, void *); void *operator new(size_t, void *);
//#include "../user/app1/appl.h" //#include "../user/app1/appl.h"
@@ -175,8 +176,6 @@ namespace Syscall {
bool copy_from_phys(Vault& vault, uintptr_t phys_ptr, void* virt_ptr, size_t size) { bool copy_from_phys(Vault& vault, uintptr_t phys_ptr, void* virt_ptr, size_t size) {
Thread* current_thread = vault.scheduler.active();
size_t offset = Page::offset(phys_ptr); size_t offset = Page::offset(phys_ptr);
size_t total_size = size + offset; size_t total_size = size + offset;
four_lvl_paging_t* search_table = vault.scheduler.active()->paging_tree; four_lvl_paging_t* search_table = vault.scheduler.active()->paging_tree;
@@ -185,10 +184,10 @@ bool copy_from_phys(Vault& vault, uintptr_t phys_ptr, void* virt_ptr, size_t siz
if (virt_addr == nullptr) { if (virt_addr == nullptr) {
return false; return false;
} }
for(uint8_t i =0; i<size/4096 +1; i++){ for(uint8_t i =0; i<size/4096 +1; i++){
setMapping((uintptr_t)virt_addr, (void*)phys_ptr, vault.scheduler.active()->paging_tree); setMapping((uintptr_t)virt_addr, (void*)phys_ptr, vault.scheduler.active()->paging_tree);
} }
memcpy(virt_ptr, (void*)((uintptr_t)(virt_addr)+ (uintptr_t)offset), size); memcpy(virt_ptr, (void*)((uintptr_t)(virt_addr)+ (uintptr_t)offset), size);
setMapping((uintptr_t)(virt_addr), 0, search_table); setMapping((uintptr_t)(virt_addr), 0, search_table);
@@ -280,9 +279,25 @@ bool reply(Vault& v, const void* buffer, size_t size) {
return true; return true;
} }
void copy_stack(Thread* parent, Thread* child){
uintptr_t dest_frame = isMapped((uintptr_t)child->StackPointer.user, child->paging_tree);
void* dest_vaddr = getFreeVirtSpace(parent->paging_tree, 1);
setMapping((uintptr_t)dest_vaddr, (void*)dest_frame, parent->paging_tree);
memcpy(dest_vaddr, (void*)0x6000000/*((uintptr_t)parent->StackPointer.user & ~0xFFF)*/, 4096);
setMapping((uintptr_t)dest_vaddr, 0, parent->paging_tree);
}
int fork(Vault &vault, InterruptContext *user_context) { int fork(Vault &vault, InterruptContext *user_context) {
Thread* parent = vault.scheduler.active(); Thread* parent = vault.scheduler.active();
//Thread* child = new Thread(false, Thread* child = new Thread(false, (void*)user_context->ip, parent->code_paddr, parent->code_pagenum);
copy_pagetable(parent->paging_tree, child->paging_tree);
copy_stack(parent, child);
child->StackPointer.user = (void*)user_context->sp;
vault.scheduler.ready(child);
return 0; return 0;
} }

View File

@@ -6,7 +6,21 @@
align 8 align 8
sys_call: sys_call:
; BSB2 1 - Syscall stub ; BSB2 1 - Syscall stub
push rbx
push rbp
push r11
push r12
push r13
push r14
push r15
int 0x80 int 0x80
pop r15
pop r14
pop r13
pop r12
pop r11
pop rbp
pop rbx
ret ret

View File

@@ -4,6 +4,7 @@
#include "../arch/core_ring.h" #include "../arch/core_ring.h"
#include "../memory/pageframealloc.h" #include "../memory/pageframealloc.h"
#include "../memory/pagetable.h" #include "../memory/pagetable.h"
#include "../memory/page.h"
#include "../debug/kernelpanic.h" #include "../debug/kernelpanic.h"
#include "../interrupt/guard.h" #include "../interrupt/guard.h"
#include "debug/output.h" #include "debug/output.h"
@@ -49,11 +50,11 @@ void Thread::map_app(void* code_paddr, uint16_t code_page_num, void* stack_vaddr
} }
} }
Thread::Thread (bool kernel, void* start_addr, void * codeframe, int code_frame_num): queue_link(nullptr), isKernel(kernel), start(start_addr), id(idCounter++), kill_flag(false){ Thread::Thread (bool kernel, void* start_addr, void * codeframe, int code_frame_num): queue_link(nullptr), isKernel(kernel), start(start_addr), code_paddr(codeframe), code_pagenum(code_frame_num), id(idCounter++), kill_flag(false){
StackPointer.isr = reinterpret_cast<void *>((uintptr_t)PageFrameAllocator::alloc(true)+STACK_SIZE);// mapped due to identity mapping StackPointer.isr = reinterpret_cast<void *>((uintptr_t)PageFrameAllocator::alloc(true)+STACK_SIZE);// mapped due to identity mapping
StackPointer.user = (void*)(0x61FF000+STACK_SIZE); StackPointer.user = (void*)(0x6000000+STACK_SIZE);
map_app(codeframe, code_frame_num, StackPointer.user, 1); map_app(codeframe, code_frame_num, (void*)((uintptr_t)StackPointer.user-STACK_SIZE), 1);
prepareContext(StackPointer.isr, context, kickoff, reinterpret_cast<uintptr_t>(this), 0, 0); prepareContext(StackPointer.isr, context, kickoff, reinterpret_cast<uintptr_t>(this), 0, 0);
} }

View File

@@ -57,7 +57,6 @@ class Thread {
/*! \brief Context of the thread, used for saving and restoring the register /*! \brief Context of the thread, used for saving and restoring the register
* values when context switching. * values when context switching.
*/ */
Context context;
/*! \brief The thread's entry point. /*! \brief The thread's entry point.
* *
@@ -87,9 +86,11 @@ class Thread {
} StackPointer; } StackPointer;
void* operator new ( size_t count )noexcept; void* operator new ( size_t count )noexcept;
Context context;
four_lvl_paging_t* paging_tree; four_lvl_paging_t* paging_tree;
pagetable_t* appcode_table;
pagetable_t* appstack_table; void* code_paddr;
int code_pagenum;
Semaphore ipc_sem; Semaphore ipc_sem;
Queue<IpcStruct> ipc_queue; Queue<IpcStruct> ipc_queue;

3
notes
View File

@@ -31,3 +31,6 @@
| | | |
| | | |
schedule(2) kickoff schedule(2) kickoff
p/x ((pagetable_t*)(((pagetable_t*)(((pagetable_t*)(child.paging_tree.l4.entries[0].address<<12)).entries[0].address<<12)).entries[0].address<<12)).entries[0]

View File

@@ -45,13 +45,23 @@ extern "C" void main() {
//sys_test(1,2,3,4,5); //sys_test(1,2,3,4,5);
fork();
unsigned id = sys_getpid(); unsigned id = sys_getpid();
char text[] = "appX"; char text[] = "appX";
text[3] = 0x30+id; text[3] = 0x30+id;
write(1, text, sizeof(text), 0, (int)id); write(1, text, sizeof(text), 0, (int)id);
uint8_t cnt = 0; uint8_t cnt = 0;
while(1){
cnt = (cnt+1)%100;
char msg[12];
char* num = itoa(cnt, msg);
write(1, num, strlen(num), 10, (int)id);
sleep(100);
}
for (uint8_t i = 1;; ++i) { for (uint8_t i = 1;; ++i) {
//counter to see app running //counter to see app running
cnt=(cnt+1)%100; cnt=(cnt+1)%100;