feat: implement fork system call with deep address space cloning (AI)

- Added paging_clone_directory_from(): deep-copies user-space pages so
  parent and child have independent memory. Kernel pages are shared.
- Fixed process_fork() to accept registers_t* for accurate child state,
  and to clone from the parent's page directory (not the kernel's).
- Refactored process_exit() to properly context-switch to next process
  using new process_switch_to_user assembly stub (loads full registers_t
  and performs iret), instead of halting unconditionally.
- Fixed sys_waitpid() to use proper blocking: marks process BLOCKED,
  invokes scheduler, and resumes with exit code when child dies.
- Added SYSCALL_SWITCHED mechanism to prevent syscall_handler from
  clobbering the next process's EAX after a context switch.
- Created fork-test user app that validates fork + waitpid.
- Added docs/fork.md with architecture documentation.

Tested: fork-test creates child, both print messages, parent waits for
child exit (code 7), parent reaps and exits (code 0). hello-world also
verified to still work correctly after the process_exit refactor.
This commit is contained in:
AI
2026-02-23 12:42:02 +00:00
parent f1de5b6da6
commit 42328ead0b
9 changed files with 350 additions and 30 deletions

View File

@@ -174,3 +174,28 @@ enter_usermode:
push $0x1B /* CS (user code) */
push %ecx /* EIP (entry point) */
iret
/*
* process_switch_to_user - Restore full register state and iret to user mode.
* void process_switch_to_user(registers_t *regs);
*
* Used by process_exit to context-switch to the next process when the normal
* interrupt-return path isn't available (because we're not returning through
* an ISR stub). Loads all registers from the registers_t struct and performs
* iret to enter user mode.
*/
.global process_switch_to_user
.type process_switch_to_user, @function
process_switch_to_user:
movl 4(%esp), %esp /* Point ESP to the registers_t struct */
/* Restore segment register (ds → all data segments) */
pop %eax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
popa /* Restore EAX-EDI */
addl $8, %esp /* Skip int_no and err_code */
iret /* Pops EIP, CS, EFLAGS, UserESP, SS */