A hand-written 32-bit x86 operating system: custom bootloader, protected mode, paging, a heap, preemptive multitasking, a persistent filesystem, a TCP/IP-ish network stack (ARP + ICMP), and an interactive shell — all from scratch, no libraries.
========================================
Channer OS v0.1
========================================
channer> ping 10.0.2.2
PING 10.0.2.2 32 bytes of data
reply from 10.0.2.2: icmp_seq=1 time=0 ms
channer> ps
ID STATE SWITCHES WORK NAME
0 running 35 0 shell
1 ready 35 91637780 miner
2 ready 22 69682784 render
- Bootloader (
boot/mbr.asm) — a 512-byte MBR that loads the kernel from disk in 32 KB chunks via INT13h LBA reads, so the kernel can grow large. - Protected mode — GDT, a runtime-built IDT (
interrupts/idt.c), and PIC remapping. Interrupt stubs (interrupts/isr.asm) save a full register frame andiretcorrectly. - Memory — E820 RAM detection, paging with a recursive page directory and a
demand-paging fault handler, a bitmap frame allocator, and a
kalloc/kfreeheap. - Preemptive multitasking (
proc/task.c) — round-robin kernel threads context-switched from the timer IRQ by swapping the saved stack pointer. - Console (
screen.c) — 80x25 VGA text with scrolling, a hardware cursor, and colors. All output is mirrored to COM1 serial for headless debugging. - Keyboard (
drivers/char/keyboard.c) — scancode set 1, shift/caps, and a type-ahead ring buffer feeding a blockingreadLine. - Filesystem (
filesystem/fs.c) — ChannerFS, a small persistent filesystem stored on disk (LBA 2048+) via an ATA PIO driver (drivers/block/disk.c). Create, read, write, append, delete; survives reboots. - Networking (
drivers/net/rtl8139.c,net/net.c) — an RTL8139 NIC driver (PCI discovery, DMA RX ring, TX), plus Ethernet / ARP / IPv4 / ICMP echo. It can resolve MACs and ping. - Shell (
shell.c) — an interactive CLI tying it all together.
Requires a cross toolchain + QEMU (macOS/Homebrew):
brew install x86_64-elf-gcc nasm qemuThen:
make build # -> out/os_image.img
make run # boot in QEMU (VGA window + serial on your terminal)
make debug # headless: serial -> out/serial.log, CPU trace -> out/qemu.logbuild.sh uses x86_64-elf-gcc -m32 because the system i386-elf-gcc install
here is missing its own assembler/linker.
help list commands ls list files
clear clear the screen cat <file> print a file
echo <text> print text write <file> <txt> (over)write a file
about about this OS append <file> <txt> append to a file
mem memory info touch <file> create empty file
uptime / ticks time since boot rm <file> delete a file
peek <hexaddr> read memory sync flush FS to disk
color <0-15> set text color format reformat the FS
reboot restart
ps list tasks
net NIC / IP info spawn [name] start a worker task
arp <ip> resolve a MAC kill <id> stop a task
ping <ip> ICMP echo
boot/mbr.asm stage-1 bootloader (LBA chunked loader)
linker.ld flat binary, loaded at 0x8200
kernel/kernel_entry.asm real mode -> protected mode entry
kernel/kernel.c unity build: #includes the C sources in order
kernel/screen.c VGA text console + serial mirror
kernel/shell.c interactive shell
kernel/stubs.c weak fallbacks for optional subsystem hooks
kernel/interrupts/ isr.asm stubs + idt.c (runtime IDT + dispatch)
kernel/drivers/ port I/O, serial, keyboard, ATA disk, PCI, RTL8139
kernel/memory/ paging, frame allocator, heap
kernel/proc/task.c preemptive scheduler
kernel/filesystem/fs.c ChannerFS
kernel/net/net.c ARP / IPv4 / ICMP
The earlier ext4 / DMA-ATA / old-scheduler experiments are left in the tree
(filesystem/ext4.c, drivers/block/ata/, proc/process.c,
proc/scheduler.c, interrupts/interrupt_handlers.c) but are not compiled
into the current build.
- Kernel threads run in ring 0; there is no user mode (ring 3) or syscall layer yet. The IDT + TSS scaffolding to add it is in place.
- ChannerFS uses fixed per-file slots (30 files, 8 KB each) — simple and fragmentation-free, but not a general allocator.
- The network stack does ARP + ICMP; no UDP/TCP/DHCP yet (the static IP matches QEMU's user-net default, 10.0.2.15).
- Networking RX is polled, not interrupt-driven.