Skip to main content

Environment Setup

What You Need

ToolMinimum VersionPurpose
riscv64-linux-gnu-gcc12.xCross-compile xv6 kernel and user programs
qemu-system-riscv647.xEmulate the virt RISC-V board
make4.xDrive the build
perl5.xxv6 linker script generation
node18.xBuild this documentation site
npm9.xNode package manager

This project was validated with GCC 15.2.1 and QEMU 10.2.2 on Fedora.

Why RISC-V and QEMU

xv6 targets RISC-V because the ISA is clean, open, and well-supported by GCC and QEMU. The privilege levels (U/S/M = User/Supervisor/Machine) map exactly to xv6's user/kernel separation.

QEMU's virt board provides the virtio disk device that xv6 uses for its filesystem. The -bios none flag tells QEMU to jump directly to the kernel ELF without a BIOS ROM, which is what xv6's linker script expects.

Install the Toolchain

Fedora / RHEL

sudo dnf install -y \
make gcc perl python3 bc \
qemu-system-riscv-core \
gcc-riscv64-linux-gnu \
binutils-riscv64-linux-gnu \
nodejs npm

Ubuntu / Debian

sudo apt-get install -y \
make gcc perl bc \
qemu-system-misc \
gcc-riscv64-linux-gnu \
binutils-riscv64-linux-gnu \
nodejs npm

Verify

riscv64-linux-gnu-gcc --version
# riscv64-linux-gnu-gcc (GCC) 15.2.1 ...

qemu-system-riscv64 --version
# QEMU emulator version 10.2.2 ...

node --version # v22.x or later
npm --version # 10.x or later

Build xv6

cd xv6-security

# Clean any stale objects
make clean

# Build kernel, user programs, mkfs, and fs.img
make

A successful build prints something like:

...
riscv64-linux-gnu-objcopy -S -O binary .obj/kernel kernel/kernel
riscv64-linux-gnu-objcopy -S -O binary .obj/user/_compliance_test user/_compliance_test
...
RWX segment warning

Modern binutils warn about ELF segments with RWX permissions, which xv6 deliberately uses. The Makefile suppresses these with -no-warn-rwx-segments. If you see this warning on an older toolchain that ignores the flag, it is harmless.

Boot xv6 in QEMU

make qemu

QEMU launches and xv6 prints its boot banner, then the login prompt:

xv6 kernel is booting

login:

Type your username and password:

login: admin
password: admin123
$

QEMU terminal showing xv6 boot banner and login prompt

QEMU Flags Explained

The Makefile passes these flags to QEMU:

FlagMeaning
-machine virtUse the generic RISC-V virt board
-bios noneNo BIOS: jump directly to the kernel
-kernel kernel/kernelLoad the kernel ELF
-m 128MAllocate 128 MiB of RAM
-smp 3Simulate 3 SMP cores (CPUs)
-nographicNo graphical window, serial on stdio
-drive file=fs.img,...Mount the filesystem image

Stopping QEMU

Press Ctrl-A then X (release Ctrl-A first, then press X).

Do not press Ctrl-C: that sends SIGINT to the QEMU process tree and may leave your terminal in a bad state.

Build the Docs Site

cd docs
npm install
npm run build # produces docs/build/
npm run serve # local preview at http://localhost:3000

Troubleshooting

SymptomLikely causeFix
make: riscv64-linux-gnu-gcc: No such file or directoryToolchain not installedRun sudo dnf install gcc-riscv64-linux-gnu
qemu-system-riscv64: command not foundQEMU not installedRun sudo dnf install qemu-system-riscv-core
mkfs: fs.img write errorStale imagemake clean && make
Login prompt not appearingQEMU not loading kernelCheck kernel/kernel file exists after build
npm run build failsMissing node_modulesRun npm install first

No output from the grep command means the quality gate passed.

Boot xv6 with:

```bash
make qemu-nox

The target reuses xv6's nographic QEMU mode, so the login prompt appears directly in the terminal.

Common Pitfalls

Some xv6 guides mention make qemu-nox, while this xv6 snapshot originally provided only make qemu. This project adds qemu-nox as a compatibility alias.

Package names differ by distribution. Fedora uses binutils-riscv64-linux-gnu; other distributions may package the same tools under a different name.

Do not commit generated build artifacts such as fs.img, kernel/kernel, object files, or generated user binaries. They are ignored and should be rebuilt locally.