← Back to all projects

TRACK A OS KERNEL PROJECTS

Operating Systems & Kernel Development — Learning Projects

Track A: Hard Mode — For kernel dev, OS teams, hypervisor/virtualization, cloud infra internals

This is the “hard mode” track for good reason. These projects will take you from observing the kernel from userspace to actually writing code that runs in kernel space.


Core Concept Analysis

The topics in this track form an interconnected system. Here’s how they relate:

Concept What You Need to Understand
Syscall paths How control transfers from user code → kernel → back, the syscall table, context switching overhead
Process lifecycle fork/exec/wait, process states (running, sleeping, zombie), exit, process hierarchy
Virtual memory Page tables, address spaces, memory mapping, copy-on-write, demand paging
Page faults Major vs minor faults, fault handlers, memory-mapped files, swapping
Scheduling Run queues, time slices, priorities, preemption, scheduler classes (CFS, RT)
Interrupts Hardware interrupts, interrupt handlers, top/bottom halves, softirqs
Device drivers Character vs block devices, file_operations, ioctl, kernel APIs
Kernel/user boundary Protection rings, privilege levels, copying data across boundary
OS-level locks Spinlocks, mutexes, semaphores, RCU, lock ordering, deadlock prevention

Project 1: Syscall Tracer (strace clone)

  • File: TRACK_A_OS_KERNEL_PROJECTS.md
  • Programming Language: C
  • Coolness Level: Level 4: Hardcore Tech Flex
  • Business Potential: 3. The “Service & Support” Model
  • Difficulty: Level 3: Advanced
  • Knowledge Area: OS Internals / Debugging
  • Software or Tool: ptrace
  • Main Book: “The Linux Programming Interface” by Michael Kerrisk

What you’ll build: A tool that intercepts and logs every system call a program makes, showing the syscall name, arguments, and return values in real-time.

Why it teaches OS internals: Building strace forces you to understand the exact boundary between user and kernel space. You’ll use ptrace() to stop a process at every syscall, decode the syscall number from registers, and understand how arguments are passed. This is the single best way to see the kernel/user boundary in action.

Core challenges you’ll face:

  • Decoding syscall numbers to names (maps to syscall table structure)
  • Reading arguments from registers and memory (maps to calling conventions, kernel/user boundary)
  • Handling multi-threaded programs (maps to process lifecycle, threading model)
  • Following child processes through fork/exec (maps to process lifecycle)
  • Dealing with restartable syscalls after signals (maps to interrupt handling)

Resources for key challenges:

  • “The Linux Programming Interface” by Michael Kerrisk (Ch. 26: Process Tracing) - The definitive guide to ptrace
  • “Computer Systems: A Programmer’s Perspective” by Bryant & O’Hallaron (Ch. 8) - Exception control flow and syscalls

Key Concepts:

  • ptrace mechanism: “The Linux Programming Interface” Ch. 26 - Michael Kerrisk
  • x86-64 calling conventions: “Computer Systems: A Programmer’s Perspective” Ch. 3 - Bryant & O’Hallaron
  • Syscall tables: Linux kernel source arch/x86/entry/syscalls/syscall_64.tbl
  • Process states: “Operating Systems: Three Easy Pieces” Ch. 4 - Arpaci-Dusseau

Difficulty: Intermediate Time estimate: 2-3 weeks Prerequisites: C programming, basic understanding of processes, comfort reading man pages

Real world outcome:

  • Run ./mystrace ls -la and see every syscall: open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
  • Output should be readable like real strace, showing timing, arguments, return codes
  • Can trace any program on your system and understand what it’s actually doing

Learning milestones:

  1. Successfully intercept and print syscall numbers → You understand the ptrace state machine
  2. Decode arguments including strings and structs → You understand memory layout and kernel/user data transfer
  3. Handle fork/exec and follow children → You understand process lifecycle deeply
  4. Support multi-threaded programs → You understand the relationship between processes and threads at OS level

