My first Linux kernel contribution
I got interested in Linux in high school when I stumbled upon it as side note in a textbook. It was only in the following couple years did I realize the importance Linux had in the computer and programming community. Linux only refers to the operating system’s kernel which is an abstraction that provides a unified platform for software to run on many different types of hardware. The kernel is open source software and anyone can contribute to its development. So after years of benefiting from the contributions of others I decided I would investigate the development process that makes it all possible.
Obtain Source Tree
There are many different kernel trees to work off of. It is important to use the same one as the maintainers of the subsystem in which your changes are made. The drivers/staging subsystem is a recommended place to start contributing and is handled by Greg KH. A list of the maintainers’ trees are available here.
git clone https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
git checkout staging-testing
Project Structure
To get started with simple contributions we are only interested in the following two directories with the kernel source tree.
- scripts folder has useful tools for development. Specifically the checkpatch.pl checks for correct coding style
- drivers/staging is a good place to start kernel. Modules here contain a TODO file which helps give direction on what to do and importantly are open to simple coding style fixes.
Janitorial Work
Coding style
For simple coding style fixes, run the following command.
./scripts/checkpatch --file --terse drivers/staging/<driver>/*.c
Sparse testing
Sparse: tool for static code analysis to help detect errors
make C=2 drivers/staging/<driver>/ # the C=2 option invokes sparse
Making changes and testing
Create and checkout new branch
Make edits
Build the kernel module with edits
make M=drivers/staging/<driver> clean make M=drivers/staging/<driver>
If the module builds, it is worth booting the custom kernel to test it out on hardware. This process differs depending on the distribution you are using. Here I will briefly outline how I did it with the Gentoo distribution
make menuconfig # enable driver as module make -j7 # build sudo make modules_install sudo make install # ensure /boot directory is mounted first sudo grub-mkconfig -o /boot/grub/grub.cfg
Use dmesg tool for reading kernel messages
dmesg -l crit dmesg -l err dmesg -l warn
Building a patch/patchset
The are strict rules to submitting patches. One of these rules dictates a single patch should only be do one thing. Patches relate to commits. If you are making a single change you’ll have one commit and hence submit one patch. If you are submitting many changes you’ll have many commits and submit a patchset (i.e. a collection of numbered patches).
Git status gives summary of files modified
Git diff shows files modified in patch format
git diff git commit -v # only staged changes will be commited. ensure a single commit only achieves a single task
Commit message should be as follows. Ensure you included signed off line.
Staging: r8188eu: Fix too many leading tabs line length Fix coding style issue. Too many leading tabs Signed off by: Joash Naidoo <joash.n09@gmail.com>
Create patch
- Must run the following from the root of the kernel source tree
git show --pretty=full # if single patch git format-patch <maintainers-branch>..<my-branch> # if patchset git format-patch -n --cover-letter <maintainers-branch>..<my-branch>
- If resubmitting patches, the –subject-prefix option must be passed (see below)
- For patchsets, remember to change cover letter subject line and contents. Contents are an overview of what the following patches fixes. Cover letter is discarded after patchset applied so ensure current information is found within the individual patch commits
- Format patch produces patch files. Use -o option to specify output directory
Ensure patch passes checkpatch.el script
./scripts/checkpatch.pl <patch-file>
Setup email (Gmail) with Git
- Enable 2 factor authentication on Gmail
- Create “App Password”
- Add the following to you .gitconfig
[sendemail] smtpserver = smtp.googlemail.com smtpencryption = tls smtpserverport = 587 smtpuser = <[email protected]>
- Find list of maintainers to send to
./scripts/get_maintainer.pl 0001-<patch>
- Send email
git send-email --to=<> --cc=<> 0001-<patch>
- You will be prompted for password. Use your “App password” you created earlier.
Replying to emails
- Do NOT use Gmail’s web based email client. Recommended clients
- You need to use an email client that supports replying inline
- Some options include MUTT (a terminal based email client) and mu4e (what I personally used)
- Reply to everyone in the list
Fix patch if you messed up
- First stage changes you were requested to make
- Amend commit. Assuming you want to create a patch out of the latest commit, run the following:
git commit --verbose --amend
- Create new patch
git format-patch --subject-prefix="PATCH v2" HEAD^ ./scripts/checkpatch.pl <new_patch_file>
- When you’re ready send email