The Kernel Is More Than Code
Office Hours and First Impressions
The Linux Kernel Bug Fixing Program runs for 24 weeks — long enough to span more than one kernel release. That alone says something. This isn’t a sprint. It’s designed to follow the pace of real kernel development: consistent, deliberate, and time-based, not feature-driven.
There are 49 mentees in total, including myself. We meet weekly for Office Hours — a one-hour, all-hands session led by the mentor, Shuah Khan. Attendance isn’t mandatory, but it’s easily the most valuable opportunity to ask questions, notice patterns, and observe how someone with deep kernel experience thinks.
At our very first session, Shuah answered every question — clearly, generously. But one message stood out, and it hasn’t left me since:
Start slow. Build credibility.
It didn’t sound like advice. It felt like a principle — something to return to when the direction isn’t yet clear. That one idea helped reset my focus: I’m not here to rush toward a patch or chase a place in the tree. I’m here to learn how to contribute responsibly — by observing, understanding, and taking care in how I participate.
Seeing Beyond the Code
At this stage, writing patches isn’t the focus. There’s no concrete plan to fix or change anything yet — and that feels right. Before contributing, it makes more sense to spend time reading, tracing, and trying to understand how the kernel holds together.
Books have been helpful along the way. Some explain subsystems clearly, with diagrams and structured reasoning. They offer a conceptual entry point. But reading the code is different. It doesn’t follow a clean narrative. It reflects real complexity — decisions made over time, patterns that evolved, edge cases accounted for without comment. Nothing is pre-digested.
One thing has become clear through this process: the kernel isn’t just code, and it isn’t just documentation. What gives it structure is the relationship between the two — how implementation, comments, configuration, and review history all inform one another. Behavior lives in the code, but intent often appears elsewhere — in Kconfig files, archived mailing list threads, test cases, or even a subtle revision made years ago.
Books describe how things are designed to work. The code shows how they’re actually maintained.
So for now, reading continues — not to prepare a patch, but to understand what sustains the kernel. Not just how it works, but how it stays working.
Understanding Is Not the Same as Proof
Reading code builds understanding. It's possible to follow the flow, trace the structs, and see what each part is doing. That clarity matters — but it has limits.
Knowing how code works is not the same as proving that it works — or that it still works after change. Logic might appear sound, but behavior exists in context. And context is fragile.
Proof doesn’t come from confidence. It comes from validation — from tests that reflect real use, from results that hold across environments, from behavior that can be checked, reproduced, and trusted.
That’s where the line becomes clear. Reading builds a mental model. But confidence in that model isn’t enough. What matters is whether it holds under pressure — whether others can rely on it. Understanding is the beginning. Trust comes from demonstrating that the understanding stands.
Credibility Is Earned, Not Claimed
It’s easy to focus on the patch itself — the lines added or removed, the logic corrected, the style made consistent. But what’s become clearer over time is that a good patch isn’t just about code. It’s about trust.
What matters just as much — maybe more — is how the work is done. Was the change understood deeply? Was it tested in a way that reflects how the kernel is actually used? Was it communicated clearly, with respect for the subsystem and its maintainers? Was there follow-up, revision, and willingness to adapt?
A patch that gets accepted doesn’t automatically make the contributor credible. That credibility is earned over time — through small changes handled carefully, through responses to feedback, through an effort to reduce the burden on others rather than add to it.
That’s the kind of contributor I want to become. Not someone chasing cleverness, but someone who takes responsibility. Someone others can trust to leave the code better, not just different.
Not a Place — A Direction
I’ve often heard that it’s important to choose a subsystem — to find a specific part of the kernel to focus on and contribute to over time. That advice makes sense. Context matters, and deep understanding doesn’t come from drifting between unrelated parts.
But right now, choosing a fixed area feels early. I don’t have enough experience to make that decision in a meaningful way. It would feel like picking a destination before knowing which way I’m facing.
What I do have is a sense of direction — shaped by what keeps drawing my attention. Certain code paths raise questions. Some files pull me back more than once. That’s what I’ve been following. Not a predefined area, but a repeated pull toward what I want to understand next.
That might eventually point toward a specific subsystem. Or it might keep shifting until something clicks. Either way, I’m not trying to map it out too early. I’d rather let the direction emerge from what stays interesting — not from trying to meet someone else’s idea of where I should focus.
The kernel is too large to grasp all at once. But by following what holds my attention, a path is beginning to form — not by choosing it, but by walking it.
Curiosity First — Not a Roadmap
There are plenty of learning paths out there — books, tutorials, guides, and now even AI-generated explanations that try to suggest what to read first, what to write next, and how to contribute. That kind of structure can be helpful. But for me, it’s never been the starting point.
The questions that matter don’t come from following a plan. They come from curiosity.
Sometimes it’s a macro in a header that doesn’t quite make sense. Sometimes it’s a subtle shift in behavior, or a function name that leads deeper than expected. Those small details catch my attention — and that’s usually when the real learning starts.
That’s also when documentation becomes useful. Not before. Books, blogs, and AI tools are helpful — but only when there’s already a reason to care, when something in the code doesn’t quite add up and needs explaining.
A fixed roadmap might offer direction, but not meaning. Letting curiosity lead feels slower, but it keeps things real. That’s how I want to keep learning — by following the questions that actually matter to me.
Validation Is the Language of Trust
The more I read kernel code, the more I start to notice what surrounds it — not just implementation details, but signs of how that code is trusted.
That trust doesn’t come from clarity alone. It comes from validation.
I haven’t run any kernel tests yet, but it’s already clear that testing isn’t an extra step. It’s part of how the system stays reliable. Fuzzing has its place, but it isn’t enough on its own. Structured test cases — written with intent, tied to real behavior — are what make changes dependable. They communicate what matters, what must not break, and what assumptions other parts of the system rely on.
Without tests, it’s harder to know whether a change preserves meaning or just preserves syntax. Even well-written code can fail quietly if nothing checks that it still does what it claims to.
Understanding how things work is one step. Knowing how that behavior is protected — and how others come to trust it — is the next. That’s what I want to learn: not just how to change code, but how to show that it still holds.
The Kernel Maintains Itself
One thing I’ve come to see more clearly over time is that the kernel isn’t just maintained by people — it’s maintained through structure.
There’s a system built around the code. Documentation explains design and expectations. Tests catch breakage and protect behavior. Reviews ensure that changes align with subsystem norms and long-term direction. Mailing lists play a central role — not just for sending patches, but for sharing context, raising concerns, reviewing history, and making decisions visible to others. Scripts and automated tools reinforce consistency and help scale that process across contributors.
None of this is perfect, but it’s resilient — not because anyone understands everything, but because the structure ensures no one has to. Coordination doesn’t depend on individuals alone. It’s embedded in the way the kernel operates.
As someone new to this, I’ve started to see that participating in that system matters more than just writing code. The goal isn’t to submit a patch and move on. It’s to contribute in a way that fits — a way that respects what’s already working.
Learning how the kernel maintains itself is part of learning how to contribute responsibly.
Looking Ahead — Steady and Intentional
The program has its goals — sending patches, getting changes merged into mainline. That’s part of what it means to complete it.
But at this stage, that’s not the immediate goal.
Right now, the focus is on learning how to contribute responsibly. Not by rushing to make a mark, but by taking time to understand what the kernel expects — and why. That means reading more. Tracing behavior. Following discussions. Running tests. Making small changes, when ready, that are careful, clear, and useful to others.
The goal in the coming weeks is to build credibility — not by claiming it, but by doing the kind of work that earns it. Quiet, steady, and intentional.
That’s what I’m working toward next — staying present, learning carefully, and building credibility the way the kernel expects it: slowly and deliberately.