Project 2: Memory Allocator (malloc/free from scratch)

  • File: TRACK_A_OS_KERNEL_PROJECTS.md
  • Programming Language: C
  • Coolness Level: Level 4: Hardcore Tech Flex
  • Business Potential: 1. The “Resume Gold”
  • Difficulty: Level 3: Advanced
  • Knowledge Area: Memory Management / Systems Programming
  • Software or Tool: sbrk / mmap
  • Main Book: “Computer Systems: A Programmer’s Perspective” by Bryant & O’Hallaron

What you’ll build: A complete memory allocator that replaces malloc/free, using only brk() and mmap() syscalls, with visual debugging output showing heap state.

Why it teaches OS internals: malloc is the interface between your program and the kernel’s virtual memory system. By implementing it, you’ll understand why the heap exists, how the kernel grows your address space, the difference between virtual and physical memory, and why memory fragmentation happens.

Core challenges you’ll face:

  • Managing the program break with brk()/sbrk() (maps to virtual memory, syscalls)
  • Using mmap() for large allocations (maps to virtual memory, page faults)
  • Implementing free lists and coalescing (maps to memory management algorithms)
  • Handling alignment requirements (maps to hardware memory model)
  • Debugging memory corruption (maps to understanding address space layout)

Resources for key challenges:

  • “Computer Systems: A Programmer’s Perspective” Ch. 9.9 - Detailed malloc implementation walkthrough
  • “Operating Systems: Three Easy Pieces” Ch. 17 - Free space management

Key Concepts:

  • Virtual address space layout: “Computer Systems: A Programmer’s Perspective” Ch. 9 - Bryant & O’Hallaron
  • Free list management: “Operating Systems: Three Easy Pieces” Ch. 17 - Arpaci-Dusseau
  • mmap syscall: “The Linux Programming Interface” Ch. 49 - Michael Kerrisk
  • Memory alignment: “C Interfaces and Implementations” Ch. 5 - David Hanson

Difficulty: Intermediate Time estimate: 2-3 weeks Prerequisites: C, pointers, basic understanding of processes

Real world outcome:

  • LD_PRELOAD=./mymalloc.so ./some_program - Replace system malloc with yours
  • Visual heap dump: [BLOCK 0x1000: 64 bytes USED] [BLOCK 0x1040: 128 bytes FREE] ...
  • Run benchmarks comparing your allocator to glibc malloc
  • Successfully run complex programs (even a shell) using your allocator

Learning milestones:

  1. Basic allocation with brk works → You understand heap growth and the program break
  2. Free works with coalescing → You understand fragmentation and metadata management
  3. mmap for large allocations → You understand different memory mapping strategies
  4. Can run real programs → You’ve built something production-quality

Project 3: Process Scheduler Visualization Tool

  • File: TRACK_A_OS_KERNEL_PROJECTS.md
  • Programming Language: C
  • Coolness Level: Level 3: Genuinely Clever
  • Business Potential: 3. The “Service & Support” Model
  • Difficulty: Level 3: Advanced
  • Knowledge Area: OS Scheduler / Kernel Internals
  • Software or Tool: Linux Scheduler (CFS)
  • Main Book: “Linux Kernel Development” by Robert Love

What you’ll build: A tool that visualizes the Linux scheduler in real-time, showing which processes are running on which CPUs, context switches, runqueue depth, and scheduling decisions.

Why it teaches OS internals: The scheduler is the heart of the OS. By building a tool to observe it, you’ll learn how the kernel decides what runs, why processes get preempted, and how modern schedulers balance fairness with performance.

Core challenges you’ll face:

  • Reading scheduler data from /proc and tracefs (maps to kernel/user data interfaces)
  • Understanding CFS vruntime and load balancing (maps to scheduling algorithms)
  • Tracking context switches in real-time (maps to process lifecycle, interrupts)
  • Correlating CPU time with priority (maps to scheduler internals)
  • Visualizing multi-core scheduling (maps to SMP considerations)

Resources for key challenges:

  • “Operating Systems: Three Easy Pieces” Ch. 7-10 - Scheduling chapters
  • “Linux Kernel Development” by Robert Love Ch. 4 - CFS scheduler deep dive

Key Concepts:

  • Completely Fair Scheduler (CFS): “Linux Kernel Development” Ch. 4 - Robert Love
  • Process states and transitions: “Operating Systems: Three Easy Pieces” Ch. 4 - Arpaci-Dusseau
  • /proc filesystem: “The Linux Programming Interface” Ch. 12 - Michael Kerrisk
  • CPU affinity: “The Linux Programming Interface” Ch. 35 - Michael Kerrisk

