Subsystems
Foundations taught you to write kernel code. Contribution taught you to get it merged. Neither told you what to change, and that is the part that takes years.
This section is the bridge. You will read all eight domains at orientation depth, choose one, and go deep enough in it to have an opinion a maintainer would engage with.
Learning Objectives
| # | You will be able to |
|---|---|
| 1 | Apply a repeatable method to read any unfamiliar subsystem cold |
| 2 | Say, for each of the eight domains, what it does and where its code lives |
| 3 | Choose a subsystem to invest in, for reasons you can defend |
| 4 | Name the three to six core data structures of your chosen domain and how they relate |
| 5 | Trace one complete control path in it, end to end, with ftrace or GDB |
| 6 | Predict what an experiment in it will show — and be right most of the time |
| 7 | Identify three plausible contribution targets and say why each is plausible |
The Method
You will use this eight times. It is the same method from the mental model, expanded, and it is the single most transferable thing in this curriculum: it works on any large codebase, not just this one.
1. WHO OWNS IT?
./scripts/get_maintainer.pl --scm --status -f <dir>
git log --since="1 year ago" --format='%cN' -- <dir> | sort | uniq -c | sort -rn | head
Formal ownership from MAINTAINERS; actual activity from git log. They differ.
2. WHAT DOES IT SAY ABOUT ITSELF?
find Documentation -ipath '*<name>*' | head -20
Read the overview .rst before any .c file. In-tree docs ship with the code
they describe and are reviewed with it; a blog post does neither.
3. WHAT ARE THE NOUNS?
rg -n "^struct [a-z_]+ \{" <dir>/*.h include/linux/<name>*.h
A subsystem is 3-6 core structs and the relationships between them.
DRAW THEM before reading any function. If you cannot draw it, you have
not found the core structs yet -- keep looking.
4. WHAT ARE THE VERBS?
rg -n "struct [a-z_]+_ops \{" -A 30 <dir> include/linux/
Function-pointer tables ARE the architecture. For each one ask: who fills
it in, who calls through it, and what is the contract?
5. FOLLOW ONE PATH ALL THE WAY DOWN.
Pick an entry point -- a syscall, a probe(), an interrupt handler -- and
follow it to the hardware or to the return. ONE path, completely. Depth
beats breadth on the first pass, every time.
6. WHAT IS MOVING?
git log --oneline --since="6 months ago" -- <dir> | head -30
Recent churn tells you what is contentious, what is being rewritten, and
what is dead. Reading thirty commit subjects is twenty minutes and it is
the best twenty minutes you will spend.
7. HOW IS IT TESTED?
ls tools/testing/selftests/ | grep -i <name>
rg -l "kunit" <dir>
Tests are executable documentation of the contract, and gaps in them are
contribution opportunities.
8. WHAT COULD YOU NOT ANSWER?
Write down three questions the tree could not answer. Phrase them well
enough to ask on the list. That list is your entry point to the community.
Tip: Do not read a subsystem front to back. You will spend two weeks and retain a vague map. Steps 3 and 5 — the nouns, then one path — produce a usable model in a day, and everything else attaches to it afterwards.
The Eight Domains
| Domain | Code | The idea that unlocks it | Hardware you need |
|---|---|---|---|
| CPU / scheduler | kernel/sched/ | Scheduling classes are a priority-ordered chain of policies; the fair class is one link | None — QEMU is enough |
| Memory management | mm/ | Almost everything is a lie the MMU tells, maintained lazily by the fault handler | None |
| Storage | block/, fs/, drivers/nvme/ | VFS is a set of function-pointer tables; a filesystem fills them in | None (virtio-blk) |
| Networking | net/, drivers/net/ | One sk_buff travels the whole stack; layers move its pointers rather than copying | None (virtio-net, veth) |
| Graphics | drivers/gpu/drm/ | The kernel does memory management and modesetting; rendering is Mesa's job | vkms needs none; real work wants a GPU |
| Security | security/ | LSMs do not implement policy; they are hooks where a policy can say no | None |
| AI / accelerators | drivers/accel/, drivers/gpu/drm/ | An NPU is a GPU with the display parts removed — hence DRM's infrastructure | Ideally an NPU; readable without |
| Firmware / platform | drivers/firmware/, drivers/acpi/, drivers/of/ | Device tree and ACPI answer the same question for two different worlds | QEMU -M virt is a real platform |
Reading order for the survey
Do the four in this section first — they are the ones every other subsystem touches. A graphics driver allocates memory, sleeps, takes interrupts, and DMAs; understanding memory and the scheduler makes it readable. The reverse is not true.
Choosing One
Depth in one subsystem is what makes you useful. Breadth across eight is what lets you tell which one. Spend a week on the survey and then commit.
The criteria that actually predict success, in order:
| # | Criterion | How to check |
|---|---|---|
| 1 | Is it active? | git log --oneline --since="6 months ago" -- <dir> | wc -l. Under ~50 and you will wait a long time for review. |
| 2 | Are maintainers responsive? | Read a month of the list on lore. How long between a patch and its first reply? |
| 3 | Do you have the hardware? | You cannot meaningfully debug a driver for something you do not own. Column 5 above. |
| 4 | Is there work at your level? | Are there small, complete, un-owned things — or is everything a six-month rewrite? |
| 5 | Do you find it interesting? | Last, but not zero. Months of evenings need some pull. |
Warning: Do not choose the subsystem that sounds most impressive. Choose the one where you can plausibly get a patch merged this quarter. A merged patch in
drivers/firmware/teaches you more than eight months of readingmm/and sending nothing — and once you have the workflow and a maintainer who knows your name, moving to a harder area is much easier.
The honest difficulty ranking
Not a ranking of importance — of how hard it is to make a first contribution.
| Easier | Why |
|---|---|
| Firmware / platform | Self-contained drivers, clear bindings, lots of small real gaps |
| Storage (drivers) | Well-defined interfaces; a bug is usually reproducible |
| Security | Small subsystem, readable, security/loadpin/ is a hundred lines |
Graphics (vkms) | A virtual driver you can run anywhere, actively maintained, welcoming |
| Networking (drivers) | Huge surface, so lots of small work — but netdev is strict |
| Accelerators | Young, moving fast, few contributors — but hardware-gated |
| Memory management | Small, dense, extremely high review bar, everything is performance-sensitive |
| Scheduler | The hardest. Every change is contentious, benchmarked, and argued about for months. |
mm/ and kernel/sched/ are the two where a newcomer's patch is most likely to be correct and still
rejected, because the bar is not correctness — it is "does this help enough to be worth the risk to
every Linux machine in the world".
What a Good First Contribution Looks Like
Per-subsystem specifics are in each index.md. The general shapes:
| Shape | Why it works |
|---|---|
| A documentation fix you can prove | You verified a claim against the code and it was wrong. Real, checkable, welcome. |
| A selftest for existing behavior | Tests are always under-supplied; adding one requires understanding, not invention |
A Fixes:-able bug with a reproducer | The reproducer does the arguing for you |
| A mechanical conversion, one patch per driver | Deprecated API, missing MODULE_DESCRIPTION, an unchecked return — Coccinelle finds them |
| A syzbot bug nobody has claimed | Public, reproducible, and the analysis is half done |
| Support for a device you own | Nobody can argue you should not have it |
And the shapes that reliably fail:
| Shape | Why it fails |
|---|---|
| A performance optimization with no measurement | "Show me the numbers" — and see Engineering |
| A refactor for readability | Churn with no upside; reviewers pay the cost |
Fixing a TODO/FIXME | It is there because it is hard, contentious, or blocked |
| A new interface for your use case | uapi is forever; the bar is very high |
A checkpatch sweep of code you have not read | Review load, risk, no benefit |
Section Structure
Each of the eight has the same shape:
| File | Contains |
|---|---|
index.md | Why it matters, where the code is, who maintains it, the structures, how to read it, what good first contributions look like |
concepts/*.md | Three chapters in the six-part treatment |
labs/*.md | One or two in the eleven-part template |
Every subsystem chapter opens by making you run these two, because a table in a book goes stale and your tree does not:
git log --oneline --since="6 months ago" -- <dir> | head -30
./scripts/get_maintainer.pl -f <dir>
Deliverables
- The eight-step method applied to a subsystem you have never read, producing a written map another engineer could use.
- The same, timeboxed to two hours, on a second subsystem. (The gap between the two is the skill you just acquired.)
- All eight orientation chapters read; one sentence each on what it does and where it lives.
- One chosen, with a written justification against the five criteria.
- For your chosen subsystem: all concept chapters read with validation questions answered, and the labs done.
- One complete control path traced with ftrace or GDB, and your written trace matches the code.
-
Subscribed to its list (or reading it on
lore), and you can name three threads from the last month. - Three plausible contribution targets, written down, each with why it is plausible and who owns it.
Validation / Self-check
- Give the eight steps of the reading method in order, and say which two produce a usable model fastest.
- Why nouns before verbs? Why one path before breadth?
- What is the difference between
MAINTAINERSownership and actual activity, and how do you measure each? - Name the eight domains and, for each, one sentence on what it does and where its code lives.
- Give the five criteria for choosing a subsystem, in order. Which one do people over-weight?
- Why are
mm/andkernel/sched/the hardest places to make a first contribution, given that the code is small? - Name four shapes of good first contribution and two that reliably fail.
- For your chosen subsystem: what are its three to six core structs, and how do they relate?
- What three questions could the tree not answer for you? Are they phrased well enough to ask?
Next: CPU and the Scheduler — start here even if you intend to specialize elsewhere, because everything else in the kernel is scheduled by it.