L10: Linux Kernel Source Tree


← Previous Lecture
Chapter 2 — Part 1 of 2
Next Lecture →

Linux Kernel Source Tree

A guided tour of what lives where — and why every kernel developer must know this

⏱ ~20 min read
🧑‍💻 Beginner Friendly
🖥 Kernel 6.x Updated

🎯 What You Will Learn

This free Linux kernel programming lecture covers everything a beginner needs to understand the Linux kernel source tree layout. By the end you will know:

  • How the Linux kernel source code is organized into directories
  • What each major folder actually does — in plain English
  • Why the kernel uses GPL-2.0 and what that means for you as a developer
  • How many CPU architectures the Linux kernel supports
  • Which tools help you navigate 35+ million lines of kernel code

Keywords in This Lecture

Linux kernel source tree
free Linux kernel programming course
kernel directory layout
GPL-2.0
free Linux device drivers course
arch/ drivers/ mm/ fs/
free embedded systems course
kbuild system

1. Before We Start — A Simple Analogy

Imagine you join a company with thousands of employees. On your first day someone hands you a huge building map and says “everything you need is in here.” Overwhelming, right? But the moment you learn that Floor 1 is HR, Floor 2 is Engineering, Floor 3 is Finance — it all clicks.

The Linux kernel source tree is exactly like that building. Millions of lines of code live inside it, but once you know which folder holds what, you stop feeling lost. This free Linux kernel programming lecture walks through every floor of that building together.

💡 Quick Fact — How Big Is the Kernel?

As of kernel 6.x, the Linux source tree contains over 35 million lines of code spread across 70,000+ files. Understanding directory layout is not optional — it is your survival skill as a kernel or device driver developer.

2. Getting the Linux Kernel Source

The official home for Linux kernel source code is kernel.org. You can either clone the Git repository or download a tarball of any stable version. Here is the simplest way to get the latest stable source on Ubuntu:

Downloading the Linux Kernel Source

# Option A: Clone the stable kernel Git tree (~3-4 GB download)
git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git# Option B: Download a specific version tarball (much smaller)
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.9.tar.xz
tar -xf linux-6.9.tar.xz
cd linux-6.9

Once extracted, run ls at the top level. You will see something like this:

Top-Level Directory Listing — Linux 6.x

arch/ block/ certs/ crypto/ Documentation/
drivers/ fs/ include/ init/ ipc/
kernel/ lib/ mm/ net/ samples/
scripts/ security/ sound/ tools/ usr/
virt/ Makefile Kconfig COPYING CREDITS

Every one of these directories has a clear purpose. Let us go through them in two groups: Core Subsystems and Infrastructure and Support.

Linux Kernel Source Tree — Visual Map