Difficulty: Intermediate Time estimate: 2 weeks Prerequisites: C, understanding of basic scheduling concepts

Real world outcome:

  • Terminal UI showing real-time CPU utilization per core with process names
  • Timeline view showing context switches: [CPU0: nginx(1234) → postgres(5678) → nginx(1234)]
  • Statistics: context switches/sec, average time slice, runqueue depth
  • Can identify scheduling problems: “Process X is getting starved because…”

Learning milestones:

  1. Read and parse /proc/schedstat → You understand kernel-exported scheduler data
  2. Visualize context switches → You understand preemption and time slicing
  3. Track vruntime progression → You understand CFS fairness model
  4. Correlate with CPU affinity → You understand multi-core scheduling

Project 4: Page Fault Analyzer

  • File: TRACK_A_OS_KERNEL_PROJECTS.md
  • Programming Language: C
  • Coolness Level: Level 4: Hardcore Tech Flex
  • Business Potential: 3. The “Service & Support” Model
  • Difficulty: Level 4: Expert
  • Knowledge Area: Virtual Memory / Kernel Tracing
  • Software or Tool: perf_event_open
  • Main Book: “Operating Systems: Three Easy Pieces” by Arpaci-Dusseau

What you’ll build: A tool that monitors page faults in running programs, distinguishing major from minor faults, showing which virtual addresses faulted, and mapping faults to source code locations.

Why it teaches OS internals: Page faults are where virtual memory becomes real. By observing them, you’ll understand demand paging, copy-on-write, memory-mapped files, and why adding RAM sometimes doesn’t help performance.

Core challenges you’ll face:

  • Using perf_event_open() to capture page faults (maps to kernel tracing interfaces)
  • Distinguishing major vs minor faults (maps to page fault types, I/O)
  • Correlating fault addresses with memory regions from /proc/pid/maps (maps to virtual memory layout)
  • Understanding COW and lazy allocation (maps to memory optimization strategies)
  • Symbolizing addresses to function names (maps to debugging/profiling)

Resources for key challenges:

  • “Operating Systems: Three Easy Pieces” Ch. 21-23 - Virtual memory and paging
  • “Computer Systems: A Programmer’s Perspective” Ch. 9 - Virtual memory

Key Concepts:

  • Page fault handling: “Operating Systems: Three Easy Pieces” Ch. 21 - Arpaci-Dusseau
  • Memory mapping: “The Linux Programming Interface” Ch. 49 - Michael Kerrisk
  • perf_event_open: man page + kernel documentation
  • /proc/pid/maps format: “The Linux Programming Interface” Ch. 48 - Michael Kerrisk

Difficulty: Advanced Time estimate: 2-3 weeks Prerequisites: C, understanding of virtual memory basics

Real world outcome:

  • ./pagefault-analyzer ./my_program
  • Output shows: MINOR fault at 0x7fff5a2b3000 (stack growth), MAJOR fault at 0x400000 (loading code from disk)
  • Heat map of which memory regions cause the most faults
  • Can explain: “Your program has 10,000 major faults because it’s not pre-faulting the mmap’d file”

Learning milestones:

  1. Capture page faults with counts → You understand the basic fault mechanism
  2. Distinguish major/minor → You understand the role of disk I/O in paging
  3. Map to source regions → You understand address space layout in detail
  4. Give optimization advice → You can apply this knowledge to real performance problems

Project 5: Linux Kernel Module — Character Device Driver

  • File: TRACK_A_OS_KERNEL_PROJECTS.md
  • Programming Language: C
  • Coolness Level: Level 4: Hardcore Tech Flex
  • Business Potential: 3. The “Service & Support” Model
  • Difficulty: Level 4: Expert
  • Knowledge Area: Kernel Development / Drivers
  • Software or Tool: Linux Kernel Headers
  • Main Book: “Linux Device Drivers” by Corbet, Rubini, Kroah-Hartman

What you’ll build: A character device driver (/dev/mydevice) that implements a simple ring buffer in kernel space, accessible from userspace via read/write/ioctl.

