API map
├── Small Unix-like kernel
│ ├── Processes and scheduler
│ ├── Context switching
│ ├── Virtual memory
│ ├── Traps and interrupts
│ ├── System-call dispatcher
│ ├── File descriptors
│ ├── Pipes
│ ├── File system and log
│ ├── Locks
│ ├── Device drivers
│ └── String and memory
├── Small user-space C library
│ ├── String and memory
│ │ ├── strlen()
│ │ ├── strcpy()
│ │ ├── strcmp()
│ │ ├── memset()
│ │ ├── memmove()
│ │ ├── memcpy()
│ │ └── memcmp()
│ ├── Input and output
│ │ ├── printf()
│ │ ├── fprintf()
│ │ └── gets()
│ ├── Memory allocation
│ │ ├── malloc()
│ │ ├── free()
│ │ ├── sbrk()
│ │ └── sbrklazy()
│ └── Utilities
│ ├── atoi()
│ ├── stat()
│ └── strchr()
├── 21 Unix-like system calls
│ ├── Process
│ │ ├── fork()
│ │ ├── exit()
│ │ ├── wait()
│ │ ├── kill()
│ │ ├── exec()
│ │ └── getpid()
│ ├── Memory and time
│ │ ├── sbrk()
│ │ ├── pause()
│ │ └── uptime()
│ ├── File descriptors
│ │ ├── pipe()
│ │ ├── read()
│ │ ├── fstat()
│ │ ├── dup()
│ │ ├── write()
│ │ └── close()
│ └── File system
│ ├── chdir()
│ ├── open()
│ ├── mknod()
│ ├── unlink()
│ ├── link()
│ └── mkdir()
├── Small Unix user environment
│ └── Commands and tests
│ ├── init
│ ├── sh
│ ├── cat
│ ├── echo
│ ├── grep
│ ├── ls
│ ├── wc
│ ├── mkdir
│ ├── rm
│ ├── ln
│ └── test programs
└── Header guide
├── Function declarations
│ ├── kernel/defs.h
│ └── user/user.h
├── Inline functions
│ └── kernel/riscv.h
├── Types and structs
│ ├── kernel/types.h
│ ├── kernel/proc.h
│ ├── kernel/file.h
│ ├── kernel/fs.h
│ ├── kernel/buf.h
│ ├── kernel/spinlock.h
│ ├── kernel/sleeplock.h
│ ├── kernel/elf.h
│ ├── kernel/virtio.h
│ └── kernel/vm.h
├── Constants and macros
│ ├── kernel/param.h
│ ├── kernel/memlayout.h
│ ├── kernel/syscall.h
│ └── kernel/fcntl.h
└── ABI shared with user space
└── kernel/stat.hHeader guide
Small Unix-like Kernel
Generated from kernel/defs.h; each entry links to the
implementation when one exists in the checked-in source.
Processes and scheduler
| Declaration | Header | Description |
|---|---|---|
int kexec(char*, char**); | kernel/defs.h:26 | Replace the current process image with an ELF program. |
int cpuid(void); | kernel/defs.h:81 | Return the current hart's CPU index. |
void kexit(int); | kernel/defs.h:82 | Terminate the current process and wake its parent. |
int kfork(void); | kernel/defs.h:83 | Create a child process by copying the current process. |
int growproc(int); | kernel/defs.h:84 | Grow or shrink the current process address space. |
void proc_mapstacks(pagetable_t); | kernel/defs.h:85 | Map fixed kernel stacks for every process slot. |
pagetable_t proc_pagetable(struct proc *); | kernel/defs.h:86 | Create a user page table with trampoline mappings. |
void proc_freepagetable(pagetable_t, uint64); | kernel/defs.h:87 | Free a process page table and its user pages. |
int kkill(int); | kernel/defs.h:88 | Mark a process so it exits when it next reaches user mode. |
int killed(struct proc*); | kernel/defs.h:89 | Report whether a process has been marked for termination. |
void setkilled(struct proc*); | kernel/defs.h:90 | Set a process's killed flag. |
struct cpu* mycpu(void); | kernel/defs.h:91 | Return the current CPU structure. |
struct proc* myproc(); | kernel/defs.h:92 | Return the process running on the current CPU. |
void procinit(void); | kernel/defs.h:93 | Initialize process table locks and kernel stacks. |
void scheduler(void) __attribute__((noreturn)); | kernel/defs.h:94 | Run the per-CPU process scheduling loop. |
void sched(void); | kernel/defs.h:95 | Switch from the current process to the scheduler. |
void sleep(void*, struct spinlock*); | kernel/defs.h:96 | Atomically sleep on a channel while releasing a lock. |
void userinit(void); | kernel/defs.h:97 | Create the first user process. |
int kwait(uint64); | kernel/defs.h:98 | Wait for a child process to exit and collect its status. |
void wakeup(void*); | kernel/defs.h:99 | Wake processes sleeping on a channel. |
void yield(void); | kernel/defs.h:100 | Give up the CPU and become runnable again. |
int either_copyout(int user_dst, uint64 dst, void *src, uint64 len); | kernel/defs.h:101 | Copy to either user memory or kernel memory. |
int either_copyin(void *dst, int user_src, uint64 src, uint64 len); | kernel/defs.h:102 | Copy from either user memory or kernel memory. |
void procdump(void); | kernel/defs.h:103 | Print a process table snapshot for debugging. |
Context switching
| Declaration | Header | Description |
|---|---|---|
void swtch(struct context*, struct context*); | kernel/defs.h:106 | Save one kernel context and restore another. |
Virtual memory
Traps and interrupts
| Declaration | Header | Description |
|---|---|---|
void trapinit(void); | kernel/defs.h:141 | Initialize global trap handling state. |
void trapinithart(void); | kernel/defs.h:142 | Install the kernel trap vector on the current hart. |
void prepare_return(void); | kernel/defs.h:144 | Prepare trapframe and registers for return to user mode. |
System-call dispatcher
| Declaration | Header | Description |
|---|---|---|
void argint(int, int*); | kernel/defs.h:132 | Read an integer syscall argument from the current trapframe. |
int argstr(int, char*, int); | kernel/defs.h:133 | Copy a string syscall argument from user memory. |
void argaddr(int, uint64 *); | kernel/defs.h:134 | Read a pointer-sized syscall argument from the current trapframe. |
int fetchstr(uint64, char*, int); | kernel/defs.h:135 | Fetch a null-terminated string from user memory. |
int fetchaddr(uint64, uint64*); | kernel/defs.h:136 | Fetch a 64-bit value from the current process's user memory. |
void syscall(); | kernel/defs.h:137 | Dispatch the current process's syscall number. |
File descriptors
| Declaration | Header | Description |
|---|---|---|
struct file* filealloc(void); | kernel/defs.h:29 | Allocate an unused entry from the global open-file table. |
void fileclose(struct file*); | kernel/defs.h:30 | Close a file object and release its underlying resource. |
struct file* filedup(struct file*); | kernel/defs.h:31 | Increase a file object's reference count. |
void fileinit(void); | kernel/defs.h:32 | Initialize the global open-file table lock. |
int fileread(struct file*, uint64, int n); | kernel/defs.h:33 | Read through a file, pipe, or device descriptor. |
int filestat(struct file*, uint64 addr); | kernel/defs.h:34 | Copy file metadata into a user stat structure. |
int filewrite(struct file*, uint64, int n); | kernel/defs.h:35 | Write through a file, pipe, or device descriptor. |
Pipes
| Declaration | Header | Description |
|---|---|---|
int pipealloc(struct file**, struct file**); | kernel/defs.h:70 | Create paired read and write file objects for a pipe. |
void pipeclose(struct pipe*, int); | kernel/defs.h:71 | Close one side of a pipe and wake blocked peers. |
int piperead(struct pipe*, uint64, int); | kernel/defs.h:72 | Read bytes from a pipe into user memory. |
int pipewrite(struct pipe*, uint64, int); | kernel/defs.h:73 | Write bytes from user memory into a pipe. |
File system and log
| Declaration | Header | Description |
|---|---|---|
void binit(void); | kernel/defs.h:13 | Initialize the buffer cache and its block list. |
struct buf* bread(uint, uint); | kernel/defs.h:14 | Return a locked buffer containing a disk block. |
void brelse(struct buf*); | kernel/defs.h:15 | Release a locked buffer and move it toward the MRU end. |
void bwrite(struct buf*); | kernel/defs.h:16 | Write a locked buffer back to disk. |
void bpin(struct buf*); | kernel/defs.h:17 | Prevent a cached disk block from being evicted. |
void bunpin(struct buf*); | kernel/defs.h:18 | Drop a buffer-cache pin reference. |
void fsinit(int); | kernel/defs.h:38 | Initialize file-system state from the disk superblock. |
int dirlink(struct inode*, char*, uint); | kernel/defs.h:39 | Add a directory entry that points to an inode number. |
struct inode* dirlookup(struct inode*, char*, uint*); | kernel/defs.h:40 | Find a named entry inside a directory inode. |
struct inode* ialloc(uint, short); | kernel/defs.h:41 | Allocate a fresh on-disk inode of a given type. |
struct inode* idup(struct inode*); | kernel/defs.h:42 | Increment an inode reference count. |
void iinit(); | kernel/defs.h:43 | Initialize the in-memory inode cache. |
void ilock(struct inode*); | kernel/defs.h:44 | Lock an inode and load its on-disk metadata if needed. |
void iput(struct inode*); | kernel/defs.h:45 | Drop an inode reference and free it when links disappear. |
void iunlock(struct inode*); | kernel/defs.h:46 | Release a locked inode. |
void iunlockput(struct inode*); | kernel/defs.h:47 | Unlock an inode and drop one reference. |
void iupdate(struct inode*); | kernel/defs.h:48 | Write an inode's in-memory metadata to disk. |
int namecmp(const char*, const char*); | kernel/defs.h:49 | Compare xv6 directory entry names. |
struct inode* namei(char*); | kernel/defs.h:50 | Resolve a pathname to an inode. |
struct inode* nameiparent(char*, char*); | kernel/defs.h:51 | Resolve a pathname to its parent directory inode. |
int readi(struct inode*, int, uint64, uint, uint); | kernel/defs.h:52 | Read bytes from an inode into kernel or user memory. |
void stati(struct inode*, struct stat*); | kernel/defs.h:53 | Fill a stat structure from an inode. |
int writei(struct inode*, int, uint64, uint, uint); | kernel/defs.h:54 | Write bytes from kernel or user memory into an inode. |
void itrunc(struct inode*); | kernel/defs.h:55 | Free all data blocks owned by an inode. |
void ireclaim(int); | kernel/defs.h:56 | Clear inode-cache entries for a removed device. |
void initlog(int, struct superblock*); | kernel/defs.h:64 | Initialize the write-ahead log from the file-system superblock. |
void log_write(struct buf*); | kernel/defs.h:65 | Record that a buffer must be written during log commit. |
void begin_op(void); | kernel/defs.h:66 | Start a logged file-system operation, waiting if the log is full. |
void end_op(void); | kernel/defs.h:67 | Finish a logged file-system operation and commit if needed. |
Locks
| Declaration | Header | Description |
|---|---|---|
void acquire(struct spinlock*); | kernel/defs.h:109 | Take a spinlock and disable interrupt-driven preemption. |
int holding(struct spinlock*); | kernel/defs.h:110 | Report whether the current CPU holds a spinlock. |
void initlock(struct spinlock*, char*); | kernel/defs.h:111 | Initialize a spinlock with a debug name. |
void release(struct spinlock*); | kernel/defs.h:112 | Release a spinlock and restore interrupt state. |
void push_off(void); | kernel/defs.h:113 | Disable interrupts and record nested critical-section depth. |
void pop_off(void); | kernel/defs.h:114 | Restore interrupt enable state after a critical section. |
void acquiresleep(struct sleeplock*); | kernel/defs.h:117 | Take a sleeplock, sleeping until the lock becomes available. |
void releasesleep(struct sleeplock*); | kernel/defs.h:118 | Release a sleeplock and wake waiters. |
int holdingsleep(struct sleeplock*); | kernel/defs.h:119 | Report whether the current process holds a sleeplock. |
void initsleeplock(struct sleeplock*, char*); | kernel/defs.h:120 | Initialize a sleeplock with a debug name. |
Device drivers
| Declaration | Header | Description |
|---|---|---|
void consoleinit(void); | kernel/defs.h:21 | Initialize console input, console output, and UART interrupts. |
void consoleintr(int); | kernel/defs.h:22 | Handle one console input character from the UART driver. |
void consputc(int); | kernel/defs.h:23 | Write one character to the console device. |
int printf(char*, ...) __attribute__ ((format (printf, 1, 2))); | kernel/defs.h:76 | Format text to the kernel console. |
void panic(char*) __attribute__((noreturn)); | kernel/defs.h:77 | Print a panic message and stop the kernel. |
void printfinit(void); | kernel/defs.h:78 | Initialize the console print lock. |
void uartinit(void); | kernel/defs.h:147 | Initialize the UART hardware. |
void uartintr(void); | kernel/defs.h:148 | Handle UART receive and transmit interrupts. |
void uartwrite(char [], int); | kernel/defs.h:149 | Write a buffer to the UART console. |
void uartputc_sync(int); | kernel/defs.h:150 | Synchronously write one character to the UART. |
int uartgetc(void); | kernel/defs.h:151 | Read one received UART character if available. |
void plicinit(void); | kernel/defs.h:174 | Configure global PLIC interrupt priorities. |
void plicinithart(void); | kernel/defs.h:175 | Enable PLIC delivery for the current hart. |
int plic_claim(void); | kernel/defs.h:176 | Claim the next pending external interrupt. |
void plic_complete(int); | kernel/defs.h:177 | Tell the PLIC an interrupt has been handled. |
void virtio_disk_init(void); | kernel/defs.h:180 | Initialize the VirtIO block device and descriptor ring. |
void virtio_disk_rw(struct buf *, int); | kernel/defs.h:181 | Submit a synchronous block read or write request. |
void virtio_disk_intr(void); | kernel/defs.h:182 | Handle completed VirtIO disk requests. |
String and memory
| Declaration | Header | Description |
|---|---|---|
int memcmp(const void*, const void*, uint); | kernel/defs.h:123 | Compare two byte ranges. |
void* memmove(void*, const void*, uint); | kernel/defs.h:124 | Copy bytes between overlapping memory ranges. |
void* memset(void*, int, uint); | kernel/defs.h:125 | Fill a memory range with one byte value. |
char* safestrcpy(char*, const char*, int); | kernel/defs.h:126 | Copy a string while always terminating the destination. |
int strlen(const char*); | kernel/defs.h:127 | Return the length of a null-terminated string. |
int strncmp(const char*, const char*, uint); | kernel/defs.h:128 | Compare bounded strings. |
char* strncpy(char*, const char*, int); | kernel/defs.h:129 | Copy a bounded string. |
Small User-space C Library
Generated from the non-syscall declarations in user/user.h.
String and memory
| Declaration | Header | Description |
|---|---|---|
char* strcpy(char*, const char*); | user/user.h:30 | Copy a null-terminated string. |
void *memmove(void*, const void*, int); | user/user.h:31 | Copy bytes between possibly overlapping memory ranges. |
int strcmp(const char*, const char*); | user/user.h:33 | Compare two null-terminated strings. |
uint strlen(const char*); | user/user.h:35 | Return the length of a null-terminated string. |
void* memset(void*, int, uint); | user/user.h:36 | Fill a memory range with one byte value. |
int memcmp(const void *, const void *, uint); | user/user.h:38 | Compare two byte ranges. |
void *memcpy(void *, const void *, uint); | user/user.h:39 | Copy bytes between non-overlapping memory ranges. |
Input and output
| Declaration | Header | Description |
|---|---|---|
char* gets(char*, int max); | user/user.h:34 | Read a line from standard input into a buffer. |
void fprintf(int, const char*, ...) __attribute__ ((format (printf, 2, 3))); | user/user.h:44 | Write formatted output to a file descriptor. |
void printf(const char*, ...) __attribute__ ((format (printf, 1, 2))); | user/user.h:45 | Write formatted output to standard output. |
Memory allocation
| Declaration | Header | Description |
|---|---|---|
char* sbrk(int); | user/user.h:40 | Grow the user heap through the normal syscall wrapper. |
char* sbrklazy(int); | user/user.h:41 | Grow the user heap using xv6's lazy-allocation mode. |
void* malloc(uint); | user/user.h:48 | Allocate bytes from the user heap. |
void free(void*); | user/user.h:49 | Return a malloc allocation to the user heap. |
Utilities
| Declaration | Header | Description |
|---|---|---|
int stat(const char*, struct stat*); | user/user.h:29 | Open a path and return its file metadata. |
char* strchr(const char*, char c); | user/user.h:32 | Find the first occurrence of a character in a string. |
int atoi(const char*); | user/user.h:37 | Parse a decimal string as an integer. |
21 Unix-like System Calls
Generated from the dispatch table in kernel/syscall.c.
Process
| Declaration | Header | Description |
|---|---|---|
int fork(void); | user/user.h:6 | Create a child process by copying the caller. |
int exit(int) __attribute__((noreturn)); | user/user.h:7 | Terminate the current process with a status value. |
int wait(int*); | user/user.h:8 | Wait for a child process to exit. |
int kill(int); | user/user.h:13 | Request termination of a process by PID. |
int exec(const char*, char**); | user/user.h:14 | Load and run a new program in the current process. |
int getpid(void); | user/user.h:23 | Return the current process ID. |
Memory and time
| Declaration | Header | Description |
|---|---|---|
char* sys_sbrk(int,int); | user/user.h:24 | Grow or shrink the process heap. |
int pause(int); | user/user.h:25 | Suspend the process for a short timer interval. |
int uptime(void); | user/user.h:26 | Return the number of timer ticks since boot. |
File descriptors
| Declaration | Header | Description |
|---|---|---|
int pipe(int*); | user/user.h:9 | Create a unidirectional pipe and return two descriptors. |
int read(int, void*, int); | user/user.h:11 | Read bytes from a file descriptor. |
int fstat(int fd, struct stat*); | user/user.h:18 | Return metadata for an open file descriptor. |
int dup(int); | user/user.h:22 | Duplicate an open file descriptor. |
int write(int, const void*, int); | user/user.h:10 | Write bytes to a file descriptor. |
int close(int); | user/user.h:12 | Release an open file descriptor. |
File system
| Declaration | Header | Description |
|---|---|---|
int chdir(const char*); | user/user.h:21 | Change the current process's working directory. |
int open(const char*, int); | user/user.h:15 | Open or create a file and return a descriptor. |
int mknod(const char*, short, short); | user/user.h:16 | Create a device inode. |
int unlink(const char*); | user/user.h:17 | Remove a directory entry. |
int link(const char*, const char*); | user/user.h:19 | Create a hard link to an existing inode. |
int mkdir(const char*); | user/user.h:20 | Create a directory at a pathname. |
Small Unix User Environment
User commands and test programs in user/.
| Command | Entry point | Description |
|---|---|---|
cat | user/cat.c | Copy files or standard input to standard output. |
dorphan | user/dorphan.c | User-space xv6 test or utility program. |
echo | user/echo.c | Print command arguments. |
forktest tests | user/forktest.c | User-space xv6 test or utility program. |
forphan | user/forphan.c | User-space xv6 test or utility program. |
grep | user/grep.c | Search input lines with a small regular-expression matcher. |
grind | user/grind.c | User-space xv6 test or utility program. |
init | user/init.c | First user process; starts the shell and reaps orphaned children. |
kill | user/kill.c | User-space xv6 test or utility program. |
ln | user/ln.c | Create a hard link. |
logstress | user/logstress.c | User-space xv6 test or utility program. |
ls | user/ls.c | List directory entries and file metadata. |
mkdir | user/mkdir.c | Create a directory. |
rm | user/rm.c | Remove a file or directory entry. |
sh | user/sh.c | Small command shell with redirection, pipes, lists, and background jobs. |
stressfs | user/stressfs.c | User-space xv6 test or utility program. |
usertests tests | user/usertests.c | User-space xv6 test or utility program. |
wc | user/wc.c | Count lines, words, and bytes. |
zombie | user/zombie.c | User-space xv6 test or utility program. |