Overview & Prerequisites
This section is the on-ramp, and it is the first gate. Before you read a single line of
vstate/vcpu/ or trace a PUT /boot-source from a Unix socket down to a KVM_RUN exit, you need a
Linux host with working hardware virtualization, a Firecracker checkout that builds with
tools/devtool, a microVM that boots from your own binary, and a git identity wired for DCO
sign-off. This page gets you there. Budget two to four hours for a cold setup — most of that is
the first Docker image pull and the first cargo build compiling the dependency tree.
This curriculum will not hold your hand. It assumes you are a strong systems/backend engineer who can
read unfamiliar Rust without a guide, who is comfortable with processes, threads, file descriptors,
mmap, ioctl, epoll, and Unix sockets. What it will do is point you at the exact parts of the
codebase that matter, give you the right questions, and make you prove competence at each gate. The
setup below is the first such gate: if you cannot build Firecracker and boot a microVM from your own
binary, nothing else in the curriculum will work.
The One Hard Requirement: Linux + KVM + Hardware Virtualization
Firecracker is Linux-only, runs on x86_64 or aarch64, and is built directly on KVM.
There is no macOS build, no Windows build, no "emulation fallback." If you are reading this on a Mac
or a Windows box (as many of you are), you need a Linux host with a real /dev/kvm to do the work.
KVM needs CPU virtualization extensions exposed to it: Intel VT-x / VMX or AMD-V / SVM on
x86_64, or EL2 + stage-2 translation on aarch64. The kernel must have the kvm and
kvm_intel/kvm_amd (or arm64 equivalent) modules loaded, and your user must be able to read and
write /dev/kvm.
# THE single most important pre-flight check. If this fails, nothing else works.
ls -l /dev/kvm
# crw-rw---- 1 root kvm 10, 232 ... /dev/kvm ← you must be able to read+write it
# Are you allowed to use it? Either be in the `kvm` group or have rw access another way.
[ -r /dev/kvm ] && [ -w /dev/kvm ] && echo "KVM OK" || echo "NO KVM ACCESS — fix this first"
# Add yourself to the kvm group if needed (then log out / back in):
sudo usermod -aG kvm "$(whoami)"
# Is hardware virtualization actually available to the CPU?
grep -Eoc '(vmx|svm)' /proc/cpuinfo # x86_64: nonzero = HW virt present
lscpu | grep -i virtualization # human-readable
Warning — nested virtualization and bare metal. A laptop or a desktop running Linux on bare metal "just works." A cloud VM usually does not, because the guest VM lacks
/dev/kvmunless nested virtualization is enabled. On AWS, Firecracker development is done on bare-metal (*.metal) instances — ordinary EC2 instances cannot run it. On GCP/Azure, enable nested virt on the instance. Locally, a Linux VM under VMware/VirtualBox/QEMU needs "Expose VT-x/AMD-V to guest" turned on. Ifls -l /dev/kvmfails inside your dev VM, you are on the wrong kind of host.
Tip: A Linux desktop or laptop you already own is the smoothest path. Second-best is a
*.metalcloud instance. WSL2 on Windows has/dev/kvmon recent builds and can work, but bare-metal Linux is the reference experience the rest of this curriculum assumes.
What You Are Setting Up (the whole picture)
┌──────────────────────────────────────────────────────────────────────────────┐
│ Your Linux host (x86_64 or aarch64, /dev/kvm present and writable) │
│ │
│ Docker ── tools/devtool runs the build/test INSIDE a pinned container ──┐ │
│ │ public.ecr.aws/firecracker/fcuvm:vNN (Rust toolchain, │ │
│ │ cross-compilers, test kernels, pytest harness) │ │
│ ▼ │ │
│ ~/src/firecracker ◄── git clone ── github.com/firecracker-microvm/... │ │
│ │ │ │
│ │ tools/devtool build (bind-mounts the source into the container) │ │
│ ▼ │ │
│ build/cargo_target/<arch>-unknown-linux-musl/<debug|release>/firecracker │ │
│ │ + jailer │ │
│ ▼ │ │
│ sudo ./firecracker --api-sock /tmp/fc.sock ── one process = one microVM │◄─┘
│ ▲ │ │
│ │ │ ioctl() on /dev/kvm (KVM_CREATE_VM, KVM_RUN, …) │
│ curl --unix-socket /tmp/fc.sock PUT /boot-source /drives /actions … │
│ │
│ git commit -s ──► DCO Signed-off-by ──► PR on GitHub (≥2 approvals) │
└──────────────────────────────────────────────────────────────────────────────┘
Three facts shape everything:
- Firecracker builds inside a Docker dev container driven by
tools/devtool. You do not install a Rust toolchain system-wide; the container pins the exact channel (fromrust-toolchain.toml), carries the cross-compilers and the test kernels, and bind-mounts your source. You need Docker, Git, and a checkout — that is essentially it. - One Firecracker process is exactly one microVM. There is no daemon managing many VMs. You
start the process with an API socket, configure the machine by
PUT-ing JSON over that socket, then sendInstanceStart. Density at scale comes from running many Firecracker processes. - Contribution happens on GitHub — issues and pull requests against
mainongithub.com/firecracker-microvm/firecracker. There is no CLA. Every commit needs a DCO sign-off (git commit -s), and merging requires two maintainer approvals.
Step 1 — Install the toolchain
| Tool | Version | Why |
|---|---|---|
| Docker | recent | tools/devtool runs the entire build/test inside a container. The one tool you truly cannot skip. |
| Git | 2.x | Clone, branch, sign off commits, push to your fork. |
| curl | any | Drive the API on the Unix socket — your primary "user" interface. |
| rustup / cargo | matches rust-toolchain.toml (e.g. 1.96.0, verify on your branch) | Optional for the container build, but you want it locally for rust-analyzer, cargo doc, and editor navigation. |
| An editor with rust-analyzer | latest | Navigation across the vmm/firecracker/jailer crates is the highest-leverage skill here. |
ripgrep (rg) | any | This curriculum locates code with rg, never line numbers. Install it. |
# Verify the essentials.
docker --version # any recent Docker
git --version # git version 2.x
curl --version # any recent curl
rg --version # ripgrep — used constantly below
# Confirm Docker can run (the build needs this to work without sudo, ideally).
docker run --rm hello-world
Note: You do not need a specific system Rust version to build Firecracker — the dev container pins it. But install
rustupand let it pull the channel named inrust-toolchain.tomlso your editor'srust-analyzerand any localcargo docuse the same compiler the CI does. Mismatches here cause confusing "works in CI, red in my editor" noise.
Tip: Add yourself to the
dockergroup (sudo usermod -aG docker "$(whoami)", then re-login) sotools/devtooldoes not needsudo. The build runs the container as your UID and writes the output back into your checkout; running it as root muddies file ownership.
Step 2 — Clone the repo and read its contract
mkdir -p ~/src && cd ~/src
git clone https://github.com/firecracker-microvm/firecracker.git
cd firecracker
# Confirm you are on the development line and see recent history.
git branch -a | head
git log --oneline -5
Read these files in the repo root before you build anything — they are the project's own contract with you. Confirm they exist, then actually read them:
cd ~/src/firecracker
ls CONTRIBUTING.md CHANGELOG.md SPECIFICATION.md FAQ.md SECURITY.md MAINTAINERS.md CHARTER.md
ls docs/getting-started.md docs/jailer.md docs/seccomp.md docs/prod-host-setup.md
| File | Read it for |
|---|---|
CONTRIBUTING.md | The DCO sign-off rule, the ≥2-approval policy, the tools/devtool checks expected before a PR, commit hygiene (one logical change per commit, ≤72-char title), the integration-test requirement. |
docs/getting-started.md | The canonical "get a kernel + rootfs and boot a microVM" walkthrough. Your Step 4 below follows it. |
SPECIFICATION.md | What Firecracker is and deliberately is not — the minimal-device-model contract. |
CHANGELOG.md | The convention you will add an entry to in every functional PR. Also tells you which features landed when (your anti-staleness anchor). |
SECURITY.md | Vulnerabilities go privately to AWS Security, never as public issues. |
MAINTAINERS.md / CHARTER.md | Who can approve/merge, and the single-vendor governance model. |
Warning: The first
tools/devtool buildpulls a multi-gigabyte Docker image and compiles the entire dependency tree. Do it on a good connection and expect 15–40 minutes the first time. Subsequent builds reuse the image andcargo's incremental cache and are far faster.
Step 3 — First build with tools/devtool
tools/devtool is the front door to everything. It wraps cargo build (via tools/release.sh)
inside the pinned container, defaulting the C library to musl for a static binary.
cd ~/src/firecracker
# See what devtool can do — read this once.
tools/devtool --help
# First build. Default profile is debug; default libc is musl.
tools/devtool build
# A release build (optimized; what you want for any timing/perf observation).
tools/devtool build --release
# Equivalent control over the C library if you ever need glibc:
# tools/devtool build --release -l gnu
The binaries land under build/cargo_target/, keyed by target triple and profile. Locate them
rather than assuming a path — the arch segment differs on aarch64 (verify on your branch):
# Find your freshly built firecracker + jailer — run this, don't trust a hard-coded path.
find build/cargo_target -maxdepth 3 -type f \( -name firecracker -o -name jailer \)
# x86_64 release example:
# build/cargo_target/x86_64-unknown-linux-musl/release/firecracker
# build/cargo_target/x86_64-unknown-linux-musl/release/jailer
# Confirm the binary runs and report its version.
FC=$(find build/cargo_target -type f -name firecracker | grep -E 'release|debug' | head -1)
"$FC" --version
While the build runs, learn the quality gates you will live by — they are exactly what reviewers run:
tools/devtool fmt # cargo fmt + clippy --fix + cargo sort + python/markdown formatters
tools/devtool checkstyle # style checks (no code changes)
tools/devtool checkbuild --all # builds every target/feature combination the CI builds
Note: Clippy runs warnings-as-errors in CI:
cargo clippy --all --all-targets --all-features -- -D warnings. A PR with a single clippy warning will not pass.CONTRIBUTING.mdrecommends wiringtools/devtool checkstyleandcheckbuild --allas git hooks so you never push a build that CI will reject. Full walkthrough in Lab 1.1 and Lab 1.2.
Warning: The integration suite is pytest, in
tests/, driven bytools/devtool test— not rawcargo test. Unit tests arecargo test, but the suite that actually gates a PR is Python. Do not assumecargo testalone proves your change.
Step 4 — Boot a microVM (the smoke test that proves the build)
This is the moment the whole thing becomes real. You need two artifacts: an uncompressed kernel
(vmlinux) and a root filesystem (a flat ext4 image). docs/getting-started.md shows how to
fetch CI artifacts from the spec.ccfc.min bucket (a vmlinux-X.Y.Z and an Ubuntu squashfs
converted to a ~1 GiB ext4). Follow it to land ./vmlinux and ./rootfs.ext4 next to your binary,
then:
FC=$(find build/cargo_target -type f -name firecracker | grep release | head -1)
API=/tmp/firecracker.socket
rm -f "$API"
# 1. Start the VMM. It does nothing yet but listen on the socket.
sudo "$FC" --api-sock "$API" &
# 2. Point it at a kernel + the kernel command line.
curl -X PUT --unix-socket "$API" \
--data '{"kernel_image_path":"./vmlinux","boot_args":"console=ttyS0 reboot=k panic=1"}' \
http://localhost/boot-source
# 3. Give it a root filesystem (exposed as a virtio-block device).
curl -X PUT --unix-socket "$API" \
--data '{"drive_id":"rootfs","path_on_host":"./rootfs.ext4","is_root_device":true,"is_read_only":false}' \
http://localhost/drives/rootfs
# 4. (Optional) size the machine. Defaults: vcpu_count=1, mem_size_mib=128, smt=false.
curl -X PUT --unix-socket "$API" \
--data '{"vcpu_count":2,"mem_size_mib":1024}' http://localhost/machine-config
# 5. Start the microVM. The kernel boots; you get a login prompt on the serial console.
curl -X PUT --unix-socket "$API" \
--data '{"action_type":"InstanceStart"}' http://localhost/actions
If a Linux boot log scrolls past in the terminal where you launched Firecracker and you reach a login prompt, your build works and your KVM access is correct. That is the gate. The full guided version, with serial-console capture and teardown, is Lab 1.3, and the Warm-Up takes this much further (networking, a second drive, snapshots, MMDS).
Tip: Default microVM is 1 vCPU / 128 MiB. To shut a running microVM down cleanly, send
{"action_type":"SendCtrlAltDel"}to/actions(x86_64), orrebootfrom inside the guest withreboot=kon the cmdline. Killing the Firecracker process also works — it owns the whole microVM.
Step 5 — Configure Git for DCO sign-off
Firecracker requires a Developer Certificate of Origin sign-off on every commit. This is
not a CLA — it is a one-line Signed-off-by: trailer asserting you have the right to contribute
the code. A DCO bot fails any PR with an unsigned commit.
# The identity in your Signed-off-by line MUST match the GitHub account/email you contribute from.
git config --global user.name "Your Real Name"
git config --global user.email "you@example.com"
# Sign off every commit with -s. This appends:
# Signed-off-by: Your Real Name <you@example.com>
git commit -s -m "net: fix off-by-one in RX descriptor accounting"
# Forgot -s on the last commit? Amend it.
git commit --amend -s --no-edit
# Forgot it across a range? Re-sign them all.
git rebase --signoff HEAD~3
A correctly signed commit message ends with:
net: fix off-by-one in RX descriptor accounting
Signed-off-by: Your Real Name <you@example.com>
Warning: The name/email in
Signed-off-by:must match yourgitidentity exactly and be an email GitHub recognizes for your account. Mismatches fail the DCO check and force you to rewrite history. Also keep commits clean: one logical change per commit, each commit passing tests, title ≤72 chars. Reviewers will ask you to split a "fix three things" commit.
The fork-and-pull flow (fork on GitHub, push a branch, open a PR against main) is covered in
Level 2 and the PR quality chapter.
For now, just get your local identity and sign-off working — this is part of the gate.
Step 6 — Join the community
Firecracker is developed in the open but single-vendor governed: a dedicated AWS team maintains
it, with no separate foundation or steering committee and no GOVERNANCE.md. Get plugged in now.
| Channel | Where | Use it for |
|---|---|---|
| GitHub account | https://github.com | Issues, PRs, code review — the entire contribution flow. |
| Issues list | https://github.com/firecracker-microvm/firecracker/issues | Find work, read triage, study how maintainers reason. |
| Maintainer email | firecracker-maintainers@amazon.com | The public contact list for project questions and coordination. |
| Security reports | AWS Security (private; see SECURITY.md) | Vulnerabilities — never open a public issue for a security bug. |
| CHANGELOG / releases | CHANGELOG.md, GitHub Releases | Track what landed and when; anchor your "(verify on your branch)" checks. |
Learn the labels you will use constantly (verify the exact set on the repo):
| Label | Meaning |
|---|---|
good first issue | Scoped, well-defined starter work — where you begin in Level 2. |
Type: Bug / Type: Enhancement | The nature of the issue. |
Status: Awaiting review / Status: ... | Where an issue/PR sits in the workflow. |
Priority: ... | Triage urgency. |
Kani | Formal-verification work (the Kani model checker). |
Roadmap: ... | Items tied to the public roadmap. |
Note: Large designs live as GitHub issues and discussion, not in a wiki. Reading how a feature was argued into existence (or rejected) on a thread is the single best way to absorb the project's values — especially the minimal-device-model philosophy, where "QEMU has it" is explicitly not an argument. The design-via-github chapter builds this skill.
How the Curriculum Fits Together
The curriculum is 9 levels of core engineering, several supporting tracks, and a capstone. Work the levels top to bottom — each builds directly on the previous, and the labs depend on foundations laid earlier.
flowchart TD
L1[Level 1: Virtualization & Firecracker Foundation] --> L2[Level 2: Contributor Onboarding]
L2 --> L3[Level 3: Architecture & the Threading Model]
L3 --> L4[Level 4: KVM, vCPUs & the Run Loop]
L4 --> L5[Level 5: Testing & Debugging]
L5 --> L6[Level 6: The Boot Process & Guest Memory]
L6 --> L7[Level 7: The Virtio Device Model]
L7 --> L8[Level 8: Real Issue Contribution]
L8 --> L9[Level 9: Advanced Maintainer]
L9 --> CAP[Capstone: one full contribution cycle]
RV[rust-vmm: the crates beneath FC] -.referenced by.-> L1
RV -.-> L4
RV -.-> L7
DD[Deep Dives x26] -.-> L3
DD -.-> L4
DD -.-> L6
DD -.-> L7
DD -.-> L9
MIND[Contributor Mindset] -.-> L2
MIND -.-> L8
ISS[Issue Roadmap: 12 stages] -.-> L2
ISS -.-> L8
ENG[Engineering at Scale] -.-> L9
MC[Feature Masterclasses x8] -.-> L7
MC -.-> L9
INT[Cross-Repo & Integration Labs] -.-> L8
GOV[Release, Review & Governance] -.-> L9
CAP --> GOV
| Track | What it is | When you touch it |
|---|---|---|
| Levels 1–9 | The spine. Sequential. Each level has 2–4 labs. | Work top to bottom; do not skip. |
| Contributor Mindset | How to read the codebase, design via GitHub, handle feedback, grow toward maintainership. | Alongside Levels 2, 8, 9. |
| Issue Roadmap | 12 staged issue difficulties, docs/tests → release-blocking. | Pick real issues as you progress. |
| Internals Deep Dives (26) | Focused internals chapters, each with a reading exercise and a "common bugs" table. | Open the relevant one whenever a level references it. |
| rust-vmm | The shared crates (kvm-ioctls, vm-memory, linux-loader, …) Firecracker is built on, with hands-on labs. | Throughout; heavily in Levels 1, 4, 7. |
| Engineering at Scale | Real design problems: snapshotting, oversubscription, I/O engines, boot-time. | Level 9 and the capstone. |
| Feature Masterclasses (8) | Deep intensives: KVM, boot, virtio, snapshots, security, networking, debugging, performance. | When you want to go past a level's depth. |
| Integration Labs | firecracker-containerd, the jailer in production, the Go SDK, bug attribution. | Around Level 8. |
| Release & Governance | Single-vendor governance, release policy, licensing, building trust. | Level 9 and the capstone. |
| Capstone | A complete real contribution: issue → reproduction → root cause → fix → tests → PR → write-up. | The final phase. |
The deep dives and the rust-vmm section are not optional reading — they are where the real depth lives. A level says "trace a virtio-block I/O"; the virtio-block deep dive and the virtqueues deep dive are where you learn how the descriptor chain actually works. Treat the levels as the spine and the deep dives as the muscle.
How to Use the Labs
Every lab follows the same shape, so you always know where you are:
- Background and Why This Lab Matters for Contributors — the why before the how.
- Prerequisites — what must already work (usually a green build and a prior lab).
- Step-by-Step Tasks — numbered, with real
tools/devtool/curl --unix-socket/git/rgcommands and expected output. - Deliverables — checkboxes you must satisfy.
- Troubleshooting, Expected Output, Stretch Goals.
- Validation / Self-check — 5–7 questions that gate completion.
Rules for the labs:
- Run every command. This is a hands-on apprenticeship; reading is not doing.
- When a lab gives an
rg/find, run it rather than trusting a line number. Firecracker's layout has shifted (a big refactor merged several crates intovmm), so the curriculum points you at code with commands instead of fabricated lines. If a path differs on your branch, thergstill finds it. - Do not advance past a lab's Validation section until you can answer it without notes.
- Treat "(verify on your branch)" literally. Where this curriculum cites a version-sensitive
fact (a default, an endpoint, a layout constant), confirm it against your checkout and
CHANGELOG.mdbefore relying on it.
You Are Ready When…
Confirm every box before opening Level 1:
-
ls -l /dev/kvmshows a device you can read and write;grep -Ec '(vmx|svm)' /proc/cpuinfois nonzero (or you are on aarch64 with EL2). -
docker run --rm hello-worldworks withoutsudo. -
~/src/firecrackeris cloned and you have readCONTRIBUTING.md,docs/getting-started.md, and skimmedSPECIFICATION.md. -
tools/devtool build --releaseproduced afirecracker(andjailer) underbuild/cargo_target/.../release/, andfirecracker --versionruns. -
tools/devtool checkstylepasses on a clean checkout. - You booted a microVM (a kernel log scrolled and you reached a login prompt).
-
git config user.name/user.emailare set andgit commit -sadds aSigned-off-by:line. - You have a GitHub account, have skimmed the issues list and its labels, and know that security reports go privately to AWS Security.
# A 5-minute "am I ready" smoke test (run from ~/src/firecracker).
# 1. Host can do hardware virtualization and you can touch /dev/kvm.
ls -l /dev/kvm && { [ -r /dev/kvm ] && [ -w /dev/kvm ] && echo "KVM rw OK"; }
grep -Ec '(vmx|svm)' /proc/cpuinfo
# 2. Your build exists and runs.
FC=$(find build/cargo_target -type f -name firecracker 2>/dev/null | head -1)
echo "binary: ${FC:-NOT BUILT — run tools/devtool build}"
[ -n "$FC" ] && "$FC" --version
# 3. Style gate is green and git is wired for DCO.
tools/devtool checkstyle 2>&1 | tail -3
git config user.name && git config user.email
# 4. Prove a microVM boots (after Step 4 artifacts are in place):
# re-run the Step 4 curl sequence and watch for a guest login prompt.
If any box is unchecked, fix it now. A broken baseline means every later tools/devtool build,
every curl --unix-socket, and every boot attempt will produce confusing failures that hide the real
work.
Where to Go Next
- The Hitchhiker's Guide to Virtualization, KVM & microVMs — read this
before Level 1. It builds the mental model from first principles: trap-and-emulate, the KVM
ioctlAPI, the three jobs of a VMM, the vCPU run loop, how a kernel boots with no BIOS, and virtio in one page. - Firecracker Warm-Up: From User to Contributor — the most important page in this section. Run Firecracker as a user across five real scenarios, then bridge each one to the source.
- 16-Week Plan — a calendar that maps Levels 1–9 + supporting tracks + capstone onto 16 weeks, with reading, labs, GitHub-issue practice, and exit checkpoints.
- Milestones: M1–M9 — the competence gates. Each has skills, self-check questions, and a 20-point rubric.
Continue to the Hitchhiker's Guide, then the Warm-Up, and only then start Level 1: Virtualization and Firecracker Foundation.