Why it teaches OS internals: This is where you cross the boundary. You’ll write code that runs in kernel space, manage kernel memory, handle concurrent access, and understand why the kernel is designed the way it is.

Core challenges you’ll face:

  • Setting up kernel module build environment (maps to kernel build system)
  • Implementing file_operations (open, read, write, release, ioctl) (maps to VFS layer)
  • Managing kernel memory with kmalloc/kfree (maps to kernel memory management)
  • Handling concurrent access with spinlocks/mutexes (maps to OS-level locks)
  • Copying data between user and kernel space (maps to kernel/user boundary)
  • Debugging without crashing your system (maps to kernel debugging)

Resources for key challenges:

  • “Linux Device Drivers” by Corbet, Rubini, Kroah-Hartman (Ch. 3) - Character drivers
  • “Linux Kernel Development” by Robert Love - General kernel programming

Key Concepts:

  • Kernel modules: “Linux Device Drivers” Ch. 2 - Corbet et al.
  • Character devices: “Linux Device Drivers” Ch. 3 - Corbet et al.
  • Kernel memory allocation: “Linux Kernel Development” Ch. 12 - Robert Love
  • Kernel synchronization: “Linux Kernel Development” Ch. 10 - Robert Love
  • copy_to_user/copy_from_user: “Linux Device Drivers” Ch. 3 - Corbet et al.

Difficulty: Advanced Time estimate: 3-4 weeks Prerequisites: Strong C, completed at least one userspace project above, comfortable with system crashes

Real world outcome:

  • insmod mydriver.ko loads your module
  • echo "hello" > /dev/mydevice writes to kernel ring buffer
  • cat /dev/mydevice reads back (FIFO)
  • ./myctl --stats (via ioctl) shows buffer stats
  • Check dmesg for your kernel printk messages

Learning milestones:

  1. Module loads/unloads cleanly → You understand kernel module lifecycle
  2. Basic read/write works → You understand file_operations and the VFS
  3. Handle concurrent access → You understand kernel locking primitives
  4. ioctl implementation → You understand custom kernel-user interfaces
  5. Survives stress testing → You’ve written robust kernel code

Project 6: Userspace Thread Library (Green Threads)

  • File: TRACK_A_OS_KERNEL_PROJECTS.md
  • Programming Language: C / Assembly
  • Coolness Level: Level 5: Pure Magic (Super Cool)
  • Business Potential: 4. The “Open Core” Infrastructure
  • Difficulty: Level 5: Master
  • Knowledge Area: OS Architecture / Concurrency
  • Software or Tool: Context Switching
  • Main Book: “Operating Systems: Three Easy Pieces” by Arpaci-Dusseau

What you’ll build: A cooperative threading library that implements thread creation, yielding, and a round-robin scheduler, entirely in userspace without kernel thread support.

Why it teaches OS internals: By building your own scheduler and context switching, you’ll understand exactly what the kernel does thousands of times per second. The constraints of userspace threading also illuminate why kernel threads and preemption exist.

Core challenges you’ll face:

  • Saving and restoring CPU state (registers, stack pointer) (maps to context switching)
  • Allocating and managing per-thread stacks (maps to memory management)
  • Implementing a scheduler and run queue (maps to scheduling)
  • Making it work with blocking I/O (maps to understanding blocking vs non-blocking)
  • Signal handling with custom stacks (maps to interrupts, signals)

Resources for key challenges:

  • “Operating Systems: Three Easy Pieces” Ch. 26-28 - Concurrency introduction
  • “Computer Systems: A Programmer’s Perspective” Ch. 8 - Control flow

Key Concepts:

  • Context switching: “Operating Systems: Three Easy Pieces” Ch. 6 - Arpaci-Dusseau
  • setjmp/longjmp: “C Programming: A Modern Approach” Ch. 24 - K.N. King
  • Stack management: “Computer Systems: A Programmer’s Perspective” Ch. 3 - Bryant & O’Hallaron
  • Scheduling algorithms: “Operating Systems: Three Easy Pieces” Ch. 7-9 - Arpaci-Dusseau

