xv6-riscv Reading Order
Use separate reading tracks. Do not mix kernel files, user programs, and mkfs into one giant list.
The clean mental model is:
Makefile
↓
kernel/ builds the OS kernel
↓
user/ builds xv6 user programs
↓
mkfs/ builds fs.img using those user programs
↓
QEMU boots kernel + fs.img1. Start with the build pipeline
Read this first to understand how everything connects.
| Order | File | Kind | Purpose |
|---|---|---|---|
| 1 | Makefile | Build file | Builds kernel, user programs, mkfs, fs.img, and runs QEMU. |
2. Kernel reading order
These files explain how the xv6 kernel itself works.
Kernel reading order with generated object files
These are the kernel source files and the object files they generate for the Makefile OBJS list.
| Order | File | Generated object | Kind | Purpose |
|---|---|---|---|---|
| 1 | kernel/types.h | — | Header | Basic integer/type aliases. |
| 2 | kernel/param.h | — | Header | Kernel-wide size limits. |
| 3 | kernel/memlayout.h | — | Header | Physical/virtual memory map. |
| 4 | kernel/riscv.h | — | Header | RISC-V registers, paging, interrupt helpers. |
| 5 | kernel/defs.h | — | Header | Cross-file kernel declarations. |
| 6 | kernel/kernel.ld | — | Linker script | Kernel memory layout at link time. |
| 7 | kernel/entry.S | kernel/entry.o | Assembly | First code after QEMU jump. |
| 8 | kernel/start.c | kernel/start.o | C | Early CPU setup before main. |
| 9 | kernel/main.c | kernel/main.o | C | Kernel initialization order. |
| 10 | kernel/spinlock.h | — | Header | Spinlock structure. |
| 11 | kernel/spinlock.c | kernel/spinlock.o | C | Short critical-section locking. |
| 12 | kernel/printf.c | kernel/printf.o | C | Kernel printing and panic. |
| 13 | kernel/string.c | kernel/string.o | C | Basic memory/string helpers. |
| 14 | kernel/kalloc.c | kernel/kalloc.o | C | Physical page allocator. |
| 15 | kernel/vm.h | — | Header | sbrk allocation mode constants. |
| 16 | kernel/vm.c | kernel/vm.o | C | Page tables and virtual memory. |
| 17 | kernel/proc.h | — | Header | Process, CPU, trapframe structures. |
| 18 | kernel/proc.c | kernel/proc.o | C | Processes, scheduling, sleep/wakeup. |
| 19 | kernel/swtch.S | kernel/swtch.o | Assembly | Low-level context switch. |
| 20 | kernel/trampoline.S | kernel/trampoline.o | Assembly | User/kernel trap transition code. |
| 21 | kernel/kernelvec.S | kernel/kernelvec.o | Assembly | Kernel-mode trap vector. |
| 22 | kernel/trap.c | kernel/trap.o | C | Trap, syscall, interrupt handling. |
| 23 | kernel/syscall.h | — | Header | Syscall number definitions. |
| 24 | kernel/syscall.c | kernel/syscall.o | C | Syscall dispatch and argument fetching. |
| 25 | kernel/sysproc.c | kernel/sysproc.o | C | Process-related syscalls. |
| 26 | kernel/uart.c | kernel/uart.o | C | Low-level serial device driver. |
| 27 | kernel/console.c | kernel/console.o | C | Console input/output layer. |
| 28 | kernel/plic.c | kernel/plic.o | C | External interrupt controller. |
| 29 | kernel/virtio.h | — | Header | Virtio disk protocol definitions. |
| 30 | kernel/virtio_disk.c | kernel/virtio_disk.o | C | Virtual disk driver. |
| 31 | kernel/buf.h | — | Header | Disk buffer structure. |
| 32 | kernel/bio.c | kernel/bio.o | C | Buffer cache and LRU block reuse. |
| 33 | kernel/fs.h | — | Header | On-disk filesystem format. |
| 34 | kernel/sleeplock.h | — | Header | Sleeping lock structure. |
| 35 | kernel/sleeplock.c | kernel/sleeplock.o | C | Locks that sleep while waiting. |
| 36 | kernel/file.h | — | Header | In-memory file/inode/device structs. |
| 37 | kernel/fs.c | kernel/fs.o | C | Inodes, directories, path lookup. |
| 38 | kernel/log.c | kernel/log.o | C | Filesystem transaction log. |
| 39 | kernel/file.c | kernel/file.o | C | Open-file table and file operations. |
| 40 | kernel/fcntl.h | — | Header | File open flags. |
| 41 | kernel/stat.h | — | Header | File metadata structure. |
| 42 | kernel/sysfile.c | kernel/sysfile.o | C | File-related syscalls. |
| 43 | kernel/pipe.c | kernel/pipe.o | C | Pipes for process communication. |
| 44 | kernel/elf.h | — | Header | ELF executable file format. |
| 45 | kernel/exec.c | kernel/exec.o | C | Load and run user programs. |
| Order | File | Kind | Purpose |
|---|---|---|---|
| 1 | kernel/types.h | Header | Basic integer/type aliases. |
| 2 | kernel/param.h | Header | Kernel-wide size limits. |
| 3 | kernel/memlayout.h | Header | Physical/virtual memory map. |
| 4 | kernel/riscv.h | Header | RISC-V registers, paging, interrupt helpers. |
| 5 | kernel/defs.h | Header | Cross-file kernel declarations. |
| 6 | kernel/kernel.ld | Linker script | Kernel memory layout at link time. |
| 7 | kernel/entry.S | Assembly | First code after QEMU jump. |
| 8 | kernel/start.c | C | Early CPU setup before main. |
| 9 | kernel/main.c | C | Kernel initialization order. |
| 10 | kernel/spinlock.h | Header | Spinlock structure. |
| 11 | kernel/spinlock.c | C | Short critical-section locking. |
| 12 | kernel/printf.c | C | Kernel printing and panic. |
| 13 | kernel/string.c | C | Basic memory/string helpers. |
| 14 | kernel/kalloc.c | C | Physical page allocator. |
| 15 | kernel/vm.h | Header | sbrk allocation mode constants. |
| 16 | kernel/vm.c | C | Page tables and virtual memory. |
| 17 | kernel/proc.h | Header | Process, CPU, trapframe structures. |
| 18 | kernel/proc.c | C | Processes, scheduling, sleep/wakeup. |
| 19 | kernel/swtch.S | Assembly | Low-level context switch. |
| 20 | kernel/trampoline.S | Assembly | User/kernel trap transition code. |
| 21 | kernel/kernelvec.S | Assembly | Kernel-mode trap vector. |
| 22 | kernel/trap.c | C | Trap, syscall, interrupt handling. |
| 23 | kernel/syscall.h | Header | Syscall number definitions. |
| 24 | kernel/syscall.c | C | Syscall dispatch and argument fetching. |
| 25 | kernel/sysproc.c | C | Process-related syscalls. |
| 26 | kernel/uart.c | C | Low-level serial device driver. |
| 27 | kernel/console.c | C | Console input/output layer. |
| 28 | kernel/plic.c | C | External interrupt controller. |
| 29 | kernel/virtio.h | Header | Virtio disk protocol definitions. |
| 30 | kernel/virtio_disk.c | C | Virtual disk driver. |
| 31 | kernel/buf.h | Header | Disk buffer structure. |
| 32 | kernel/bio.c | C | Buffer cache and LRU block reuse. |
| 33 | kernel/fs.h | Header | On-disk filesystem format. |
| 34 | kernel/sleeplock.h | Header | Sleeping lock structure. |
| 35 | kernel/sleeplock.c | C | Locks that sleep while waiting. |
| 36 | kernel/file.h | Header | In-memory file/inode/device structs. |
| 37 | kernel/fs.c | C | Inodes, directories, path lookup. |
| 38 | kernel/log.c | C | Filesystem transaction log. |
| 39 | kernel/file.c | C | Open-file table and file operations. |
| 40 | kernel/fcntl.h | Header | File open flags. |
| 41 | kernel/stat.h | Header | File metadata structure. |
| 42 | kernel/sysfile.c | C | File-related syscalls. |
| 43 | kernel/pipe.c | C | Pipes for process communication. |
| 44 | kernel/elf.h | Header | ELF executable file format. |
| 45 | kernel/exec.c | C | Load and run user programs. |
3. User-space support reading order
These files are not the kernel. They are the tiny user-space runtime that xv6 programs use.
| Order | File | Kind | Purpose |
|---|---|---|---|
| 1 | user/user.h | Header | User-visible syscall and library declarations. |
| 2 | user/usys.pl | Generator | Generates user syscall stubs. |
| 3 | user/usys.S | Generated assembly | User-side syscall wrappers using ecall. |
| 4 | user/ulib.c | User library | Basic user-space helper functions. |
| 5 | user/printf.c | User library | User-space formatted printing. |
| 6 | user/umalloc.c | User library | Simple user-space memory allocator. |
Syscall path:
user program
↓
user/usys.S
↓
ecall
↓
kernel/trampoline.S
↓
kernel/trap.c
↓
kernel/syscall.c
↓
kernel/sysproc.c or kernel/sysfile.c4. User program reading order
These are actual programs that run inside xv6.
| Order | File | Kind | Purpose |
|---|---|---|---|
| 1 | user/init.c | User program | First user process. |
| 2 | user/sh.c | User program | xv6 shell. |
| 3 | user/ls.c | User program | List directory contents. |
| 4 | user/cat.c | User program | Print file contents. |
| 5 | user/echo.c | User program | Print arguments. |
| 6 | user/grep.c | User program | Search text. |
| 7 | user/wc.c | User program | Count lines, words, bytes. |
| 8 | user/mkdir.c | User program | Create directories. |
| 9 | user/rm.c | User program | Remove files. |
| 10 | user/ln.c | User program | Create hard links. |
| 11 | user/kill.c | User program | Kill a process. |
| 12 | user/stressfs.c | Test program | Stress filesystem behavior. |
| 13 | user/forktest.c | Test program | Stress process creation. |
| 14 | user/grind.c | Test program | Stress processes/filesystem/concurrency. |
| 15 | user/usertests.c | Test program | Broad xv6 test suite. |
Minimum useful order:
user/init.c
↓
user/sh.c
↓
user/ls.c
↓
user/cat.c5. mkfs and filesystem image creation
mkfs is not kernel code and not an xv6 user program.
It is a host-side tool that runs on your laptop before xv6 boots.
| Order | File / Artifact | Kind | Purpose |
|---|---|---|---|
| 1 | kernel/fs.h | Shared format header | Defines xv6 on-disk filesystem layout. |
| 2 | mkfs/mkfs.c | Host tool | Creates fs.img using xv6 filesystem format. |
| 3 | user/_init, user/_sh, etc. | RISC-V binaries | Compiled user programs inserted into fs.img. |
| 4 | fs.img | Disk image | Virtual disk passed to xv6 by QEMU. |
Important distinction:
mkfs/mkfs.c → compiled for the host machine
user programs → compiled for RISC-V
fs.img → raw disk image in xv6 filesystem formatBuild flow:
user/init.c
↓
user/_init
user/sh.c
↓
user/_sh
mkfs/mkfs.c
↓
mkfs/mkfs
mkfs/mkfs README user/_init user/_sh ...
↓
fs.img6. Full build-to-boot pipeline
| Order | Step | Runs where? | Purpose |
|---|---|---|---|
| 1 | Makefile | Host | Coordinates the build. |
| 2 | Build kernel files | Host cross-compiler | Produces kernel/kernel. |
| 3 | Build user support files | Host cross-compiler | Produces user runtime objects. |
| 4 | Build user programs | Host cross-compiler | Produces user/_init, user/_sh, etc. |
| 5 | Build mkfs/mkfs.c | Host compiler | Produces host executable mkfs/mkfs. |
| 6 | Run mkfs/mkfs | Host | Packs user binaries into fs.img. |
| 7 | Start QEMU | Host | Creates virtual RISC-V machine. |
| 8 | Run kernel/kernel | QEMU/RISC-V | Boots xv6 kernel. |
| 9 | Run /init | xv6 user mode | Starts first user process. |
| 10 | Run /sh | xv6 user mode | Starts shell. |
Runtime flow:
QEMU
↓
kernel/entry.S
↓
kernel/start.c
↓
kernel/main.c
↓
disk + filesystem init
↓
kernel/exec.c loads /init
↓
user/init.c starts /sh
↓
user/sh.c runs commands7. Mental grouping
| Group | Files |
|---|---|
| Build system | Makefile |
| Kernel | kernel/* |
| User runtime | user/user.h, user/usys.pl, user/usys.S, user/ulib.c, user/printf.c, user/umalloc.c |
| User programs | user/init.c, user/sh.c, user/ls.c, user/cat.c, etc. |
| Filesystem image builder | mkfs/mkfs.c |
| Disk image | fs.img |
Final mental model:
kernel/ = the operating system
user/ = programs that run inside the operating system
mkfs/ = host tool that creates the xv6 disk image
fs.img = virtual disk containing user programs
QEMU = fake RISC-V machine that runs xv6