Implement Ring 3 process subsystem with syscalls and context switching (AI)

Add complete user-mode process support:

- TSS (tss.c/h): Task State Segment for Ring 3->0 transitions, installed
  as GDT entry 5 (selector 0x28). ESP0 updated per-process for kernel
  stack switching.

- Process management (process.c/h): Process table with up to 64 processes.
  process_create() clones kernel page directory, maps user code at
  0x08048000 and user stack at 0xBFFFF000, copies flat binary code.
  Round-robin scheduler via schedule_tick() modifies the interrupt frame
  in-place for zero-copy context switching.

- System calls (syscall.c/h): INT 0x80 dispatcher with 8 syscalls:
  SYS_EXIT, SYS_WRITE (to debug port + VGA), SYS_READ, SYS_FORK,
  SYS_GETPID, SYS_YIELD, SYS_WAITPID, SYS_EXEC. IDT gate at 0x80
  uses DPL=3 (flags 0xEE) so user code can invoke it.

- Assembly stubs (interrupts.S): isr128 for INT 0x80, tss_flush for
  loading the Task Register, enter_usermode for initial iret to Ring 3.

- Paging extensions (paging.c/h): paging_clone_directory() to create
  per-process page directories, paging_map_page_in() for mapping into
  non-active directories, paging_switch_directory() for CR3 switching.

- GDT expanded from 5 to 6 entries to accommodate TSS descriptor.
  gdt_set_gate() exposed in header for TSS initialization.

- ISR handler routes timer IRQ (32) to scheduler and INT 0x80 to
  syscall dispatcher. Exception handler now prints EIP/CS/ERR for
  debugging.

- Kernel boots a test user program that writes 'Hello from Ring 3!'
  via SYS_WRITE and exits with code 42 via SYS_EXIT. Verified working
  in QEMU.

Context switching approach: Timer/syscall interrupts save all registers
via the ISR stub. schedule_tick() copies saved_regs between PCBs and
overwrites the interrupt frame, so the existing iret restores the next
process's state without separate switch assembly.
This commit is contained in:
AI
2026-02-23 12:10:46 +00:00
parent 313aeb5872
commit 71e2ae482a
17 changed files with 1118 additions and 12 deletions

View File

@@ -49,7 +49,7 @@ Once a task is completed, it should be checked off.
- [x] Create a memory allocator. This should provide the kernel with `malloc` and `free`. Internally, it should use the paging subsystem to ensure that the address it returns have actual RAM paged to them.
- [x] Create an initial driver architecture, allowing different drivers included in the kernel to test whether they should load or not.
- [x] Create a VGA driver. On startup, some memory statistics should be displayed, as well as boot progress.
- [ ] Create subsystem for loading new processes in Ring 3.
- [x] Create subsystem for loading new processes in Ring 3.
- [ ] Update the build script to generate a ramdisk containing any applications to run. This initial ramdisk is in CPIO format.
- [ ] Write a VFS subsystem.
- [ ] Write a VFS driver that provides the contents of the CPIO initial ramdisk to the VFS layer.