Difficulty: Advanced Time estimate: 2-3 weeks Prerequisites: Strong C, assembly basics, understanding of calling conventions

Real world outcome:

thread_create(worker_function, arg);
thread_create(another_worker, arg2);
scheduler_run();  // Runs both, switching on yield()
  • Demo program with multiple threads printing interleaved output
  • Can implement a simple cooperative web server using your threads
  • Benchmark: show context switch overhead (nanoseconds)

Learning milestones:

  1. Basic context switch works → You understand what state defines a “thread”
  2. Multiple threads round-robin → You understand scheduling decisions
  3. Thread exit and cleanup → You understand resource management
  4. Works with real workloads → You’ve built something useful

Project 7: Interrupt Latency Profiler

  • File: TRACK_A_OS_KERNEL_PROJECTS.md
  • Programming Language: C
  • Coolness Level: Level 4: Hardcore Tech Flex
  • Business Potential: 3. The “Service & Support” Model
  • Difficulty: Level 4: Expert
  • Knowledge Area: OS Performance / Kernel
  • Software or Tool: ftrace / eBPF
  • Main Book: “Systems Performance” by Brendan Gregg

What you’ll build: A tool that measures and visualizes interrupt latency on your system, showing how long it takes from hardware interrupt to handler execution, and identifying sources of latency.

Why it teaches OS internals: Interrupts are how hardware talks to software. By measuring them, you’ll understand interrupt handlers, top/bottom halves, interrupt masking, and why real-time systems are hard.

Core challenges you’ll face:

  • Accessing interrupt statistics from /proc/interrupts (maps to interrupt subsystem)
  • Using ftrace to trace interrupt handlers (maps to kernel tracing)
  • Understanding IRQ affinity and distribution (maps to SMP interrupt handling)
  • Measuring time accurately at microsecond scale (maps to timekeeping)
  • Correlating latency spikes with system activity (maps to system analysis)

Key Concepts:

  • Interrupt handling: “Linux Kernel Development” Ch. 7 - Robert Love
  • Top/bottom halves: “Linux Kernel Development” Ch. 8 - Robert Love
  • ftrace: Kernel documentation + Steven Rostedt’s articles
  • /proc/interrupts: “Understanding the Linux Kernel” Ch. 4 - Bovet & Cesati

Difficulty: Advanced Time estimate: 2 weeks Prerequisites: Understanding of userspace profiling, basic kernel concepts

Real world outcome:

  • Real-time display: IRQ 16 (eth0): avg 2.3μs, max 150μs, count 45032/sec
  • Histogram of latencies per interrupt source
  • Alert when latency exceeds threshold
  • Can diagnose: “Your network latency spikes happen when IRQ 16 and IRQ 18 hit the same CPU”

Learning milestones:

  1. Parse /proc/interrupts → You understand interrupt accounting
  2. Trace with ftrace → You understand kernel tracing infrastructure
  3. Measure latencies accurately → You understand timekeeping challenges
  4. Correlate with system events → You can debug real interrupt issues

Project Comparison Table

Project Difficulty Time Depth of Understanding Fun Factor Topics Covered
Syscall Tracer Intermediate 2-3 weeks ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ Syscalls, process lifecycle, kernel/user boundary
Memory Allocator Intermediate 2-3 weeks ⭐⭐⭐⭐ ⭐⭐⭐ Virtual memory, page faults, syscalls
Scheduler Visualizer Intermediate 2 weeks ⭐⭐⭐ ⭐⭐⭐⭐ Scheduling, process lifecycle
Page Fault Analyzer Advanced 2-3 weeks ⭐⭐⭐⭐⭐ ⭐⭐⭐ Virtual memory, page faults
Kernel Module Advanced 3-4 weeks ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ Device drivers, locks, kernel/user boundary
Thread Library Advanced 2-3 weeks ⭐⭐⭐⭐ ⭐⭐⭐⭐ Scheduling, locks, process lifecycle
Interrupt Profiler Advanced 2 weeks ⭐⭐⭐⭐ ⭐⭐⭐ Interrupts, scheduling

Given this is “hard mode,” here’s the progression I recommend:

