This guide walks you through building a sustainable Linux kernel contribution workflow. We set up a local development environment, enforce quality checks before anything leaves your machine, and produce patches that respect reviewer time. The process works for both beginners and experienced developers and stays relevant long after any particular release cycle.
With the current mainline development tree (Linux 7.4-rc2 and the recent 7.3 stable series) seeing high patch volume, the steps below help you submit clean, well-tested changes. This reduces noise for maintainers while still letting you contribute effectively.
What You Need
- A Linux machine (Ubuntu 24.04/25.04, Fedora, or similar) with at least 50 GB free disk space and 16 GB RAM recommended
- Basic comfort with the terminal and Git
- An email account configured for plain-text messages (Gmail, Fastmail, or a dedicated kernel address)
- Familiarity with C is helpful but not required for the setup steps
We will create a working kernel tree, install the standard quality tools, and practice the full patch lifecycle on a small change.
Step-by-Step Guide
Step 1: Install the required tools
Start by installing the compilers, libraries, and kernel-specific helpers. These packages give you the build system plus the scripts used for style and static checking.
sudo apt update
sudo apt install -y build-essential libncurses-dev bison flex libssl-dev libelf-dev \
git git-email sparse coccinelle bc kmod cpio rsync wget
On Fedora the equivalent issudo dnf install gcc make ncurses-devel bison flex openssl-devel elfutils-libelf-devel git-email sparse coccinelle. After installation you have the classic toolchain plussparse(for type checking) andCoccinelle(for semantic patches).
Step 2: Clone a clean development tree
Clone the mainline repository so you work against current code. For day-to-day work many people also track linux-next, but the Torvalds tree is the right starting point.
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v7.4-rc2 # or the latest rc / stable tag you prefer
git checkout -b my-first-change
The branch keeps your work isolated. Always base new changes on a recent tag so you avoid conflicts with the ongoing merge window.
Step 3: Configure and do a smoke-build
Generate a default configuration and compile. This verifies your toolchain and produces a bootable kernel you can test later if needed.
make defconfig
make -j$(nproc) 2>&1 | tee build.log
A successful build ends with “Kernel: arch/x86/boot/bzImage is ready” (or the equivalent for your architecture). If the build fails, the log usually points to a missing library; reinstall the packages from Step 1.
Step 4: Make a small, well-scoped change
Pick a trivial but real improvement so you can practice the full flow. A common first change is a typo fix or a missing comment in a driver you care about. After editing, stage only the intended files.
git add path/to/file.c
git commit -s -m "drivers: example: fix typo in comment
Signed-off-by: Your Name "
The-sflag adds theSigned-off-byline required by the Developer Certificate of Origin. Keep the subject line under 75 characters and describe the “why” in the body.
Step 5: Run the official quality checks
Before generating a patch, run the kernel’s own style and static-analysis tools. These catch the majority of issues that would otherwise consume reviewer time.
./scripts/checkpatch.pl --strict -f path/to/file.c
make C=1 CHECK=scripts/checkpatch.pl path/to/file.o # sparse + checkpatch
# Optional deeper check
make coccicheck MODE=report
Fix every warning that is not a false positive. Clean output is the single biggest help you can give maintainers.
Step 6: Generate the patch series
Create a properly formatted patch that includes the cover-letter style information maintainers expect.
git format-patch -1 --cover-letter --signoff -o /tmp/patches
Open the generated files in a text editor. Confirm the subject, body, and Signed-off-by line are correct. For a multi-commit series use a higher number instead of-1.
Step 7: Identify the correct recipients
The kernel provides a script that reads the MAINTAINERS file and suggests the right mailing lists and people.
./scripts/get_maintainer.pl /tmp/patches/*.patch
Copy the output. Always include the subsystem list (for example linux-mm or linux-kernel) and the relevant maintainers. Never send a patch only to a personal address.
Step 8: Configure git send-email and send
Set up your SMTP details once, then use the tool that produces correctly threaded messages.
git config --global sendemail.smtpServer smtp.gmail.com
git config --global sendemail.smtpServerPort 587
git config --global sendemail.smtpEncryption tls
git config --global sendemail.smtpUser you@example.com
# Then send (replace with real addresses from get_maintainer)
git send-email --to=linux-kernel@vger.kernel.org \
--cc=maintainer@example.com /tmp/patches/*.patch
Use an app-specific password if your provider requires it. After sending, watch the list archive (lore.kernel.org) for replies and respond on the same thread.
Common Mistakes
- Missing Signed-off-by– Patches without it are ignored. Always use
git commit -sor add the line manually. - Sending to the wrong list– Rely on
get_maintainer.pl; guessing wastes everyone’s time. - Huge multi-purpose patches– One logical change per patch. Split unrelated fixes.
- Ignoring checkpatch warnings– Style issues that are easy for you to fix become review noise.
- Working on an outdated tree– Rebase onto the latest rc or linux-next before the final send.
- AI-generated code without review– Any automated suggestion must still pass the same checks and be fully understood by you before submission.
Final Check
Before you consider the workflow complete, verify the following:
- The tree builds cleanly after your change
checkpatch.pl --strictreports no new issues- The patch applies cleanly with
git amon a fresh clone of the same tag - Recipients match the output of
get_maintainer.pl - You have a local copy of the sent message and know where to watch for replies
If all of those pass, your contribution is ready for the mailing list.
Summary
You now have a repeatable process: a clean tree based on current mainline (7.4-rc2 or later), automated style and static checks, correctly formatted patches, and the right recipients. Following these steps keeps your own work high-quality and reduces the load on maintainers who already handle large volumes of submissions.
Next steps: practice on a real small fix in a subsystem you use, read Documentation/process/submitting-patches.rst in the tree, and subscribe to the relevant mailing list so you can see how other patches are discussed. Once the basic flow feels natural, explore sparse, Coccinelle, and kselftest for deeper validation.

