Kernel Contribution
Chapter 19: Linux Kernel Development and Community Contribution
Submitting a patch to the Linux kernel is a technical milestone for many engineers. The kernel community is large and process-driven, yet welcoming to newcomers who follow established conventions. This chapter covers the full pipeline: acquiring sources, building the kernel, understanding coding standards, checking code with checkpatch.pl, generating patches with git format-patch, sending them to the LKML via git send-email, and earning maintainer acceptance.
1. Getting Started: Barriers and Opportunities
The fundamental difference between kernel and application development is the execution environment: kernel code runs in privileged mode with no standard library, no memory protection, and no floating-point arithmetic. A null pointer dereference does not produce a segfault โ it triggers a kernel panic. This demands deep understanding of hardware and OS internals.
Despite the high bar, the kernel community offers many contributor-friendly entry points. You do not have to start by writing a new driver or implementing a new subsystem. Recommended beginner paths include:
- Documentation improvements โ fix typos, add examples, translate docs โ minimal risk, fast maintainer review
- drivers/staging cleanup โ staging drivers have uneven quality with TODO comments everywhere โ ideal for beginners
- checkpatch warning fixes โ run checkpatch.pl across the tree and fix coding style warnings
- Coccinelle semantic patches โ use Coccinelle scripts to automate bulk code transformations (e.g., merging kzalloc+memset into kcalloc)
- sparse static analysis fixes โ
make C=1invokes sparse for type annotation checking โ fix the findings
Why contribute: Your code runs on billions of devices worldwide. Kernel Newbies data shows most contributors who get their first patch accepted keep contributing. A commit record in Linus's tree is also a powerful resume entry.
2. Acquiring the Kernel Source
The Linux kernel has multiple official trees. Beginners should understand what each is for:
| Tree | URL | Purpose |
|---|---|---|
| mainline | kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git | Linus's mainline, releases rc versions |
| linux-next | kernel.org/pub/scm/linux/kernel/git/next/linux-next.git | Integration of all subsystem next branches; base your patches here |
| stable | kernel.org/pub/scm/linux/kernel/git/stable/linux.git | Stable release maintenance and backported critical fixes |
| Subsystem trees | Maintained by respective maintainers | e.g. net-next (networking), drm-next (GPU) |
# ๅ
้ linux-next๏ผไฝฟ็จ --depth=1 ่็ๆถ้ด๏ผๅฎๆดๅๅฒ็บฆ 4GB๏ผ
git clone --depth=1 \
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git \
linux-next
cd linux-next
# ๅฆๆๅ็ปญ้่ฆๅฎๆดๅๅฒ๏ผ็จไบ git log / git blame๏ผ
git fetch --unshallow
# ๆทปๅ stable ๆ ไฝไธบ่ฟ็จไปๅบ
git remote add stable \
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
# ๆฅ็ tag ๅ่กจ๏ผๅ
ๆ ธ็ๆฌๅท๏ผ
git tag -l 'v6.*' | sort -V | tail -20
3. Building the Kernel
Install Build Dependencies
# Debian / Ubuntu
sudo apt-get install -y \
build-essential libelf-dev libssl-dev \
flex bison bc dwarves pahole \
libncurses-dev pkg-config
# Fedora / RHEL
sudo dnf install -y \
gcc make flex bison elfutils-libelf-devel \
openssl-devel ncurses-devel bc dwarves
Kernel Configuration
# ๆนๅผ1๏ผๅพๅฝขๅ TUI ่ๅ๏ผๆจ่ๆฐๆ๏ผ
make menuconfig
# ๆนๅผ2๏ผไฝฟ็จๆถๆ้ป่ฎค้
็ฝฎ๏ผ้ๅๅฟซ้้ช่ฏ่กฅไธ๏ผ
make defconfig
# ๆนๅผ3๏ผๅบไบๅฝๅ่ฟ่กๅ
ๆ ธ็้
็ฝฎ๏ผๅช็ผ่ฏๅทฒๅ ่ฝฝๆจกๅ๏ผ้ๅบฆๆๅฟซ๏ผ
make localmodconfig
# ไนๅๆๅฝๅๅ
ๆ ธ config ๅคๅถ่ฟๆฅ
cp /boot/config-$(uname -r) .config
make olddefconfig # ๅฏนๆฐๅข้้กน้็จ้ป่ฎคๅผ
# ไป
ไฟฎๆนๅไธช้
็ฝฎ้กน๏ผไธๆๅผ่ๅ๏ผ
./scripts/config --enable CONFIG_DEBUG_INFO
./scripts/config --disable CONFIG_SECURITY_SELINUX
make olddefconfig
Build and Install
# ๅนถ่ก็ผ่ฏ๏ผnproc ่พๅบ CPU ๆ ธๅฟๆฐ๏ผ็ผ่ฏๆถ้ด้ๆบๅจ่ๅผ๏ผ็บฆ10ๅ้ๅฐ1ๅฐๆถ๏ผ
make -j$(nproc)
# ็จ ccache ๅ ้ไบๆฌก็ผ่ฏ๏ผ้ฆๆฌก็ผ่ฏๅๆๆๆๆพ๏ผ
sudo apt-get install -y ccache
CC="ccache gcc" make -j$(nproc)
# ๅฎ่ฃ
ๅ
ๆ ธๆจกๅ
sudo make modules_install
# ๅฎ่ฃ
ๅ
ๆ ธ้ๅ๏ผๅๆถๆดๆฐ initramfs ๅ GRUB๏ผ
sudo make install
# ๆๆๅจๅคๅถ
sudo cp arch/x86/boot/bzImage /boot/vmlinuz-$(make kernelrelease)
sudo update-grub
# ้ช่ฏๆฐๅ
ๆ ธ็ๆฌ
cat include/generated/utsrelease.h
Note: Always test self-compiled kernels in a VM or spare machine โ never replace the kernel on a production system. If the new kernel fails to boot, select the previous kernel in the GRUB menu to roll back.
4. Kernel Coding Standards
The kernel coding style document lives at Documentation/process/coding-style.rst and is mandatory reading for all contributors. Patches that violate these rules will be rejected by maintainers โ often without explanation.
Indentation and Line Length
/* ๅ
ๆ ธไฝฟ็จ TAB ็ผฉ่ฟ๏ผๅฎฝๅบฆไธบ 8 ไธชๅญ็ฌฆ๏ผ้็ฉบๆ ผ๏ผ๏ผ */
/* ่ก้ฟ้ๅถไปๅๅฒ็ 80 ๅญ็ฌฆๆพๅฎฝๅฐไบ 100 ๅญ็ฌฆ */
/* ๆญฃ็กฎ */
int kernel_function(struct device *dev, unsigned long flags)
{
if (flags & SOME_FLAG) {
do_something(dev);
return 0;
}
return -EINVAL;
}
/* ้่ฏฏ๏ผไฝฟ็จ็ฉบๆ ผ็ผฉ่ฟ */
int bad_function(void) {
return 0; /* ่ฟๆฏ็ฉบๆ ผ๏ผไธๆฏ TAB */
}
Brace Placement
/* ๅฝๆฐไฝ็ๅทฆ่ฑๆฌๅท็ฌๅ ไธ่ก๏ผK&R ้ฃๆ ผ็ๅ
ๆ ธๅไฝ๏ผ */
int my_function(int arg)
{
/* ๅฝๆฐไฝ */
}
/* ๆงๅถ่ฏญๅฅ๏ผif/for/while๏ผๅทฆ่ฑๆฌๅทๅจๅไธ่ก */
if (condition) {
do_something();
} else {
do_other();
}
/* ๅ่ก if ไธ่ฆๅ ่ฑๆฌๅท๏ผ้ค้ else ๅๆฏ้่ฆ */
if (err)
return err;
Naming Conventions
- Functions/variables:
lowercase_with_underscores - Macros/constants:
UPPERCASE_WITH_UNDERSCORES - Struct types:
struct my_struct๏ผavoid typedef unless there is a specific reason๏ผ - Global variables: avoid strongly; if necessary, add a module prefix
Legitimate Use of goto
/* ๅ
ๆ ธไธญ goto ็จไบ้่ฏฏ่ทฏๅพๆธ
็๏ผๆฏๆจ่ๅๆณ */
int probe_device(struct platform_device *pdev)
{
struct my_priv *priv;
int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) {
ret = -ENOMEM;
goto err_alloc;
}
ret = request_irq(priv->irq, my_irq_handler, 0, "mydev", priv);
if (ret)
goto err_irq;
ret = register_device(priv);
if (ret)
goto err_register;
return 0;
err_register:
free_irq(priv->irq, priv);
err_irq:
/* devm_kzalloc ่ชๅจ้ๆพ๏ผๆ ้ๆๅจ free */
err_alloc:
return ret;
}
5. Finding Places to Contribute
drivers/staging
The drivers/staging/ directory contains drivers not yet meeting mainline quality standards. Each driver has a TODO file explicitly listing what needs to be fixed โ the best entry point for beginners.
# ๅๅบๆๆ staging ้ฉฑๅจๅๅ
ถ TODO ๆไปถ
ls drivers/staging/
cat drivers/staging/greybus/TODO
# ็จ checkpatch ๆซๆๆไธช staging ้ฉฑๅจ
scripts/checkpatch.pl --strict -f drivers/staging/greybus/*.c
# ๆ็ดข coding style ้ฎ้ข๏ผๅ
ธๅ๏ผ็จ printk ๆฟไปฃ dev_err๏ผ
grep -rn "printk(" drivers/staging/greybus/ | grep -v "KERN_"
Using sparse for Type Annotation Checks
# ๅฎ่ฃ
sparse
sudo apt-get install -y sparse
# ๅช็ผ่ฏ็ฎๆ ้ฉฑๅจ๏ผไธ้่ฆๅ
จ้็ผ่ฏ๏ผ
make C=1 drivers/staging/greybus/
# C=2 ๅจๆๆๆไปถไธ่ฟ่ก sparse๏ผๅ
ๆฌๅทฒ็ป็ผ่ฏ่ฟ็๏ผ
make C=2 drivers/staging/greybus/
# ๅธธ่ง sparse ่ญฆๅ๏ผ
# warning: incorrect type in argument
# warning: context imbalance in 'func' -- unexpected unlock
6. Preparing Your First Patch
Understand the Problem
Before touching any code, fully understand the problem. Use git log --oneline drivers/xxx/ to review change history, git blame to find the original authors, and read relevant kernel docs and comments. Confirm this is genuinely a bug or standards violation, not a misunderstanding of kernel APIs.
# ๅๅปบๅทฅไฝๅๆฏ๏ผๅๆฏๅๆ่ฟฐๅ
ทไฝๆนๅจ๏ผไพฟไบ maintainer ่ฏๅซ๏ผ
git checkout -b staging/greybus/fix-coding-style
# ็ผ่พๆไปถ๏ผๅๆๅฐๅใ่็ฆ็ๆนๅจ
# ไธไธช patch ๅชๅไธไปถไบ๏ผไธ่ฆๆๅคไธชๆ ๅ
ณๆนๅจๆททๅจไธ่ตท
vim drivers/staging/greybus/core.c
# ๅช็ผ่ฏ็ฎๆ ๆจกๅ้ช่ฏๆนๅจไธๅผๅ
ฅ็ผ่ฏ้่ฏฏ
make -j$(nproc) drivers/staging/greybus/
# sparse ๆฃๆฅ
make C=1 drivers/staging/greybus/
Running checkpatch.pl
# ๆฃๆฅๆๆฐไธไธช commit๏ผๆๅธธ็จๆนๅผ๏ผ
scripts/checkpatch.pl --strict -g HEAD
# ๆฃๆฅไธไธช .patch ๆไปถ
scripts/checkpatch.pl --strict 0001-staging-greybus-fix-style.patch
# ๆฃๆฅๆไธชๆบๆไปถ๏ผไธ้่ฆๅ
commit๏ผ
scripts/checkpatch.pl --strict -f drivers/staging/greybus/core.c
# ่พๅบ็คบไพ๏ผ
# WARNING: line over 100 characters
# ERROR: do not use assignment in if condition
# CHECK: 'foo' may be better written as 'bar'
# total: 0 errors, 1 warnings, 0 checks, 42 lines checked
Target: Before sending, aim for
total: 0 errors, 0 warnings. CHECK-level hints (blue) are advisory โ fix them when reasonable but they are not mandatory.
Writing the Commit Message
git add drivers/staging/greybus/core.c
git commit
# commit message ๆ ผๅผ๏ผ้ๅธธ้่ฆ๏ผ๏ผ๏ผ
# ็ฌฌไธ่ก๏ผsubsystem: component: Short description (50ๅญ็ฌฆไปฅๅ
)
# ็ฉบ่ก
# ๆญฃๆ๏ผ่งฃ้ไธบไปไนๅ่ฟไธชๆนๅจ๏ผWHY๏ผ๏ผ่ไธๆฏๅไบไปไน๏ผWHAT๏ผไปฃ็ ๅทฒ็ป่ฏดๆ๏ผ
# ็ฉบ่ก๏ผๅฆๆ๏ผ
# ๆ ็ญพ่ก๏ผSigned-off-by ๆฏๅผบๅถ่ฆๆฑ๏ผ
staging: greybus: replace printk with dev_err for proper log context
Using raw printk() in device drivers loses the device context from
the log message, making it harder to correlate log entries with
specific devices in systems with multiple greybus instances.
Replace printk(KERN_ERR ...) calls with dev_err(dev, ...) which
automatically prepends the device name to the log output.
Signed-off-by: Your Name
Signed-off-by:
Signed-off-byis the Developer's Certificate of Origin (DCO) declaration, confirming you have the right to submit this code. Patches without it are rejected outright. Usegit commit -sto add it automatically.
7. Finding the Right Maintainer
The Linux kernel has hundreds of maintainers, each responsible for a specific subsystem. Finding the right maintainer and mailing list before sending is essential โ otherwise your patch will be ignored.
# get_maintainer.pl ๆ นๆฎๆไปถ่ทฏๅพๆ patch ๅ
ๅฎนๆฅๆพ maintainer
# ่พๅบๆ ผๅผ๏ผName (role: maintainer/reviewer/...)
# ๅฏนๆๆฐ็ commit ็ๆ patch ๅนถๆฅๆพ maintainer
git format-patch -1 HEAD --stdout | scripts/get_maintainer.pl
# ๆ็ดๆฅๆๅฎๆไปถ
scripts/get_maintainer.pl --file drivers/staging/greybus/core.c
# ็คบไพ่พๅบ๏ผ
# Greg Kroah-Hartman (maintainer:STAGING SUBSYSTEM)
# Johan Hovold (reviewer:GREYBUS SUBSYSTEM)
# [email protected] (open list:STAGING SUBSYSTEM)
# [email protected] (open list:GREYBUS SUBSYSTEM)
The MAINTAINERS file in the kernel root is the maintainer database, containing M (maintainer), R (reviewer), L (mailing list), S (status), and F (file pattern) fields for each subsystem. Understanding this file helps you decide where to send your patch.
8. Sending the Patch
Generating .patch Files
# ็ๆๆๆฐ 1 ไธช commit ็ patch๏ผ-1 ่กจ็คบๆ่ฟ 1 ไธช๏ผ
git format-patch -1 HEAD
# ็ๆๅคไธช commit ็ patch ็ณปๅ๏ผ่ชๅจๆทปๅ ๅบๅทๅ็ผ๏ผ
git format-patch -3 HEAD # ๆ่ฟ 3 ไธช commit
# ๅ cover letter๏ผ่กฅไธ็ณปๅไป็ป๏ผ--cover-letter ็ๆ 0000-cover-letter.patch๏ผ
git format-patch -3 HEAD --cover-letter
# ๆๅฎ่พๅบ็ฎๅฝ
git format-patch -1 HEAD -o /tmp/patches/
# ็ๆ็ๆไปถ็คบไพ๏ผ
# 0001-staging-greybus-replace-printk-with-dev_err.patch
Configuring git send-email
# ๅฎ่ฃ
git send-email๏ผๅฏ่ฝ้่ฆๅ็ฌๅฎ่ฃ
๏ผ
sudo apt-get install -y git-email
# ~/.gitconfig ไธญ้
็ฝฎ SMTP๏ผไปฅ Gmail ไธบไพ๏ผ
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 [email protected]
# SMTP ๅฏ็ ้่ฟ git credential helper ็ฎก็ๆๅจๅฝไปค่ก่พๅ
ฅ
# ไปฅ่
พ่ฎฏไผไธ้ฎไธบไพ
git config --global sendemail.smtpserver smtp.exmail.qq.com
git config --global sendemail.smtpserverport 465
git config --global sendemail.smtpencryption ssl
Sending the Patch
# ๅ
็จ --dry-run ้ข่ง๏ผไธๅฎ้
ๅ้๏ผ
git send-email \
--to [email protected] \
--cc [email protected] \
--dry-run \
0001-staging-greybus-replace-printk-with-dev_err.patch
# ็กฎ่ฎคๆ ่ฏฏๅๅปๆ --dry-run ๅ้
git send-email \
--to [email protected] \
--cc [email protected] \
0001-staging-greybus-replace-printk-with-dev_err.patch
# ๅ้ patch ็ณปๅ๏ผcover letter + ๅคไธช patch๏ผ
git send-email \
--to [email protected] \
--cc [email protected] \
/tmp/patches/*.patch
Critical: Kernel patches must be sent as plain text with no HTML, and the mail client must not re-wrap lines. Thunderbird requires plain-text mode with format=flowed disabled. Gmail's web interface corrupts patch formatting โ strongly prefer
git send-email.
9. LKML Etiquette
Writing a Cover Letter
A single patch usually does not need a cover letter, but a patch series (more than 2 patches) must include one explaining the overall intent. The cover letter subject line format is [PATCH 0/N] Subject; the body explains why you are making these changes, how you tested them, and any known limitations.
Responding to Review Feedback
- Reply within 48 hours to show you are engaged
- Address each comment individually โ accept, decline with reasoning, or request further discussion
- Resend as
[PATCH v2]with a changelog in the cover letter - Do not be discouraged by critical feedback โ rigorous review is why the kernel is high quality
Common Tag Meanings
| Tag | Meaning |
|---|---|
| Signed-off-by: | Author certifies right to submit (DCO); also used by maintainers when forwarding |
| Reviewed-by: | Reviewer confirms code is correct and recommends merging |
| Acked-by: | Relevant party (e.g., subsystem maintainer) does not object without deep review |
| Tested-by: | Tester verified the patch works on real hardware |
| Reported-by: | Credits the person who reported the bug |
| Fixes: | Points to the commit this patch fixes (format: Fixes: abcdef ("commit subject")) |
Tracking Patch Status with patchwork
patchwork.kernel.org automatically archives patches sent to mailing lists and tracks their status (New / Under Review / Accepted / Rejected / Deferred). After sending, search patchwork by your name or patch subject to confirm correct archival.
10. Kernel Newbies and Learning Resources
The kernel community provides excellent learning and support channels for newcomers:
- kernelnewbies.org โ the most important newcomer portal, including a TODO list (beginner-friendly tasks), per-release change explanations, and IRC channels
- [email protected] โ the main LKML list โ very high volume (hundreds of emails per day). Use mail filters or read via the lore.kernel.org web archive
- lore.kernel.org โ public archive and search interface for all kernel mailing lists, with threaded reading support
- #kernelnewbies (Libera.Chat IRC) โ real-time Q&A channel where maintainers and experienced contributors answer questions
- Kernel Documentation โ
Documentation/process/contains complete contribution guides (submitting-patches.rst, email-clients.rst, etc.) - Weekly kernel activity tracking โ LWN.net publishes weekly kernel development roundups โ the best way to follow the community
Action checklist: โ Clone linux-next, โก find a checkpatch warning in drivers/staging/, โข fix it and verify with checkpatch, โฃ use get_maintainer.pl to find recipients, โค send the patch to the mailing list (even staging patches get real human review). Complete these five steps and you are officially a kernel contributor.
Previous
โ Ch18: Mini Shell
Next
Ch20: Final Project โ