The Weekly Learning Plan
A calendar-shaped version of the roadmap, for people who prefer a schedule to a checklist. Twenty weeks at roughly 8–12 hours per week — evenings and one weekend session — plus a tail whose length is not yours to decide.
Adjust freely. The only rule that matters is the one from the teaching method: do not move on until the current behavior can be inspected and explained. A week that ends with a module that loads but that you cannot explain is a week you will repay with interest in week 13, when a lockdep splat means nothing to you.
The Shape of the Course
W0 ▓ Orientation: history, warm-up, mental model M0
W1 ▓ The lab rig: build, boot, GDB M1
W2-8 ▓▓▓▓▓▓▓ Foundations: the floor M2-M6
W9-10 ▓▓ Contribution: the workflow ── clock starts M8-M10
W11 ▓ Read a subsystem cold M7
W12-15 ▓▓▓▓ Subsystems: breadth, then depth in one M11
W16-17 ▓▓ Engineering: regressions and performance M12
W18-19 ▓▓ Capstone: find it, write it, send it, revise M13
W20+ ░░░░░░░░ ← not yours Waiting on the merge window M14
Weeks 9–10 sit where they do on purpose. They come before the deep subsystem work because the community's clock runs in weeks and you want it started. The roadmap draws M7 before M8 — read before you patch — and that is right for a substantive patch. Your first patch is deliberately trivial and needs only enough reading to be certain the fix is correct, so this schedule starts the mailing-list clock in week 9 and completes the full cold-read in week 11.
Week 0: Orientation
| Session | Work | Output |
|---|---|---|
| 1 (2h) | The Hitchhiker's Guide | Understanding why any of this is like this |
| 2 (2h) | The Warm-Up, exercises 1–7 | warmup.md with written predictions |
| 3 (2h) | The Warm-Up, exercises 8–13 + the debrief | The debrief answered |
| 4 (2h) | The Kernel Mental Model — Milestone 0 | answers-m0.md, committed |
Gate: you can state the context rules from memory — which of process context, spinlock-held, softirq, hardirq, and NMI may sleep — and name all four ways into the kernel.
Tip: Commit
answers-m0.mdeven though parts of it are wrong. You re-answer the same fifteen questions at the capstone, and the diff is the most direct measure of what this curriculum did for you.
Week 1: The Lab Rig
The whole week on infrastructure. It feels like a detour. It is not.
| Session | Work | Milestone |
|---|---|---|
| 1 | Overview & Prerequisites: packages, clone the tree, first defconfig build | — |
| 2 | The Lab Rig: the config fragments, the busybox initramfs | — |
| 3 | Lab 1: boot in QEMU, serial console, panic handling | M1 |
| 4 | Lab 1 continued: GDB, lx- scripts, -S and start_kernel, measure the loop | M1 |
Gate: a one-file change to a rebuilt-and-booted guest in under two minutes, with a breakpoint firing. Write the measured number down.
Warning: Do not proceed with a five-minute-plus loop on the theory that you will optimize it later. Every subsequent week assumes you experiment freely, and you will not experiment freely if each experiment costs five minutes. Fix it now: ccache,
O=, KVM, and 9p instead of repacking the initramfs.
Weeks 2–8: Foundations
The longest stretch, and the one that most rewards patience. Everything after it assumes these seven concepts are reflexes.
Week 2 — The boundary, and your first module
| Session | Work | Milestone |
|---|---|---|
| 1 | The User/Kernel Boundary | — |
| 2 | Kernel C — the dialect and its rules | — |
| 3 | Lab 2: hello, parameters, clean unwind | M2 |
| 4 | Lab 2 challenges: the failure path; read modules/01-hello line by line; checkpatch it | — |
Gate: ten load/unload cycles with no leak; you can name every line of your module's teardown and what leaks if it is missing.
Week 3 — Context and concurrency
The most important week in the curriculum. Two chapters, and you read both twice.
| Session | Work | Milestone |
|---|---|---|
| 1 | Context and Atomicity — read this twice | — |
| 2 | Concurrency: atomics, spinlock vs. mutex, per-CPU | — |
| 3 | Concurrency continued: RCU, memory barriers, lockdep | — |
| 4 | Deliberately break it: sleep in atomic context, write an ABBA deadlock, read both splats | — |
Gate: you can look at an arbitrary kernel function and say which contexts it may be called from, and justify the answer from its code rather than its name.
Warning: This is where people fall behind, because the failure modes are non-local and non-deterministic. Budget the extra evening. If a concept has not landed, do the experiment again with
-smp 8instead of-smp 4— most concurrency intuitions are built by watching something that "worked" stop working when there are more CPUs.
Week 4 — A real device
| Session | Work | Milestone |
|---|---|---|
| 1 | Lab 3: file_operations, open/read/write | M3 |
| 2 | Lab 3: ioctl and its ABI rules; the userspace exerciser | M3 |
| 3 | Lab 3: the deliberate race — reproduce it, then fix it, under PROVE_LOCKING | — |
| 4 | Lab 3 experiment: dereference a user pointer directly; all three cases | — |
Gate: two concurrent processes cannot corrupt your device's state, and you can say which lock you chose and why the alternative was wrong.
Week 5 — Memory
| Session | Work | Milestone |
|---|---|---|
| 1 | Memory: virtual memory, the page allocator, GFP flags | — |
| 2 | Memory: slab vs. vmalloc vs. alloc_pages; when each is right | — |
| 3 | Memory: DMA, and why kmalloc'd memory is not always reachable by a device | — |
| 4 | Experiments: watch /proc/buddyinfo and slabtop while your module allocates; fault injection | — |
Gate: given an allocation site, you can name the right allocator and the right GFP flags, and say what happens under memory pressure with each.
Week 6 — Deferred work and debugging
| Session | Work | Milestone |
|---|---|---|
| 1 | Deferred Work: IRQ, softirq, tasklet, workqueue, timers | — |
| 2 | Lab 4: ftrace and kprobes on your own module | M4 |
| 3 | Lab 4: KASAN, lockdep, kmemleak; produce and decode an oops | M4 |
| 4 | Lab 4 experiment: the use-after-free, ten runs with and without KASAN | — |
Gate: you can read an oops, a lockdep splat, and a KASAN report line by line, and say what each one is telling you before you look at the source.
Week 7 — The device model, and a syscall
| Session | Work | Milestone |
|---|---|---|
| 1 | The Device Model: kobject, sysfs, bus/driver/device, probe | — |
| 2 | The device model: devres, DT/ACPI matching, module lifetime and refcounting | — |
| 3 | Lab 5: add one, wire it up, validate arguments | M5 |
| 4 | Lab 5: the ABI write-up, the struct-layout experiment, and the argument against | M5 |
Gate: a written ABI specification for your syscall, plus a paragraph arguing it should not exist.
Week 8 — Testing
| Session | Work | Milestone |
|---|---|---|
| 1 | Lab 6: KUnit, run under kunit.py | M6 |
| 2 | Lab 6: a kselftest for your char device or syscall | M6 |
| 3 | Lab 6: make C=1 (sparse), make W=1, and an allmodconfig build | — |
| 4 | Lab 6 experiment: the __user annotation error, through all three checkers | — |
Gate: both tests fail informatively when you reintroduce the bug they cover. Foundations is complete — you can write, load, debug, and test kernel code.
Weeks 9–10: Contribution — and the Clock Starts
Week 9 — Send something
| Session | Work | Milestone |
|---|---|---|
| 1 | Maintainers and Trees; get_maintainer.pl; add a subsystem remote | — |
| 2 | Patch Craft + Style and Checks | — |
| 3 | Email Workflow: configure git send-email; send a patch to yourself and git am it | — |
| 4 | Lab 7: find a real trivial fix and send it | M8 |
Gate: your patch is on lore.kernel.org and you have its message-ID. The clock is running.
Tip: Do session 3 completely before session 4. The single most common first-patch failure is a mail path that mangles the patch — and you can detect that in five minutes by mailing it to yourself, with nobody watching.
Week 10 — Series, review, and etiquette
| Session | Work | Milestone |
|---|---|---|
| 1 | Review and Etiquette; read a week of your subsystem's list on lore | — |
| 2 | Lab 8: a multi-patch series with a cover letter | M9 |
| 3 | Lab 8: the bisectability check (git rebase --exec), then a v2 with range-diff | M9 |
| 4 | Lab 9: review someone else's patch, on-list | M10 |
Gate: a series that builds at every commit, and a review you posted that the author responded to.
Week 11: Read a Subsystem Cold
| Session | Work | Milestone |
|---|---|---|
| 1 | Subsystems Overview: the method; choose an unfamiliar subsystem | — |
| 2 | Apply steps 1–4 of the method: maintainers, docs, the nouns, the verbs | — |
| 3 | Apply steps 5–7: trace one path, read six months of git log, find the tests | M7 |
| 4 | Repeat the whole thing on a second subsystem, timeboxed to two hours | — |
Gate: a written subsystem map another engineer could orient themselves with, plus three well-phrased questions the tree could not answer.
Weeks 12–15: Subsystems
Read all eight orientation chapters. Go deep in one.
Week 12 — Breadth
| Session | Work |
|---|---|
| 1 | CPU/Scheduler + Memory Management orientation |
| 2 | Storage + Networking orientation |
| 3 | Graphics + Security orientation |
| 4 | Accelerators/AI + Firmware/Platform orientation; choose one |
Gate: for each of the eight, one sentence on what it does and one on where its code lives — and a choice you can justify.
Tip: Choose the one where you can most plausibly get a patch merged, not the one that sounds most impressive. Activity level, maintainer responsiveness, and hardware you actually own matter more than glamour. The
git log --since="6 months ago"count from each orientation chapter is the most useful single data point.
Weeks 13–15 — Depth
| Week | Work | Milestone |
|---|---|---|
| 13 | Your subsystem's concept chapters, with the validation questions answered | — |
| 14 | Your subsystem's labs, including every experiment | — |
| 15 | Trace one full control path with ftrace or GDB; find three contribution targets; subscribe to the list | M11 |
Gate: you can predict, before running it, what an experiment in your subsystem will show — and you are usually right.
Weeks 16–17: Engineering
Week 16 — Regressions
| Session | Work | Milestone |
|---|---|---|
| 1 | Regressions: git bisect, and what 125 means | — |
| 2 | A full automated bisection on a real behavior difference between two versions | — |
| 3 | syzkaller and syzbot: read a report end to end; what a reproducer is and is not | — |
| 4 | Stable and Backports + API and ABI | — |
Week 17 — Performance
| Session | Work | Milestone |
|---|---|---|
| 1 | Performance: perf, counters, and what they do not measure | — |
| 2 | The noise experiment: same workload, same kernel, five runs. Report the spread. | — |
| 3 | Benchmark a real change with a control, variance, and a named noise source | M12 |
| 4 | A flame graph, plus a written statement of what it does not show | M12 |
Gate: a benchmark result you would defend on a mailing list, including its error bars.
Weeks 18–19: The Capstone Contribution
| Week | Session | Work | Milestone |
|---|---|---|---|
| 18 | 1 | Choose the target from your week-15 list; confirm it is still open and unclaimed | — |
| 18 | 2–3 | Write it. Test it under lab-paranoid. Write the selftest or KUnit case. | — |
| 18 | 4 | Commit message, tags (Fixes:, Cc: stable, Link:), checkpatch --strict, allmodconfig | — |
| 19 | 1 | Send it, at the right point in the cycle, to the right people | — |
| 19 | 2–4 | Respond to review. Produce v2. Collect trailers. Repeat. | M13 |
Gate: your commit is in a maintainer's tree and appears in a linux-next tag.
The Part of the Schedule You Do Not Control
Milestone 14 is not a week. It is a wait.
you send v1 ──▶ review latency: days to weeks (or silence)
you send v2 ──▶ maintainer applies: days to weeks
applied to -next ──▶ soaks in linux-next: until the next merge window
the merge window ──▶ opens every ~9-10 weeks, lasts 2 weeks
Linus pulls ──▶ your commit is in mainline, at -rc1
-rc1 … -rc7 ──▶ 6-7 more weeks
vX.Y released ──▶ M14 complete
Realistic total, from sending v1 to a tagged release: six to sixteen weeks. Sometimes longer. If you send at -rc6, add a full cycle before anything happens at all.
Three consequences, and they are the reason this section exists:
1. Start M8 in week 9, not week 18. The trivial first patch exists partly to teach the mechanics and partly to start the clock while you still have three months of curriculum left.
2. Do not idle while waiting. The wait is not blocked time; it is the time to do M10 (review others' patches), read your subsystem's list, and find the second contribution target. A person who sends one patch and waits has learned the workflow once. A person who has three in flight has learned it.
3. Distinguish "the work is done" from "it merged." The curriculum's deliverable is a patch that should merge — correct, tested, reviewed, well-argued. Whether it merges also depends on the maintainer's priorities, the cycle, and sometimes whether they agree with the approach. A rejected patch that you can defend is a pass. A merged whitespace cleanup is not.
Note: If your patch is NAK'd — rejected on the merits — that is not a failure of this curriculum. Read Review and Etiquette on what a NAK means and what to do next, then either fix the objection or pick a different target. Arguing with a NAK you do not understand is the one move guaranteed to fail.
Compressed Schedules
Twelve weeks (~20 h/week)
Double up. Do not compress weeks 3 and 6 — context/concurrency and debugging are the foundation, and compressing them is false economy that surfaces in week 13 as inability to read a splat.
W1 Orientation + the lab rig (W0 + W1)
W2 Foundations W2 + half of W3
W3 Foundations W3 (concurrency) — FULL LENGTH
W4 Foundations W4 + W5
W5 Foundations W6 (debugging) — FULL LENGTH
W6 Foundations W7 + W8
W7 Contribution W9 + W10 ── send the first patch here at the latest
W8 Subsystems W11 + W12
W9 Subsystem depth (W13-15 compressed)
W10 Engineering W16 + W17
W11 Capstone: write and send
W12 Capstone: revise; then wait
"I only care about X"
| Goal | Minimum path |
|---|---|
| Understand how the kernel works, no contribution | W0–W8, then W11–W15. Stop. That is a complete, satisfying unit. |
| Write drivers for hardware you own | W0–W8, then W12 + the device model and firmware/platform |
| Get a patch merged, minimum path | W0–W2, W9–W10, W18–W19. Fast, and you will be a worse contributor for skipping the middle. |
| Kernel debugging and performance work | W0–W6, then W16–W17 |
| eBPF / observability | W0–W6, W12, then the networking and scheduler chapters |
| Kernel security research | W0–W8, then security + W16 (syzkaller) |
Weeks 0–8 are the part nobody should skip. Everything else is a route through them.
Keeping Yourself Honest
Weekly, ten minutes:
- Did I write predictions before every experiment this week?
- Can I explain everything I built, or only run it?
-
Did I run this week's work under
lab-paranoidat least once? -
Is my source tree clean? (
git status --short— a forgotten edit will cost you a day.) - Did I commit? The git history is a capstone deliverable.
- Is there a patch of mine in flight? If not, why not?
At every gate: re-read the gate line and check it honestly. "Mostly" is a no.
When You Fall Behind
You will. The four common causes and their fixes:
| Cause | Symptom | Fix |
|---|---|---|
| The rig (week 1) | Every experiment feels expensive; you stop doing them | Stop the curriculum and fix the loop. Measure it. This is never wasted time. |
| Concurrency (week 3) | "It works on my machine"; splats you cannot read | Slow down. Re-run every experiment with -smp 8 and PROVE_LOCKING. Do not proceed until a lockdep splat reads like English. |
| Reading fatigue (weeks 12–15) | The subsystem chapters feel like they are not progress | They are the slowest-feeling and highest-value weeks. Switch to tracing one path with ftrace instead of reading — the code makes more sense after you have watched it run. |
| The wait (week 20+) | Momentum collapses after sending the capstone patch | This is the predictable one. Have the second target chosen before you send the first. |
And the meta-fix: the schedule is not the point. Twenty weeks is an estimate for a person with a job. If week 3 takes three weeks because you actually understood memory barriers, that is the plan working.
Next: The Teaching Method — the shape of every concept chapter and every lab, and the predict-first protocol.