linux-6.x/
|
+– arch/ [ CPU-specific code: x86, ARM, RISC-V, … ]
+– drivers/ [ Device drivers: USB, I2C, SPI, GPIO, BT, … ]
+– kernel/ [ Core OS: scheduler, syscalls, signals, timers ]
+– mm/ [ Memory management: paging, slab, OOM killer ]
+– fs/ [ Filesystems: ext4, btrfs, FAT, VFS layer ]
+– net/ [ Networking: TCP/IP, Bluetooth, WiFi ]
+– ipc/ [ IPC: shared mem, message queues, semaphores ]
+– sound/ [ Audio: ALSA, USB audio, I2S codecs ]
+– virt/ [ Virtualization: KVM hypervisor ]
+– crypto/ [ Crypto: AES, SHA-256, RSA, ChaCha20 ]
+– include/ [ Kernel headers: #include <linux/module.h> ]
+– init/ [ Boot entry: start_kernel() lives here ]
+– lib/ [ Kernel library: strings, compression, bitmaps ]
+– scripts/ [ Build scripts, style checker, patch tools ]
+– security/ [ LSM: SELinux, AppArmor, Landlock, Yama ]
+– tools/ [ Userspace tools: perf, GPIO tools, USB tools ]

3. Core Subsystem Directories in the Linux Kernel Source Tree

These directories are where the action happens in the free Linux kernel development world — scheduling, memory, drivers, networking, and filesystems.

kernel/ — The Brain of the OS

This directory contains the core mechanisms that make Linux an OS: the process scheduler, system calls, signals, timers, and kernel threads. Without this, nothing else in the system works.

Notable files every free Linux kernel programming student should know: kernel/sched/core.c (the scheduler), kernel/signal.c (signal handling), kernel/sys.c (system calls).

mm/ — Memory Management

Everything related to RAM lives here — how it is allocated, freed, and shared. Topics like virtual memory, paging, slab allocator, OOM (Out Of Memory) killer, and memory-mapped files are all implemented inside mm/.

In embedded systems, understanding mm/ is critical because you work with constrained RAM and must avoid fragmentation at all costs.

fs/ — Filesystems

Linux supports a huge range of filesystems — ext4, btrfs, tmpfs, FAT, NFS, and many more. Each filesystem is a subdirectory inside fs/. The VFS (Virtual Filesystem Switch) abstraction layer also lives here, which is what allows the same open(), read(), and write() system calls to work regardless of which filesystem is underneath.

Embedded developers often work with fs/squashfs, fs/jffs2, and fs/ubifs for flash storage targets.

drivers/ — Device Drivers

The biggest directory in the entire source tree. It contains device drivers for almost every type of hardware — USB, PCI, I2C, SPI, GPIO, network cards, displays, Bluetooth, and much more. As a student in a free Linux device drivers course, you will spend most of your time here.

Key subdirectories: drivers/bluetooth/, drivers/net/, drivers/gpio/, drivers/i2c/, drivers/spi/.

net/ — Networking Stack

The entire networking stack lives here — TCP/IP, sockets, Bluetooth protocol stack (BlueZ core), WiFi subsystem (mac80211), and netfilter (firewall). If a packet travels through Linux, the code that processes it is inside net/.

For BLE and Bluetooth developers: net/bluetooth/ is where HCI, L2CAP, and the GATT core are implemented at the kernel level.

ipc/ — Inter-Process Communication

This directory contains the kernel-side implementation of shared memory, message queues, and semaphores (both System V IPC and POSIX). When two processes on the same machine need to exchange data, the code that makes it happen lives here.

sound/ — Audio Subsystem

The complete audio subsystem. The modern Linux audio stack is called ALSA (Advanced Linux Sound Architecture). Everything from USB audio to embedded I2S audio codecs is implemented through the sound/ directory.

virt/ — Virtualization

Virtualization support lives here. This is the home of KVM (Kernel-based Virtual Machine) — Linux’s built-in hypervisor that lets virtual machines run at near-native speed. If you have ever used QEMU on Linux, KVM is what makes it fast.

4. Infrastructure and Support Directories

These directories do not run “on” hardware directly, but they are the glue that holds the entire kernel together — headers, crypto, security, scripts, and architecture-specific code.

arch/ — CPU Architecture-Specific Code

Each supported CPU family has its own subfolder inside arch/. This is where boot code, memory layout, interrupt handling, and system call entry points differ from one chip family to another. Linux is one of the most ported operating systems in history.

Linux 6.x — Supported CPU Architectures in arch/

$ ls arch/
alpha/ arm/ arm64/ arc/
csky/ hexagon/ loongarch/ m68k/
microblaze/ mips/ nios2/ openrisc/
parisc/ powerpc/ riscv/ s390/
sh/ sparc/ um/ x86/
xtensa/NOTES for kernel 6.x vs older reference books:
loongarch/ — Added in kernel 5.19 (NOT in older books)
c6x/ — Removed in kernel 6.1 (was in older books)
nds32/ — Removed in kernel 6.1 (was in older books)
unicore32/ — Removed in kernel 5.17 (was in older books)Active arches for embedded work today:
arm — Most IoT and SBC boards (Raspberry Pi 3 and older)
arm64 — Modern SBCs (Raspberry Pi 4/5, Jetson, etc.)
riscv — Growing fast (SiFive, StarFive boards)
mips — Routers, older embedded boards

📌 Key Insight — One Kernel Source for Everything

There is one unified kernel source for all platforms. You are not downloading a different kernel for your ARM Raspberry Pi vs your x86 laptop. It is the same source code — compiled differently with architecture-specific code pulled from the right arch/ subfolder. This is what makes the free Linux kernel programming model so powerful and versatile.

crypto/ — Cryptographic Algorithms

Cryptographic algorithms implemented at the kernel level. AES, SHA-256, RSA, ChaCha20 are all here. These are consumed by the networking stack (TLS/IPsec), disk encryption (dm-crypt), and any kernel subsystem that needs secure hashing or encryption.

include/ — Kernel Headers

All architecture-independent kernel header files live here. When you write a kernel module and add #include <linux/module.h>, that file comes from include/linux/module.h. Architecture-specific headers live under arch/<cpu>/include/.

init/ — The Kernel Boot Entry Point

The closest thing the kernel has to a main() function is inside init/main.c. The function is called start_kernel() and it is the first C code the kernel executes after very early architecture-specific assembly boot code.

Studying init/main.c is one of the best ways to understand the kernel boot sequence — you can trace every subsystem being initialized in order just by reading through it.

lib/ — The Kernel’s Standard Library

The kernel cannot use glibc (the C library used by userspace programs), so it has its own implementations inside lib/: string routines, compression/decompression, bitmap operations, CRC algorithms, sorting, and linked list helpers. Unlike a normal shared library, this code is statically compiled directly into the kernel image. There are no .so files in kernel land.

scripts/ — Build and Helper Scripts

Build scripts, Perl scripts, and helper tools. Many are used internally during the kernel build. Others help with checking coding style, static analysis, and finding the right maintainer to send a patch to.

Finding the Right Maintainer for a Patch

# Who maintains the Bluetooth drivers? Run this:
$ scripts/get_maintainer.pl -f drivers/bluetooth/# Output shows names and emails of the right maintainers
# Note: must be run on a Git tree clone, not a tarball

security/ — Linux Security Modules

The kernel’s security framework lives here. LSM (Linux Security Modules) is a flexible hook-based system that lets security policies be enforced at the kernel level without modifying the core kernel code.

LSMs Available in Linux 6.x

SELinux — Used on Android and RHEL; Mandatory Access Control
AppArmor — Default on Ubuntu; path-based access control
Smack — Simplified Mandatory Access Control Kernel
Tomoyo — Lightweight path-based MAC
Yama — Restricts ptrace() scope system-wide
Integrity — IMA: Integrity Measurement Architecture
Landlock — NEW in 5.13: Unprivileged sandboxing for apps
SafeSetID — NEW: Restricts which UIDs/GIDs a process can switch toNOTE: Landlock and SafeSetID are NOT in older reference books.
They are active in all modern kernel 6.x installs.

tools/ — Userspace Tools Coupled to the Kernel

Userspace tools that interact so deeply with kernel internals that they live inside the kernel source itself. The most famous is perf — the Linux performance profiler. GPIO test tools, USB gadget utilities, and networking tools also live here.

5. Linux Kernel Licensing — GPL-2.0 and What It Means for You

The Linux kernel is released under the GNU General Public License version 2 (GPL-2.0). This is one of the most important things to understand if you plan to do any commercial kernel or embedded Linux work. The GPL-2.0 governs the entire Linux kernel source tree.

✅ What GPL-2.0 Allows

  • Use the kernel freely for any purpose including commercial products
  • Study and modify the source code
  • Distribute the kernel to others
  • Release kernel modules under a dual license (e.g. BSD/GPL)

⚠ What GPL-2.0 Requires

  • If you modify the kernel and distribute a product, you must share your source code
  • Derivative works must also be released under GPL-2.0
  • You cannot secretly keep kernel modifications proprietary

In the real world, many products run on Linux and have proprietary components. Companies navigate this by writing their proprietary code as Loadable Kernel Modules (LKMs). Whether a closed-source LKM truly complies with GPL-2.0 is legally debated, but the kernel community strongly discourages it.

⚠ Important for Embedded Linux Developers

If your company builds a product using the Linux kernel and you modify kernel code — you are legally required to release those modifications under GPL-2.0 when you distribute the product. Many responsible embedded Linux companies publish their kernel patches publicly.

6. Navigating the Linux Kernel Source Tree — Practical Tools

With 35+ million lines of code, you cannot just use grep and hope for the best. Here are the tools every serious kernel developer uses in this free Linux kernel development course and beyond:

ctags — Function and Variable Index

Creates an index of every function and variable in the source. Works with Vim, VS Code, Emacs, and most editors for instant jump-to-definition navigation.

Build ctags Index

cd linux-6.9/
make tags
# In Vim: place cursor on a function name, press Ctrl+] to jump
# Press Ctrl+T to jump back

cscope — Interactive Source Browser

An interactive browser for the kernel source. Lets you find all callers of a function, all places a variable is used, and all files that include a particular header.

Build cscope Database

make cscope
# Launch the interactive browser:
cscope -d
# Press Ctrl+D to exit

Elixir Cross Referencer — Best Web-Based Tool

Available at elixir.bootlin.com — browse any kernel version online with one click, jump to any function definition, see all callers, no local setup needed. Highly recommended for beginners in this free Linux kernel programming course because there is nothing to install.

VS Code + clangd — Modern IDE Approach

Use VS Code with the clangd language server extension and a compile_commands.json file generated during the kernel build. This gives you intelligent code navigation, inline documentation, and error detection as you type.

Generate compile_commands.json for clangd

# After running make, generate the compile commands file:
make compile_commands.json# Open the linux-6.x/ folder in VS Code
# Install the clangd extension, it auto-picks up the file

7. Quick Reference — Linux Kernel Source Tree Directory Summary

Linux Kernel Source Tree — All Directories at a Glance

Directory | What it Contains | Most Relevant To
————|—————————————-|———————————
arch/ | CPU boot, interrupts, syscall entry | Board bring-up / embedded dev
drivers/ | Device drivers for all hardware | Driver developer (most of us!)
kernel/ | Scheduler, syscalls, signals, timers | OS internals / kernel engineer
mm/ | Virtual memory, paging, slab, OOM | Embedded dev (RAM is precious)
fs/ | Filesystems: ext4, btrfs, FAT, VFS | Storage / flash developer
net/ | TCP/IP, Bluetooth, WiFi stacks | Networking / BLE engineer
ipc/ | Shared mem, message queues, semaphores | Systems programmer
sound/ | ALSA, USB audio, I2S codecs | Audio / embedded audio dev
virt/ | KVM hypervisor | Virtualization engineer
crypto/ | AES, SHA, RSA, ChaCha20 | Security / networking dev
include/ | Kernel headers (#include linux/…) | Kernel module developer
init/ | start_kernel() boot entry point | Anyone studying boot sequence
lib/ | Kernel library: strings, bitmaps, CRC | Anyone writing kernel code
scripts/ | Build tools, style checker, patch help | Any contributor
security/ | LSM: SELinux, AppArmor, Landlock | Security-focused developer
tools/ | perf, GPIO test tools, USB tools | Performance / debug engineer

📌 Key Takeaway from This Free Linux Kernel Programming Lecture

You do not need to memorize every directory. The real skill is knowing which directory to look in when you face a problem. With practice, “there is a Bluetooth issue” immediately maps to net/bluetooth/ and drivers/bluetooth/. Start by exploring the directories most relevant to your current work. The rest follows naturally.

🎓 Interview Questions and Answers

Q1. Where does the Linux kernel’s boot sequence begin in C code?

The kernel’s early C entry point is the start_kernel() function located in init/main.c. Before this, architecture-specific assembly code inside arch/<cpu>/ handles very early CPU initialization. Once start_kernel() is called, it initializes every major kernel subsystem one by one in a fixed, documented sequence.

Q2. Is there a separate Linux kernel source for embedded devices vs servers?

No. There is a single unified Linux kernel source tree used for everything from a tiny IoT sensor to a cloud server with 1000+ CPU cores. The differences come from how the kernel is configured and compiled — which features are enabled, which drivers are included, and which architecture folder in arch/ is targeted.

Q3. What is an LSM and name three examples available in the Linux kernel?

LSM stands for Linux Security Module. It is a hook-based framework inside the security/ directory that lets security policies be enforced at the kernel level without touching core kernel code. Three examples: SELinux (used on Android and RHEL), AppArmor (default on Ubuntu), and Landlock (added in kernel 5.13, allows userspace apps to sandbox themselves without root privileges).

Q4. Can a company legally ship a closed-source Linux kernel driver?

This is a legally grey area. The kernel is GPL-2.0, which technically requires derivative works to also be GPL-2.0. Some companies release proprietary drivers as Loadable Kernel Modules (LKMs) anyway. Whether this truly complies with the GPL-2.0 is debated. The kernel community officially marks such modules as “tainted” and strongly discourages the practice. The safest approaches are to open-source the driver or use an official dual-license arrangement.

Q5. If you write a Bluetooth kernel driver, in which two directories would your code live?

Protocol-level code (HCI, L2CAP, GATT core) belongs in net/bluetooth/. The hardware-specific driver for a particular chip (a USB Bluetooth dongle, a UART-attached controller) belongs in drivers/bluetooth/. This clean separation between protocol logic and hardware-specific logic is a key design principle of the Linux kernel source tree.

Q6. Why cannot the kernel use glibc or any standard C library?

glibc is a userspace library that depends on the kernel itself for services like mmap() and read(). The kernel is the lowest software layer — nothing underneath it can provide those services. So the kernel has its own implementations inside lib/: string routines, sorting, compression, CRC, and bitmap operations. Unlike glibc, all of this code is statically compiled into the kernel image.

Q7. What is the difference between arch/ and drivers/ in the kernel source tree?

arch/ contains code that is specific to a CPU family — how that architecture boots, handles interrupts, and implements system call entry. drivers/ contains code for specific hardware devices and is largely architecture-independent. A single Bluetooth driver in drivers/bluetooth/ can work on x86, ARM64, and RISC-V without modification because the arch/ layer abstracts all CPU differences away.

← Previous Lecture
Chapter 2 — Part 1 of 2
Next Lecture →

EmbeddedPathashala — Free Embedded Systems Education — embeddedpathashala.com

Leave a Reply

Your email address will not be published. Required fields are marked *