// RESEARCH
SaakshiOS
A 32-bit x86 operating system, from scratch
Overview
SaakshiOS is a 32-bit x86 operating system written from scratch in C and NASM, with zero external dependencies — no libc, no standard library. It boots via GRUB, drops into ring 0, sets up its own GDT/TSS/IDT, paging, heap, drivers, filesystem, and scheduler, then launches a userspace shell in ring 3 that talks to the kernel via int $0x80.
What's implemented
| Layer | What it does |
|---|---|
| Boot | Multiboot-compliant boot via GRUB, 16KB kernel stack, Multiboot info parsing |
| CPU | GDT (6 entries), TSS, IDT (256 gates), ring 0/3 privilege separation |
| Memory | Physical page allocator (bitmap), two-level x86 paging, first-fit free-list heap |
| Interrupts | PIC remap (IRQ → INT 32–47), ISR stubs for all 32 CPU exceptions, IRQ handlers |
| Drivers | VGA text mode (80×25, color, scrolling), PIT (100 Hz), PS/2 keyboard with shift |
| Filesystem | VFS abstraction + in-memory ramfs (64 files × 32 KB) + custom initramfs format |
| Processes | PCB structs, round-robin scheduler, ring-switching context switch |
| Syscalls | 10 calls via int $0x80 — read, write, open, close, exit, getpid, readdir, uptime, meminfo, ps |
| Shell | Userspace REPL with help, ls, cat, echo, clear, uptime, meminfo, ps |
| Tools | mkramfs host-side tool to pack a directory into an initramfs image |
Boot flow
GRUB hands off control → boot.asm sets up the stack → kernel C entry point → init GDT → init paging → init heap → init PIC / IDT → init drivers → mount ramfs → load shell.bin at 0x600000 → switch to ring 3 → first user-mode instruction runs.
When the shell makes a syscall, the CPU traps into the kernel via the IDT, the syscall dispatcher reads the syscall number from eax, and the call returns through the same gate back to ring 3.
What's been most fun to debug
- Triple faults during early paging setup — when you've mapped the kernel wrong, you don't get a graceful error. You just reboot.
- Race conditions in the scheduler — IRQ-driven context switches without proper save/restore corrupt register state in subtle, delayed ways.
- Keyboard scancode tables — turns out keyboards are weirder than you think.
Why build it
You can read "Operating System Concepts" cover to cover and still not understand what an OS actually does until you write one. Every layer has its own surprises — paging, ring transitions, the relationship between hardware interrupts and the IDT, why a TSS is needed at all in 32-bit mode. Writing it from scratch is the only way to feel any of that.