A hobby operating system for x86_64 architecture, written in C++23 and assembly.
This is a hobby operating system project for educational purposes.
⚠️ Not production-ready or security-hardened⚠️ May contain bugs or undefined behavior⚠️ Not recommended for use on real hardware- ✅ Safe for use in virtual machines (QEMU, VirtualBox, etc.)
Use at your own risk. The author(s) are not responsible for any damage, data loss, or hardware issues that may result from running this software.
Target: x86_64 (AMD64/Intel 64)
- Requires APIC support (LAPIC + IOAPIC)
- Uses Limine bootloader protocol
- Tested on: QEMU
- Physical memory manager (PMM) with bitmap allocator
- Virtual memory manager (VMM) with 4-level paging
- Higher-half kernel with HHDM (Higher Half Direct Map)
- Slab allocator for efficient small object allocation (32-1024 bytes)
- Per-process address spaces with user/kernel separation
- Unix-like VFS with single dispatch (
fd->inode->ops->read()) - Initramfs (tar-based) mounted at
/ - Devfs mounted at
/dev/dev/tty1- TTY with line editing and command history/dev/null- Null device
- Path canonicalization (
.,.., redundant slashes)
- ELF64 binary loading from initramfs
- Ring 3 userspace execution
- Preemptive scheduling via APIC timer
- Cooperative scheduling via
sys_yield - Process states: RUNNING, READY, BLOCKED, DEAD
- Per-process page tables and file descriptor tables
sys_read,sys_write,sys_open,sys_closesys_exit,sys_yieldsys_sleep_msfor timed blocking
- GDT with ring 0/3 segments
- IDT with interrupt/exception handling
- ACPI table parsing (RSDP, XSDT, MADT)
- APIC support (LAPIC + IOAPIC)
- PS/2 keyboard driver with scancode translation
- Framebuffer console with PSF font rendering
- Serial output (COM1) for kernel logging
- Dynamic containers (
kstring,kvector) - In-kernel unit test framework (160+ tests)
- Modern C++23 with freestanding implementation
os/
├── src/
│ ├── kernel/
│ │ ├── kernel.cpp # Kernel entry point
│ │ ├── include/ # Kernel headers
│ │ │ ├── arch.hpp # Architecture abstraction
│ │ │ ├── fs/ # Filesystem (VFS, initramfs, devfs)
│ │ │ ├── memory/ # PMM, VMM, Slab, kmalloc
│ │ │ ├── process/ # Process management
│ │ │ ├── scheduler/ # Process scheduler
│ │ │ ├── syscall/ # Syscall declarations
│ │ │ ├── containers/ # kstring, kvector
│ │ │ └── ...
│ │ ├── lib/ # Implementations
│ │ │ ├── fs/ # VFS, initramfs, devfs, dev_tty, dev_null
│ │ │ ├── memory/
│ │ │ ├── process/ # ELF loader, process creation
│ │ │ ├── scheduler/
│ │ │ ├── syscall/ # Syscall implementations
│ │ │ └── ...
│ │ ├── arch/x86_64/ # x86_64-specific code
│ │ │ ├── boot/ # Limine entry
│ │ │ ├── gdt/ # Global Descriptor Table
│ │ │ ├── interrupts/ # IDT, IRQ handling
│ │ │ ├── entry/ # Syscall entry (LSTAR/SYSRET)
│ │ │ ├── context/ # Context switching
│ │ │ ├── memory/ # VMM implementation
│ │ │ ├── drivers/ # APIC, keyboard, serial, etc.
│ │ │ └── ...
│ │ ├── test/ # Unit tests
│ │ └── CONVENTIONS.md # Code style guide
│ └── user/ # Userspace programs
│ └── ... # ELF binaries for initramfs
├── initramfs/ # Files packaged into initramfs
│ └── bin/ # Userspace binaries
├── limine/ # Limine bootloader files
└── configure.sh # Build script
See src/kernel/CONVENTIONS.md for namespace and code style conventions.
Requirements:
- GCC/G++ cross-compiler for x86_64-elf (or system compiler with proper flags)
- CMake 3.16+
- GNU assembler
- Limine bootloader
- xorriso (for ISO creation)
- QEMU (for testing)
Build Commands:
./configure.shRun in QEMU:
qemu-system-x86_64 -cdrom myos.isoWith serial output (recommended for debugging):
qemu-system-x86_64 -cdrom myos.iso -serial stdioBoot Sequence:
- Limine loads kernel, initramfs, and provides framebuffer, memory map, RSDP
- Early init sets up GDT, IDT, PMM, VMM with HHDM
- Parse ACPI tables (MADT) for APIC configuration
- Initialize LAPIC and IOAPIC for interrupt routing
- Initialize drivers (keyboard, serial, console)
- Mount initramfs at
/, devfs at/dev - Load and run userspace programs from
/bin/ - Scheduler manages processes with preemptive multitasking
VFS Architecture:
sys_read(fd, buf, count)
→ fd->inode->ops->read(fd, buf, count) // single dispatch
│
├─ fs_file_ops (regular files)
│ └─ memcpy from FsFileMeta->data
│
└─ tty_ops (char devices)
└─ keyboard input / console output
Key Design Decisions:
- Higher-half kernel: Kernel mapped at high addresses via HHDM
- Architecture abstraction:
lib/code usesarch::namespace, notx86_64::directly - Single dispatch VFS:
fd->inode->ops->read()- no double indirection - Flat namespaces: No
kernel::prefix; subsystems usefs::,pmm::,log::, etc. - k-prefixed utilities: Global types like
kstring,kvector,kprint() - Modern C++: C++23 with freestanding implementation, concepts, fold expressions
GNU General Public License v3.0
Built following OS development resources:
- Intel Software Developer Manual
- OSDev Wiki
- Limine bootloader documentation