xv6, line by line
tour 1
Tours1 From make qemu to a disk image and a kernel

Tour 1 · Boot and build · about 34 minutes · 21 steps

From make qemu to a disk image and a kernel

Before xv6 can run a single instruction, two files must exist: kernel/kernel, the program the three CPUs will execute, and fs.img, the disk they will read init and the shell from. You type make qemu, about a hundred commands scroll past, and QEMU starts. This tour slows that scroll down and reads it as a story.

You will watch make / Makefile work out what must be built and in what order, see the real command that turns one .c file into an object file (.o) for a CPU your computer does not have, assemble a .S file, and watch the linker (ld) place the kernel at 0x80000000 according to kernel/kernel.ld. Then a small program, mkfs, runs on your computer and lays out a 2000-block file system, block by block. Finally QEMU is told to build a machine with three CPUs and boot it.

Every number in this tour comes from a real build of this commit, with GCC 15.2.0 for riscv64 and QEMU 11.0.0. Your addresses may differ by a few bytes with another compiler; the layout will not.

Who is running where

Nothing is running yet. There are no harts, no processes and no locks: only make on your computer, and later mkfs. But keep three harts in mind. The last command of this tour, -smp 3, creates them, and many choices made at build time (one boot stack per CPU, one kernel image shared by every CPU, global tables in .bss) exist because of them.

Hart What it is doing
0 Does not exist yet. QEMU will create it at the end of this tour
1 Does not exist yet
2 Does not exist yet
Three harts are running. This tour follows one path through the code, but the machine has three CPUs executing at the same time. Watch the locks held display at the top of each step, and read the Meanwhile, on other harts boxes: they show what the other CPUs could be doing at that very moment.
The route
  1. 1You ask for a running system Makefile
  2. 2Finding a compiler for a CPU you do not have Makefile
  3. 3The kernel is 27 object files Makefile
  4. 4Compiling one C file, with the real flags Makefile
  5. 5What the compiler made of main.c kernel/main.c
  6. 6-MD teaches make which headers matter Makefile
  7. 7Assembling a .S file kernel/entry.S
  8. 8The trampoline asks for a page of its own kernel/trampoline.S
  9. 9Linking 27 objects into one kernel Makefile
  10. 10kernel.ld puts the code at 0x80000000 kernel/kernel.ld
  11. 11kernel.ld lays out the data, and marks the end kernel/kernel.ld
  12. 12User programs, the user library and the system-call stubs Makefile
  13. 13Every user program starts at address 0 user/user.ld
  14. 14mkfs is compiled for your computer, not for RISC-V Makefile
  15. 15fs.img depends on every user program Makefile
  16. 16mkfs plans the disk mkfs/mkfs.c
  17. 17The root directory and the files mkfs/mkfs.c
  18. 18iappend hands out blocks in order mkfs/mkfs.c
  19. 19Marking the used blocks mkfs/mkfs.c
  20. 20The QEMU command line Makefile
  21. 21What the build decided, and what it left to the harts Makefile

Keys: ← → step · Home start