Writing an OS Kernel from Scratch – Part 7: User-Mode Processes and System Calls — Make Your OS Truly Usable!
“No matter how powerful the kernel, if it can’t run user programs, it’s just a fancy bare-metal toy. Today, we embrace user mode, taking the decisive step toward becoming a true OS!”
In the previous six posts, we completed boot, protected mode, paging, kernel multitasking, and other key modules. But kernel-mode multitasking has limited use — it can’t run third-party programs, can’t isolate errors, let alone be called an “operating system.”
A real OS must safely and isolatedly run user-written programs, providing services through system calls.
Today, we implement:
✅ User-mode process creation
✅ Privilege level switching (Ring 3 ←→ Ring 0)
✅ The first system call: sys_write
From now on, your OS is no longer “talking to itself” but a service platform that can run user code!
Privilege Levels (Rings): Hardware-level Security Boundary
x86 defines 4 privilege levels (Ring 0~3), but modern OS uses only two:
- Ring 0: Kernel mode — can execute all instructions, access all memory
- Ring 3: User mode — privileged instructions prohibited, memory restricted by page tables
If user mode attempts a privileged instruction, the CPU triggers #GP (General Protection Fault), and the kernel can catch and kill the process!
Loading User Programs: Simple ELF Parsing
Loading steps:
- Read ELF header from disk/memory
- Iterate program headers, find PT_LOAD segments
- For each segment, allocate physical pages, map to p_vaddr
- Copy segment content from ELF file to physical pages
- Initialize user stack (e.g., 0xBFFFFFFF)
Comments