1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 08:18:11 +00:00

Implement fork()!

This is quite cool! The syscall entry point plumbs the register dump
down to sys$fork(), which uses it to set up the child process's TSS
in order to resume execution right after the int 0x80 fork() call. :^)

This works pretty well, although there is some problem with the kernel
alias mappings used to clone the parent process's regions. If I disable
the MM::release_page_directory() code, there's no problem. Probably there's
a premature freeing of a physical page somehow.
This commit is contained in:
Andreas Kling 2018-11-02 20:41:58 +01:00
parent 10b666f69a
commit 8accc92c3c
16 changed files with 228 additions and 78 deletions

View file

@ -43,7 +43,7 @@ void initialize()
kprintf("syscall: int 0x80 handler installed\n");
}
DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3)
static DWORD handle(RegisterDump& regs, DWORD function, DWORD arg1, DWORD arg2, DWORD arg3)
{
ASSERT_INTERRUPTS_ENABLED();
switch (function) {
@ -128,6 +128,8 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3)
return current->sys$tcgetpgrp((int)arg1);
case Syscall::PosixTcsetpgrp:
return current->sys$tcsetpgrp((int)arg1, (pid_t)arg2);
case Syscall::PosixFork:
return current->sys$fork(regs);
default:
kprintf("<%u> int0x80: Unknown function %x requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3);
break;
@ -143,5 +145,6 @@ void syscall_entry(RegisterDump& regs)
DWORD arg1 = regs.edx;
DWORD arg2 = regs.ecx;
DWORD arg3 = regs.ebx;
regs.eax = Syscall::handle(function, arg1, arg2, arg3);
regs.eax = Syscall::handle(regs, function, arg1, arg2, arg3);
}