OS-C is a freestanding 64-bit operating system kernel written in ISO C11 and x86_64 assembly, designed to explore and understand the boundary between firmware, hardware, and software abstraction.
Unlike typical OS hobby projects, this kernel intentionally avoids libc and external runtime dependencies. Every runtime primitive — memory management, interrupt handling, and execution flow — is implemented directly within the kernel.
The system boots as a UEFI application (kernel.efi), transitions control from firmware to kernel-owned memory management, initializes core CPU structures, and enters an interactive shell environment over serial I/O.
Modern software development often abstracts away the underlying machine. This project was built to reverse that abstraction — to understand:
- How firmware transfers control to an OS
- How memory is discovered, mapped, and managed
- How interrupts and syscalls form the foundation of execution
- What is required to move from raw hardware to a usable system
The goal is not just to “build an OS”, but to understand the constraints, tradeoffs, and failure modes of real systems.
The kernel follows a monolithic design with explicit control over all subsystems.
- UEFI loads
kernel.efi - Kernel retrieves memory map
- Exits boot services safely
- Transfers control to
kernel_main - Initializes subsystems in deterministic order
- Enters interactive shell loop
-
Physical Memory Manager (PMM):
- Bitmap-based allocator
- Initialized from EFI memory map
- Page size: 4 KiB
-
Virtual Memory:
-
4-level paging (PML4)
-
Identity mapping (low memory)
-
Higher-half kernel mapping:
0xFFFFFFFF80000000
-
-
Heap Allocator:
- Bump allocator (8 MiB region)
- 16-byte aligned
- No free (intentional simplification)
-
GDT: Kernel/user segments initialized and loaded
-
IDT: 256-entry table with interrupt gates
-
Interrupts:
- PIC remapped (0x20–0x2F)
- PIT configured at 1 kHz
-
Uses
syscall/sysretinstructions -
MSRs configured:
STAR,LSTAR,FMASK,EFER
-
Assembly stubs bridge user/kernel boundary
-
Round-robin task list
-
Circular linked structure
-
Current limitation:
- No full register context switching yet
- In-memory filesystem (flat inode structure)
- Basic VFS abstraction layer
- Interactive shell commands:
ls
echo <text>
cat <file>
uptime
meminfo
draw
help
Chosen for simplicity and deterministic behavior during early boot. While less efficient than buddy allocation, it provides predictable allocation patterns and low implementation complexity.
Separates kernel space from user space and mirrors real OS design patterns, improving safety and clarity in address space layout.
To maintain full control over runtime behavior and avoid hidden abstractions that obscure low-level mechanics.
UEFI provides structured interfaces (memory map, protocols) and is closer to modern system initialization flows.
UEFI requires the memory map to remain unchanged between retrieval and exit. Early implementations failed due to mismatched map keys, requiring a retry-safe loop.
Incorrect page table setup caused CPU resets. Debugging required careful validation of identity mapping and CR3 loading.
Improper ISR setup initially corrupted execution state. Fixed by enforcing strict register save/restore discipline in assembly stubs.
Ensuring safe transition from firmware-managed memory to kernel-managed memory required careful sequencing of PMM initialization.
src/efi_main.c— UEFI entry and boot transitionsrc/kernel.c— Kernel initialization and main loopsrc/pmm.c— Physical memory allocatorsrc/paging.c— Virtual memory setupsrc/gdt.c,src/start.S— GDT initializationsrc/idt.c,src/interrupt_stubs.S— Interrupt systemsrc/scheduler.c— Task managementsrc/fs.c,src/vfs.c— Filesystem layersrc/graphics.c— Framebuffer abstractionscripts/linker.ld— Higher-half linker script
- x86_64-elf GCC toolchain
- QEMU
- OVMF firmware
make
./scripts/run.sh
Inside the kernel shell:
ls
echo hello
cat test.txt
uptime
meminfo
draw
help
- No page fault handler
- No full context switching
- No complete user-mode execution path
- Limited driver implementations
These are intentional next steps toward a more complete system.
- Demand paging and page fault handling
- Full context switching (register + stack state)
- User-mode process execution
- SMP (multi-core support)
- Persistent filesystem
OS-C is an exploration of system fundamentals — from firmware interfaces to kernel execution — with a focus on understanding rather than abstraction.
This project represents an ongoing effort to move from “writing programs” to engineering systems.