Skip to content

Repository files navigation

OSV — Unix-like Teaching Kernel for x86_64

A small Unix-like kernel built from scratch for x86_64, implementing core OS subsystems from bootloader through to a working shell with file I/O, multiprocessing, pipes, and demand paging.

Features

Lab Feature Status
1 File descriptors — open, read, write, close, dup, fstat, readdir Done
2 Multiprocessing — fork, wait, exit with process trees Done
3 Pipes — pipe, buffered IPC between processes Done
4 Demand paging — sbrk, heap growth, stack growth, malloc/free Done
5 Copy-on-write fork In progress

Architecture

arch/x86_64/          # Machine-dependent: bootloader, GDT/IDT/paging,
                      # context switch (swtch.S), APIC/PIC drivers
kernel/               # Portable kernel: proc, thread, sched, syscall,
                      # VM (mm/), VFS + sfs filesystem (fs/), pipes, drivers
include/kernel/       # Kernel-internal headers
include/lib/          # Shared headers (syscall numbers, userspace stubs)
lib/                  # Minimal libc shared by kernel and userspace
user/                 # Userspace programs + lab test suites (lab1–lab5)
tools/                # mkfs: host tool that builds fs.img
CacheSizeTest/        # Cache hierarchy benchmarking tool
TLBSizeTest/          # TLB size benchmarking tool

Key design points:

  • Many subsystems have two halves — policy in kernel/, mechanism in arch/x86_64/kernel/. When modifying thread/VM/trap behavior, check both sides.
  • Syscall dispatch lives in kernel/syscall.c, indexed by numbers in include/lib/syscall-num.h. User pointers are validated via validate_ptr/validate_str before the kernel touches them.
  • The VFS layer (kernel/fs/fs.c) uses file_operations vtables so pipes, console, and the sfs filesystem all plug in uniformly through struct file.

Boot flow

arch/x86_64/boot/bootasm.S + bootmain.c   (real-mode → long mode, loads kernel)
  └─ arch/x86_64/kernel/kstart.S / entry.S
       └─ kernel/main.c:main()             (VM, threading, syscalls, console)
            └─ kernel_init()               (block device, filesystem, SMP)
                 └─ proc_spawn(init)       → user/init.c → sh prompt

Build & run

Building requires Linux tooling (gcc, binutils, qemu-system-x86_64, python3). On Windows use Docker or WSL — PowerShell alone cannot build this project.

Docker (recommended on Windows)

docker build -t osv .
docker run --rm -it osv          # builds with `make` by default

Linux / WSL

make                             # build kernel ELF + disk images (build/osv.img, build/fs.img)
make qemu                        # boot in QEMU, serial console in terminal
make qemu-graphic                # boot with QEMU graphical window
make qemu-low-mem                # boot with 4 MB RAM (tests paging edge cases)
make qemu-gdb                    # boot paused, then `make gdb` in a second terminal to attach
make clean                       # remove build/
CPUS=4 make qemu                 # boot with 4 virtual CPUs (exercises SMP paths)

CFLAGS includes -Wall -Werror — any compiler warning fails the build.

Testing

User-space tests live under user/lab1user/lab5. Each is built into build/user/<lab>/<name> and baked into fs.img.

Single test — boot with make qemu, wait for the $ prompt, then type the binary name:

$ fork-tree

Full lab suite — runs QEMU headlessly and greps serial output for pass/fail:

python3 test.py 2     # run all lab 2 tests
python3 test.py 4     # run all lab 4 tests

Benchmarking tools

Directory What it measures
CacheSizeTest/ Memory access latency vs. array size to estimate cache hierarchy sizes
TLBSizeTest/ Memory access latency vs. number of pages touched to estimate TLB size

Run inside Linux/WSL (not QEMU) — see CacheSizeTest/run_cache.sh and TLBSizeTest/run_tlb.sh.

Design docs

Detailed per-lab design notes are in docs/:

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages