xv6-riscv User and Kernel Source Architecture

A readable map of how files in user/ and kernel/ work together, from building user programs to entering the kernel through traps and system calls.

Architecture

xv6 source architecture diagram User programs call library code and syscall stubs, enter the kernel through traps, and use kernel subsystems that talk to devices and the file system image. User space: user/ Programs sh, init, cat, ls, grep, tests... User support library ulib.c, printf.c, umalloc.c, user.h System call stubs usys.pl generates usys.S with ecall user.ld links each _program binary Kernel space: kernel/ Boot and init entry.S, start.c, main.c Trap path trap.c, trampoline.S System calls syscall.c, sysproc.c, sysfile.c Processes proc.c, swtch.S, proc.h Memory vm.c, kalloc.c, riscv.h Files and pipes file.c, fs.c, pipe.c, log.c Shared headers: defs.h, types.h, param.h, memlayout.h Devices UART console PLIC interrupts VirtIO disk Build image Makefile mkfs/mkfs.c ecall trap

Source layers

User interface

Programs in user/ are the visible xv6 commands and tests. They rely on the user library and generated syscall stubs instead of linking against kernel code.

API documentation

The API index lists kernel routines, user library calls, system-call handlers, and user commands with direct links to their implementation.

Kernel boundary

trampoline.S, trap.c, and syscall.c turn traps into calls to process, memory, and file-system services.

Kernel services

Process scheduling, virtual memory, files, pipes, logging, and device drivers are linked into one supervisor-mode image and share contracts through headers such as defs.h.

Build image

The build flow links the kernel, links each user program, and uses mkfs to create the disk image mounted by the running kernel.

Runtime

User program

Code such as sh.c, cat.c, or ls.c calls functions declared in user.h.

→

Library and stub

ulib.c wraps helpers. usys.S, generated by usys.pl, loads a syscall number into a7 and runs ecall.

→

Trap and dispatch

trampoline.S and trap.c move into kernel mode. syscall.c dispatches to sysproc.c or sysfile.c.

→

Kernel service

Process, memory, file system, and driver code perform the request, then the return value is placed in the user trap frame.

System Calls

User programs enter the kernel through these xv6 system calls. The list follows Figure 1.2 in the xv6 guide.

System call Description Implementation path
int fork()Create a child process and return its PID to the parent.sys_fork in sysproc.c calls kfork in proc.c.
int exit(int status)Terminate the current process and report a status to wait.sys_exit in sysproc.c calls kexit in proc.c.
int wait(int *status)Wait for a child process to exit and return the child's PID.sys_wait in sysproc.c calls kwait in proc.c.
int kill(int pid)Mark a process so it exits when it next returns to user space.sys_kill in sysproc.c calls kkill in proc.c.
int getpid()Return the current process ID.sys_getpid in sysproc.c reads the current process through myproc.
int pause(int n)Pause the process for n clock ticks.sys_pause in sysproc.c waits on timer ticks advanced by trap.c.
int uptime()Return the number of clock ticks since boot.sys_uptime in sysproc.c reads timer ticks maintained by trap.c.
int exec(char *file, char *argv[])Replace the current process image with a program loaded from a file.sys_exec in sysfile.c calls kexec in exec.c.
char *sbrk(int n)Grow the process heap and return the previous heap end.sys_sbrk in sysproc.c grows process memory through growproc and uvmalloc.
int open(char *file, int flags)Open a path and return a file descriptor.sys_open in sysfile.c allocates file descriptors and opens inodes through namei.
int write(int fd, char *buf, int n)Write bytes from a user buffer to a file descriptor.sys_write in sysfile.c calls filewrite in file.c.
int read(int fd, char *buf, int n)Read bytes from a file descriptor into a user buffer.sys_read in sysfile.c calls fileread in file.c.
int close(int fd)Release an open file descriptor.sys_close in sysfile.c closes descriptor references through fileclose.
int dup(int fd)Return another descriptor for the same open file.sys_dup in sysfile.c duplicates descriptor references through filedup.
int pipe(int p[])Create paired read and write file descriptors for a pipe.sys_pipe in sysfile.c allocates pipe endpoints through pipealloc.
int chdir(char *dir)Change the current working directory.sys_chdir in sysfile.c resolves the path through namei and updates the process directory.
int mkdir(char *dir)Create a directory.sys_mkdir in sysfile.c creates a directory inode through create.
int mknod(char *file, int, int)Create a device file.sys_mknod in sysfile.c creates a device inode through create.
int fstat(int fd, struct stat *st)Copy metadata for an open file into a user stat structure.sys_fstat in sysfile.c calls filestat in file.c.
int link(char *file1, char *file2)Add another directory entry for an existing file.sys_link in sysfile.c updates inode links and directories through dirlink.
int unlink(char *file)Remove a directory entry.sys_unlink in sysfile.c resolves the parent directory through nameiparent.

