A hobby x86-64 operating system kernel written in C++20 and NASM. Code is partially written by AI models (Claude, GPT) with human control over architecture decisions, testing, and code review. Tested primarily in QEMU/KVM environments, including Google Cloud and Yandex Cloud VMs (MBR-based disk image, virtio devices). Real hardware support has not been tested.
- SMP — up to 8 CPUs with INIT/SIPI AP bootstrap
- Preemptive multitasking — per-CPU task queues, round-robin scheduling, load-balanced task placement
- Virtual memory — 4-level paging (4 KB pages), high-half kernel at
0xFFFF800001000000, TLB shootdown across CPUs via IPI - Page allocator — fixed-size block allocator (1–128 contiguous pages), pool allocator (32 B – 2 KB),
new/deletesupport - ACPI — RSDP/RSDT/MADT parsing for LAPIC/IOAPIC discovery and IRQ→GSI routing
- Interrupts — IDT with exception handlers, IOAPIC routing (edge + level-triggered), LAPIC IPI, PIC (remapped then disabled)
- Drivers — serial (COM1), VGA text mode, PIT (10 ms tick, SeqLock-protected counters), RTC (CMOS wall clock), PS/2 keyboard (8042), PCI bus scan, LAPIC, IOAPIC, virtio-blk, virtio-net, virtio-scsi, virtio-rng (legacy + modern virtio-pci transport)
- Block I/O — asynchronous, interrupt-driven block request queue with DMA slot pool,
BlockRequestsubmission withWaitGroupcompletion, direct DMA from caller buffers (page-aligned), virtqueue locking (RawSpinLock) for safe interrupt/task concurrency, early-boot polling fallback, SoftIrq-based retry for ring-full conditions, block device abstraction, MBR partition discovery - Networking — virtio-net driver with asynchronous interrupt-driven TX/RX, software frame queues (256-entry TX/RX) in
NetDevicebase class, reference-countedNetFramedescriptors for zero-copy DMA, TX slot pool with bitmask allocation, SoftIrq-based TX retry and RX processing, IP routing (subnet mask + gateway from DHCP, off-subnet traffic forwarded to gateway), ARP (cache, request, reply, dump), IPv4/UDP transmit, ICMP echo (ping reply + send, per-type statistics), DHCP client with lease renewal (sets IP, subnet mask, gateway, DNS server), DNS resolver with 32-entry cache (A-record queries, name compression, DHCP-provided server), TCP (connection state machine, 3-way handshake, sequence/ack tracking, retransmission timers, MSS negotiation, send/receive ring buffers, graceful close with FIN exchange, RST handling, ephemeral port allocation, granular locking:Mutexfor ports,RawSpinLockfor pool and per-connection state, SoftIrq-driven timer processing), HTTP client (URL parsing, DNS resolution, TCP connection, request/response, redirect following for 301/302/303/307/308 with loop limit,wgetshell command), UDP remote shell (execute kernel commands over the network), network device abstraction with per-protocol packet counters,MacAddress/IpAddressstructs (IPv6-ready tagged union) - Filesystem — VFS layer with mount points and path resolution, ramfs (in-memory), nanofs (on-disk filesystem with 4 KB blocks, superblock with UUID, inode/data bitmaps, CRC32 checksums for superblock/inodes/data, file and recursive directory deletion, persistent across remount)
- Entropy —
EntropySourceinterface,EntropySourceTableregistry, virtio-rng hardware random number generator - Power management — ACPI S5 shutdown, keyboard controller reset/reboot
- Interactive shell — trace output suppressed during shell session (dmesg only), restored on shutdown; commands:
ps,cpu,bt <pid>,dmesg [filter],uptime,date,memusage,pci,disks,diskread,diskwrite,irqstat,net,arp,icmpstat,tcpstat,udpsend,ping,nslookup,dnsflush,dhcp,wget,random,format,mount,umount,ls,cat,write,mkdir,touch,del,panic,version,cls,help,poweroff,reboot - Timekeeping — TSC calibration via PIT channel 2 (multi-round median), KVM paravirt clock (
kvmclock) for accurate VM time, RTC wall clock, layered clock source selection (kvmclock → calibrated TSC → PIT fallback),GetBootTime()/GetWallTimeSecs()API - Kernel infrastructure — spinlocks, mutexes, SeqLock (single-writer/multi-reader), atomics, wait groups, SoftIrq deferred processing, IPI tasks, timers, watchdog, stack traces with symbol resolution, dmesg ring buffer (512 KB, 2048 messages), panic handler with backtrace and CPU/task context, per-device interrupt statistics, AP startup diagnostics, virtual-to-physical address translation (4-level page table walk), byte-order helpers (
Htons/Htonl/Ntohs/Ntohl) - Optimized stdlib —
MemSet,MemCpy,MemCmp,StrLen,StrCmp,StrStrimplemented in x86-64 assembly usingrep stosq/rep movsq/repe cmpsb/repne scasb - Boot tests — allocator, btree, ring buffer, stack trace, multitasking, contiguous page alloc (up to 128 pages), parsing helpers, block device table, memset, memcpy, memcmp, strlen, strcmp, strstr
Native (requires clang, nasm, ld, grub-mkrescue):
makeVia Docker (works on macOS / Apple Silicon):
./scripts/build-iso-docker.shThis produces nos.iso and bin/kernel64.elf (for GDB symbols).
Build a bootable qcow2 disk image (MBR, 2 partitions):
./scripts/build-disk.shThis produces nos.qcow2 (1 GB, MBR, virtio-blk compatible, suitable for KVM-based public clouds including Google Cloud Compute Engine).
With KVM (Linux):
qemu-system-x86_64 -enable-kvm -smp 8 -cdrom nos.iso -serial file:nos.log \
-device isa-debug-exit,iobase=0xf4,iosize=0x04Without KVM (macOS with TCG):
qemu-system-x86_64 -smp 2 -cdrom nos.iso -serial file:nos.log -s -vga stdBoot from disk image (with virtio-blk):
./scripts/qemu-disk.shDeploy to Google Cloud Compute Engine (select Skip OS adaptation when importing the image — the kernel already has the necessary drivers and no guest agent):
# Upload disk image to a GCS bucket
gcloud storage cp nos.qcow2 gs://YOUR_BUCKET/nos.qcow2
# Create a Compute Engine image from the disk (skip OS adaptation)
gcloud compute images create nos-image \
--source-uri=gs://YOUR_BUCKET/nos.qcow2
# Launch a VM (serial console recommended)
gcloud compute instances create nos-vm \
--image=nos-image \
--machine-type=e2-small \
--metadata=serial-port-enable=true
# Connect via serial console
gcloud compute connect-to-serial-port nos-vmStart QEMU with -s (GDB server on port 1234), then:
gdb -ex "symbol-file bin/kernel64.elf" \
-ex "set architecture i386:x86-64" \
-ex "target remote :1234"Pass via GRUB command line (edit build/grub.cfg):
smp=off— disable SMP, run on BSP onlyconsole=serial— direct shell output to serial port onlyconsole=vga— direct shell output to VGA onlydhcp=auto— start DHCP oneth0automatically at bootdhcp=off— disable DHCP entirely (even via shell command)dhcp=on— enable DHCP only via shell command (default)dns=on— enable DNS resolver (uses DHCP-provided DNS server; requiresdhcp=auto)udpshell=PORT— start UDP remote shell on the given port (e.g.udpshell=9000)
When udpshell=PORT is set, the kernel listens for commands on that UDP port.
A lightweight protocol header (16 bytes: magic, sequence number, chunk index, flags, payload length) frames every packet, enabling the client to validate replies, reassemble multi-chunk responses in order, and detect the end of a response without relying on timeouts.
Connect with the included Python client:
python3 scripts/udpsh.py <vm-ip> [port] [timeout]- Default port is
9000, default timeout is30seconds (long enough for blocking commands likeping). - On protocol errors or timeouts, the client reconnects automatically and resets state.
- All shell commands work over the UDP session (including blocking ones like
ping). - Warning: the UDP shell has no authentication — anyone who can reach the port has full kernel shell access. Use only for testing or behind a firewall.
| Command | Description |
|---|---|
cls |
Clear screen |
cpu |
Dump CPU state |
dmesg [filter] |
Dump kernel log (optional substring filter) |
uptime |
Show uptime |
date |
Show wall clock date and time (RTC + boot time) |
ps |
Show tasks |
bt <pid> |
Dump stack trace of a task (uses IPI for remote CPUs) |
watchdog |
Show watchdog stats |
memusage |
Show memory usage |
pci |
Show PCI devices |
disks |
List block devices |
diskread <disk> <sector> |
Read and hex-dump a sector |
diskwrite <disk> <sector> <hex> |
Write hex data to a sector |
irqstat |
Show per-device interrupt counters |
help |
List commands |
net |
List network devices and per-protocol stats |
arp |
Show ARP table |
icmpstat |
Show ICMP statistics |
tcpstat |
Show TCP connections and statistics |
wget <url> |
Fetch a URL via HTTP GET (follows redirects) |
udpsend <ip> <port> <msg> |
Send a UDP packet |
ping <ip|hostname> |
Send 5 ICMP echo requests with RTT (resolves hostnames via DNS) |
nslookup <hostname> |
Resolve hostname to IP via DNS |
dnsflush |
Flush DNS cache |
dhcp [dev] |
Obtain IP address via DHCP |
random [len] |
Get random bytes as hex string |
format nanofs <disk> |
Format disk with nanofs |
mount ramfs <path> |
Mount a ramfs at path |
mount nanofs <disk> <path> |
Mount nanofs from disk at path |
umount <path> |
Unmount filesystem |
mounts |
List mount points |
ls <path> |
List directory contents |
cat <path> |
Show file contents |
write <path> <text> |
Write text to file (creates if needed) |
mkdir <path> |
Create directory |
touch <path> |
Create empty file |
del <path> |
Remove file or directory |
panic [type] |
Trigger kernel panic (direct, pagefault, divzero, ud) |
version |
Show kernel version |
poweroff / shutdown |
Power off (ACPI S5) |
reboot |
Reset system (keyboard controller) |
boot/ Multiboot2 entry, 32→64-bit transition, AP trampoline
kernel/ Core: scheduling, tasks, interrupts, SoftIrq, shell, timers, timekeeping (TSC, kvmclock), locks, panic, symbol table
drivers/ Hardware: serial, VGA, PIT, RTC, 8042, PCI, PIC, LAPIC, IOAPIC, ACPI, virtio-blk, virtio-net, virtio-scsi, virtio-rng
block/ Block I/O: device abstraction, async request queue, MBR partition discovery
net/ Networking: device abstraction, protocol headers, ARP, ICMP, DHCP, DNS, TCP, HTTP client, UDP shell
fs/ Filesystem: VFS, ramfs, nanofs, block I/O helpers
mm/ Memory: page tables (4-level walk, VirtToPhys), page allocator, pool allocator
lib/ Utilities: list, vector, btree, ring buffer, bitmap, CRC32 checksum, stdlib
build/ Linker script, GRUB configs
scripts/ Build, run, debug, and GDB helpers