Phase 1: Observe the Kernel from Outside (Weeks 1-5)

  1. Syscall Tracer - Start here. It’s the best way to see the kernel/user boundary without writing kernel code.
  2. Memory Allocator - Builds on syscall knowledge, teaches virtual memory deeply.

Phase 2: Understand Scheduling and Concurrency (Weeks 6-9)

  1. Thread Library - Forces you to implement what the scheduler does.
  2. Scheduler Visualizer - Now observe the real kernel scheduler with informed eyes.

Phase 3: Cross into Kernel Space (Weeks 10-15)

  1. Kernel Module - The real thing. Everything before this was preparation.
  2. Page Fault Analyzer - Combines userspace tooling with deep kernel knowledge.
  3. Interrupt Profiler - Capstone project tying it all together.

Final Comprehensive Project: Mini Operating System Kernel

What you’ll build: A minimal operating system that boots on real hardware (or QEMU), implements protected mode, basic virtual memory with paging, a simple process model with context switching, a basic syscall interface, and a simple shell.

Why this is the ultimate project: This synthesizes everything. You can’t fake understanding when you’re writing the code that sets up page tables, handles interrupts, and switches between processes.

Core challenges you’ll face:

  • Bootloader and protected mode setup (maps to hardware initialization)
  • Setting up GDT, IDT, TSS (maps to x86 architecture)
  • Implementing paging and virtual memory (maps to virtual memory internals)
  • Writing interrupt handlers (maps to interrupts)
  • Implementing basic syscalls (maps to syscall paths, kernel/user boundary)
  • Context switching between processes (maps to scheduling, process lifecycle)
  • Basic device drivers (keyboard, screen) (maps to device drivers)
  • Kernel synchronization primitives (maps to OS-level locks)

Resources for key challenges:

  • “Operating Systems: Three Easy Pieces” - Conceptual foundation
  • OSDev Wiki (wiki.osdev.org) - Practical x86 OS development
  • “Computer Systems: A Programmer’s Perspective” Ch. 9 - Virtual memory implementation
  • James Molloy’s kernel tutorials - Step-by-step x86 kernel

Key Concepts:

  • x86 protected mode: OSDev Wiki + Intel manuals
  • Paging setup: “Operating Systems: Three Easy Pieces” Ch. 18-20 - Arpaci-Dusseau
  • Interrupt Descriptor Table: “Computer Systems: A Programmer’s Perspective” Ch. 8 - Bryant & O’Hallaron
  • Context switching: “Operating Systems: Three Easy Pieces” Ch. 6 - Arpaci-Dusseau
  • System call implementation: “The Linux Programming Interface” Ch. 3 - Michael Kerrisk (for design)

Difficulty: Expert Time estimate: 2-3 months Prerequisites: All projects above, x86 assembly, strong C, patience

Real world outcome:

  • Boot your OS in QEMU: qemu-system-i386 -kernel myos.bin
  • See your kernel print “MyOS v0.1”
  • Type commands in your shell
  • Run multiple processes that time-slice
  • ps shows running processes with PIDs
  • mem shows memory map with page table info
  • Handle a page fault gracefully (not crash)

Learning milestones:

  1. Boot to protected mode → You understand x86 boot process
  2. Paging works, can map/unmap pages → You understand virtual memory at the hardware level
  3. Keyboard interrupt works → You understand interrupt handling
  4. Two processes context switch → You understand scheduling at the deepest level
  5. Syscalls work → You understand the complete kernel/user boundary
  6. Shell runs user programs → You’ve built an operating system

Final Notes

Why this order matters: Each project builds mental models that the next project requires. The syscall tracer shows you the boundary; the allocator makes you use it; the thread library makes you implement scheduling; the kernel module puts you on the other side; and the mini-OS makes you build the whole thing.

The reality check from your curriculum is accurate: This path has the highest prestige and highest difficulty. The jobs are fewer but they’re the jobs that really matter—kernel teams at Linux distros, hypervisor teams at VMware/AWS/Google, OS teams at Apple/Microsoft, embedded systems, and security research.

Strong OSS signaling: Every one of these projects can go on GitHub. A working strace clone or kernel module demonstrates skills that can’t be faked in an interview.

Start with the syscall tracer. When you can explain every line of output from strace ls, you’re ready for the rest.