Build and Image Tools

Makefile

Builds kernel objects into kernel/kernel, builds each user program as user/_name, and packages programs into fs.img.

User binaries

User programs link with ulib.o, usys.o, printf.o, umalloc.o, and user.ld.

mkfs/mkfs.c

Creates the xv6 file system image and inserts README plus the compiled user binaries.

Kernel image

Kernel C and assembly files link with kernel.ld. QEMU boots this image directly with -kernel kernel/kernel.

QEMU devices

The Makefile attaches fs.img as a VirtIO block device and uses UART for console I/O.

User Source

Files in user/ either become runnable xv6 programs or provide the small user-space library linked into those programs. Click any file name to open a highlighted source page.

File Use Relationships
cat.cPrints file or standard input contents.program Uses read, write, open, close.
echo.cWrites command-line arguments to standard output.program Uses write through printf.
forktest.cStress test for process creation limits.test Links with a smaller library set in the Makefile.
grep.cSearches input for lines matching a simple pattern.program Uses file syscalls and user library string helpers.
init.cFirst user process; opens the console and starts the shell.boot userland Created by userinit through exec.
kill.cSends kill requests to process IDs.program Calls kill.
ln.cCreates hard links.program Calls link.
ls.cLists file and directory metadata.program Uses open, read, fstat, and stat.
mkdir.cCreates directories.program Calls mkdir.
rm.cRemoves directory entries.program Calls unlink.
sh.cInteractive shell with command parsing, pipes, redirection, and background jobs.program Heavily uses fork, exec, pipe, dup, wait.
stressfs.cSimple file system stress program.test Exercises file creation, writing, reading, and process scheduling.
logstress.cStress test for logging and file-system transactions.test Targets log.c, fs.c, and disk writes.
usertests.cMain xv6 regression test suite.test Exercises syscalls, VM, file system, pipes, and process behavior.
grind.cRandomized stress test for process and file-system operations.test Combines fork, file, pipe, and exec paths.
wc.cCounts lines, words, and bytes.program Uses file read loops and simple parsing.
zombie.cCreates a zombie process for testing process state handling.test Uses fork and exits without immediate wait.
forphan.cCreates orphaned processes for process reparenting tests.test Exercises parent exit and child cleanup.
dorphan.cDirectory-related orphan process test.test Exercises process lifecycle while touching file-system paths.
printf.cUser-space formatted output.library Sends formatted bytes to file descriptors with write.
ulib.cSmall C library: strings, memory, input, stat, and sbrk helpers.library Linked into most user programs through ULIB.
umalloc.cUser-space heap allocator.library Gets heap space through sbrk and serves malloc/free.
user.hUser-space declarations for syscalls and library functions.header Included by programs and library files.
usys.plGenerates assembly syscall stubs.generator Produces usys.S, which becomes usys.o.
user.ldLinker script for user programs.linker Controls user binary layout used by exec.c.

Kernel Source

Files in kernel/ are linked into one supervisor-mode kernel image. Headers define the shared contracts between subsystems. Click any file name to open a highlighted source page.

Boot, Traps, and System Calls

