As a kernel developer, you'll spend a lot of time creating, applying,and submitting patches. Creating and applying patches can be tricky -a lot of conventions must be learned and a lot of common mistakesavoided. Submitting a patch also takes some work.
At first, submitting patches might seem like the easiest part ofkernel development. After all, it can't be as hard as fixing anethernet driver bug, right? Well, often it's easier to fix a kernelbug than to get a kernel patch accepted into the mainline kernel.Part of the reason is the sheer limitations of one person - the kernelmaintainer can only read and accept so many patches per release. Butother reasons why patches are hard to get accepted are controversialchanges, territoriality, personality conflicts, and apathy. Andfinally, whenever you submit a patch, you are putting your reputationand ego on the line and that's more than a little scary.
That being said, submitting a patch can be a lot of fun and veryencouraging. Some kernel developers had parties to celebrate thefirst patch they wrote that was accepted into the mainline kernel.Knowing that you wrote some code that other people thought was goodenough to include in the Linux kernel is a great feeling! So, let'slearn how to apply, create, and submit patches.
A "patch" is a file that describes the differences between twoversions of a file. The programdiff
compares the original file andthe new file line-by-line and prints the differences to standard outin a specific format. The programpatch
can read the output ofdiff
and apply those changes to another copy of the original file.(Note that the word "patch" refers both to the output of thediff
command and to the command that applies the patch.) For example:
val@evilcat <~>$ cat old/file.txt This is a simple file. val@evilcat <~>$ cat new/file.txt This is a slightly more complex file. val@evilcat <~>$ diff -uNr old new diff -uNr old/file.txt new/file.txt --- old/file.txt Tue May 28 23:00:21 2002 +++ new/file.txt Tue May 28 23:01:01 2002 @@ -1,5 +1,5 @@ This is a -simple +slightly more complex file.
As you can see, the two files differ in only one line. The line fromthe first file listed on the command line is shown with a "-" in frontof it, followed by the line from the second file on the command lineis shown with a "+" in front of it. Intuitively, you are"subtracting" the line from the old file and "adding" the line fromthe new file. Remember, the old files always come first and the newerfiles come second.
Now, lets apply the patch we just created. A patch updates the olderversion of the file to the newer version of the file, so we want toapply the patch to the older version of the file.
val@evilcat <~>$ diff -uNr old new > patchfile val@evilcat <~>$ cd old val@evilcat <~/old>$ patch -p1 < ../patchfile patching file file.txt val@evilcat <~/old>$ cat file.txt This is a slightly more complex file.
After applying the output of the diff
commandusing patch
, the "old"file is now the same as the "new" file.
Next, we'll learn how to apply patches. One of the common reasonsyou'll need to apply a patch is in order to get a particular kernelversion which isn't available as one big tarball downloadable fromftp.kernel.org
, or else to get an incremental patch so you don't haveto download an entire new kernel when most of the kernel files arestill the same.
The kernel patch naming and creation standards are not particularlysimple. Say that you want to get the kernel2.6.9-rc4
for somereason, and you currently have the full kernel source for version2.6.7
. You'll need to download the following patches to get from2.6.7
to2.6.10-rc1
:
2.6.7
to 2.6.8
2.6.8
to 2.6.9-rc4
Each prepatch (the patches that come between the major releases andare named patch-2.6.x-rcN
, usually found in a directory on the ftpsite called testing
) is created by diffing against the previousmajor release. A common mistake is to download kernel version2.6.9
and then attempt to apply the 2.6.9-rc4
prepatch. If you wantkernel version2.6.9-rc4
, you should download kernel 2.6.8
and thenapply the2.6.9-rc4
prepatch. This is because 2.6.9-rc4
is a predecessor of2.6.9
, not the other way around. NOTE: The naming convention andlocation of kernel prepatches tends to change frequently. You mayhave to read the linux-kernel mailing list to find out where the verylatest patches are being kept and what they are being named.
The official kernel patches are all made so that you can simply do:
cd <your linux source tree> patch -p1 < ../patchfile
What the -p1
option to the patch command says is "Strip the part ofthe pathname up through the first forward slash and then try to applythe patch to the file with the stripped down pathname."
If all this seems incredibly complex and annoying, you might want totry using BitKeeper. See the end of this lesson for a briefintroduction to BitKeeper.
The first thing to remember is to always keep an untouched, pristineversion of the kernel source somewhere. Don't compile in it, don'tedit any files in it, don't do anything to it - just copy it to makeyour working copy of the source tree. The original kernel sourceshould be in a directory named linux.vanilla
or linux.orig
, andyour working directory should be in the same directory as the originalsource. For example, if your pristine source is in/usr/src/linux.vanilla
, your working source should be in /usr/src/
also.
After you make your changes to your working copy, you'll create apatch using diff
. Assuming that your working tree is namedlinux.new
, you would run this command:
val@evilcat <~>$ diff -uNr linux.vanilla linux.new > patchfile
All the differences between the original kernel source and your newkernel source are now inpatchfile
. NOTE: Do not ever create apatch with uneven directories, for example (DON'T do this):
val@evilcat <~>$ diff -uNr linux.vanilla working/usb/thing1/linux > patchfile
This will not create a patch in the standard patch format and no onewill bother trying out your patch since it's hard to apply.
Now that you've created a patch - read it! It's almost guaranteedthat your patch includes files that you don't want as part of yourpatch, such as old editor backup files, object files, or random cruftyou created during development. To get rid of these files, you cantell diff to ignore certain files, you can delete the files, or youcan hand-edit the diff. Be sure you understand the patch formatbefore you hand-edit a patch, or you can easily create a patch thatwon't apply. One useful command for getting rid of most of the extrafiles created during a kernel build is:
make mrproper
But remember, this deletes your .config
file and forces you to do acomplete recompile of your kernel.
Also, make sure that your patch goes in the correct direction. Areyour new lines the ones with "+"'s in front of them? And, make surethose are the changes you wanted to send. It's surprisingly easy tomake a diff against the wrong source tree entirely.
After you think you've got a final version of the patch, apply it to aa copy of your pristine source tree (don't ruin your only copy of thepristine source tree). If it doesn't apply without any errors, redothe patch.
Once again, if this seems awfully complex, you may want to tryBitKeeper, described at the end of this lesson.
After you've created a patch, you'll hopefully want to share it withother people. Ideally, you'll test the patch yourself, get otherpeople to test it too, and have other people read the patch itself.In summary, you want your patch to be bug-free, well-written, andeasy to apply.
Always compile and test your patches yourself. You'll see peopleposting "totally untested" patches to linux-kernel, but don't fall forit - a totally untested patch is likely to be a useless patch. Kernelmaintainers have more than once released a kernel which doesn'tcompile at all. No one is perfect - always test your patches.
Be sure that your code fits in with the code around it and follows thekernel coding style conventions. See the fileDocumentation/CodingStyle
for specific directions, although lookingat other source files is often the best way to figure out what thecurrent conventions are.
If it's difficult to apply your patch, it almost certainly won't beaccepted. In addition to creating the patch with the proper level ofdirectories, you need to create it against the kernel that isidentical (or nearly so) to the kernel that other people will beapplying your patch to. So, if you want person XYZ to apply yourpatch, find out what version of the kernel person XYZ is using and tryto get something as close to that as possible. Usually this is thelatest vanilla kernel released by the kernel maintainer. For example,if you have a patch against 2.6.9-rc2
, and 2.6.9-rc4
is the latestversion released, then you should recreate your patch against2.6.9-rc4
. The easiest way to do this is to apply your patch from2.6.9-rc2
to 2.6.9-rc4
and fix up any changes that occurredbetween the two versions, then rediff against2.6.9-rc4
.
The answer to "Who should I submit this patch to?" is "It depends."Subscribe to linux-kernel and any list which is more specific to thearea you are working on, and you will begin to get an idea of who theappropriate person is. Some general rules of thumb:
Try to find the person most specifically involved in maintaining thepart of the kernel you are changing. If you make a change to the foodriver in the bar subsystem, and the foo driver has a maintainer, youshould probably submit your patch to the foo maintainer, and only tothe bar subsystem maintainer if the foo maintainer is ignoring you.
The file in the toplevel kernel source directory, MAINTAINERS
, isfrequently out of date, but often helpful anyway. No one will faultyou if you send your patch to the person listed in theMAINTAINERS
file and CC linux-kernel. When in doubt, this is always the safestroute to take.
And finally, ask a friend! Send mail to the linuxchix lists askingfor advice on who to submit a patch to. We can help.
Most patches are small enough to be included in an email. While somemaintainers refuse to accept patches in attachments, and some refuseMIME encoded attachments, all maintainers will accept a patch that isincluded in the body of a text-only email. Make sure your mail clientisn't mangling your patch - if you aren't sure, email your patch toyourself and apply it to make sure other people will be able to applyit to. Most Linux mailing lists like patches with a meaningful English-languagesubject, prefixed with the string [PATCH]
so that it's easy to find and read patches.
If your patch is too big to send by email (around 20K or larger), putit on a web page or ftp site where other people can download it, andput the URL in your email.
If all that mattered is that your patch was well-formed, correct, andfixed a bug, submitting a patch would be a lot simpler. Instead, yourpatch needs to be tasteful, timely, interesting, and considerate ofthe maintainer's ego. Most of the time, a simple bugfix will beimmediately accepted. Occasionally though, you'll run into biggerproblems. The important thing to remember is that you can't workaround the Linux maintainer system, you have to work through it. Reada few threads on linux-kernel in which people tried to wheedle theirpatch into the kernel (I've tried - and failed). If your patch isn'taccepted, listen to what other people are saying about it and try tofix the problems with it. The most often rejected patch is thefeature patch - adding a new feature that is considered tasteless bythe other maintainers. Don't waste your time trying to get that patchaccepted, just maintain it separately. If enough people find thepatch useful, you'll gain a reputation as being a useful kernel hackeramong all the people who download and use your patch.
Sometimes, a maintainer just can't accept a patch because of his orher ego. When this happens, the only option is to maintain a betterversion of the code independently of the main kernel. Often,externally maintained code that proves to be better will replace thein-kernel code after a while, which is one way to become a maintainer.
BitKeeper is currently being used by many kernel developers as areplacement for diff and patch. It simplifies a lot of kerneldevelopment tasks, such as updating to the latest version, creatingpatches, and applying patches. For more information, see theBitKeeper website:
http://www.bitkeeper.com
Or "BitKeeper for Kernel Developers"
http://www.nmt.edu/~val/ols/bk.ps.gz