FileUseRelationships
entry.SEarliest machine-mode entry point.Sets up the initial stack and transfers to start.c.
start.cMachine-mode setup before entering supervisor mode.Configures timer interrupts and jumps to main.c.
main.cKernel initialization sequence.Initializes console, memory, process table, traps, file system, devices, and scheduler.
kernel.ldKernel linker script.Places text, data, trampoline, and kernel symbols for boot.
kernelvec.SKernel-mode trap vector assembly.Saves registers and calls kernel trap handling in trap.c.
trampoline.SPage shared by user and kernel for user trap entry/return.Switches page tables and saves/restores user registers through trap frames.
trap.cHandles traps, interrupts, and returns to user mode.Calls syscall.c, device interrupt handlers, and scheduler yield paths.
syscall.cDecodes syscall numbers and dispatches handlers.Uses syscall.h; calls handlers in sysproc.c and sysfile.c.
syscall.hSyscall number definitions.Included by generated user stubs and kernel dispatch code.
sysproc.cProcess and memory syscall handlers.Wraps proc.c, vm.c, and timer functions for user calls.
sysfile.cFile-system syscall handlers.Wraps file.c, fs.c, pipe.c, and log transactions.

Processes, Scheduling, and Memory

FileUseRelationships
proc.cProcess table, fork, exit, wait, sleep, wakeup, and scheduler.Uses vm.c for address spaces, swtch.S for context switches, and trap.c for user return.
proc.hCPU, process, context, and trapframe structures.Included by process, trap, syscall, and VM code.
swtch.SLow-level context switch routine.Saves and restores kernel registers for scheduler switches.
vm.cKernel and user virtual memory management.Maps pages, copies user memory, handles page faults, and works with kalloc.c.
vm.hPage-table type aliases and helpers.Shared by VM and process code.
kalloc.cPhysical page allocator.Supplies pages for page tables, user memory, kernel stacks, and buffers.
memlayout.hPhysical and virtual memory layout constants.Used by boot, VM, device, and trap code.
riscv.hRISC-V registers, page-table flags, and inline assembly helpers.Used throughout low-level kernel code.

File System, Files, Pipes, and Exec

FileUseRelationships
exec.cLoads ELF user programs into a process address space.Reads inodes through fs.c, builds user memory with vm.c, and uses elf.h.
elf.hELF executable format structures.Used by exec.c to parse user binaries.
file.cOpen file table and file descriptor operations.Connects syscalls to inodes, pipes, and device files.
file.hOpen file, inode, and device switch structures.Shared by file, fs, pipe, and syscall code.
fcntl.hOpen flag constants.Shared with user programs through includes.
fs.cInode, directory, block mapping, and path-name logic.Uses buffer cache, log, and disk blocks; called by file and exec code.
fs.hOn-disk file-system layout structures.Shared with mkfs/mkfs.c so images match the kernel format.
bio.cBuffer cache for disk blocks.Uses virtio_disk.c for actual I/O and is used by fs/log code.
buf.hBuffer cache structure definition.Shared by bio, log, fs, and disk driver code.
log.cSimple write-ahead log for file-system updates.Coordinates transactional writes from file-system syscalls.
pipe.cKernel pipe implementation.Provides file-like read/write endpoints for pipe syscalls.
stat.hFile metadata structure.Shared with user space for fstat and stat.

Devices, Locks, and Utilities

FileUseRelationships
console.cConsole input/output device.Uses UART, provides consoleread/consolewrite through the device switch.
uart.cUART serial driver.Backs console output/input and handles UART interrupts.
plic.cPlatform-Level Interrupt Controller setup.Routes external interrupts from UART and VirtIO to trap handling.
virtio_disk.cVirtIO block device driver.Reads and writes disk blocks for the buffer cache.
virtio.hVirtIO MMIO and descriptor definitions.Used by virtio_disk.c.
spinlock.cSpinlock implementation for short critical sections.Used across process, buffer, file, device, and memory code.
spinlock.hSpinlock structure definition.Included by code that embeds or manipulates spinlocks.
sleeplock.cSleepable locks for longer disk/inode operations.Used mainly by inode and buffer-related file-system paths.
sleeplock.hSleeplock structure definition.Included by file-system structures.
printf.cKernel formatted printing and panic.Outputs through console/UART and supports diagnostics.
string.cKernel string and memory routines.Used by many kernel subsystems because the kernel is freestanding.
defs.hCross-file kernel function declarations.Main internal API header connecting kernel subsystems.
types.hBasic integer and page-table types.Included broadly by both kernel and user-facing headers.
param.hKernel size limits and constants.Defines limits such as process count, file counts, and log size.