Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1274096
  • 博文数量: 389
  • 博客积分: 2874
  • 博客等级: 少校
  • 技术积分: 3577
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-24 10:34
文章分类

全部博文(389)

文章存档

2020年(2)

2018年(39)

2017年(27)

2016年(3)

2015年(55)

2014年(92)

2013年(54)

2012年(53)

2011年(64)

分类: LINUX

2011-11-23 08:45:47

Kernel Hacking Lesson #9: Creating, Applying, and Submitting Patches

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 mistakes avoided. Submitting a patch also takes some work.

At first, submitting patches might seem like the easiest part of kernel development. After all, it can't be as hard as fixing an ethernet driver bug, right? Well, often it's easier to fix a kernel bug than to get a kernel patch accepted into the mainline kernel. Part of the reason is the sheer limitations of one person - the kernel maintainer can only read and accept so many patches per release. But other reasons why patches are hard to get accepted are controversial changes, territoriality, personality conflicts, and apathy. And finally, whenever you submit a patch, you are putting your reputation and 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 very encouraging. Some kernel developers had parties to celebrate the first patch they wrote that was accepted into the mainline kernel. Knowing that you wrote some code that other people thought was good enough to include in the Linux kernel is a great feeling! So, let's learn how to apply, create, and submit patches.

How patches work

A "patch" is a file that describes the differences between two versions of a file. The program diff compares the original file and the new file line-by-line and prints the differences to standard out in a specific format. The program patch can read the output of diff and apply those changes to another copy of the original file. (Note that the word "patch" refers both to the output of the diff 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 from the first file listed on the command line is shown with a "-" in front of it, followed by the line from the second file on the command line is shown with a "+" in front of it. Intuitively, you are "subtracting" the line from the old file and "adding" the line from the new file. Remember, the old files always come first and the newer files come second.

Now, lets apply the patch we just created. A patch updates the older version of the file to the newer version of the file, so we want to apply 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 command using patch, the "old" file is now the same as the "new" file.

Applying patches

Next, we'll learn how to apply patches. One of the common reasons you'll need to apply a patch is in order to get a particular kernel version which isn't available as one big tarball downloadable from ftp.kernel.org, or else to get an incremental patch so you don't have to download an entire new kernel when most of the kernel files are still the same.

The kernel patch naming and creation standards are not particularly simple. Say that you want to get the kernel 2.6.9-rc4 for some reason, and you currently have the full kernel source for version 2.6.7. You'll need to download the following patches to get from 2.6.7 to 2.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 and are named patch-2.6.x-rcN, usually found in a directory on the ftp site called testing) is created by diffing against the previous major release. A common mistake is to download kernel version 2.6.9 and then attempt to apply the 2.6.9-rc4 prepatch. If you want kernel version 2.6.9-rc4, you should download kernel 2.6.8 and then apply the 2.6.9-rc4 prepatch. This is because 2.6.9-rc4 is a predecessor of 2.6.9, not the other way around. NOTE: The naming convention and location of kernel prepatches tends to change frequently. You may have to read the linux-kernel mailing list to find out where the very latest patches are being kept and what they are being named.

The official kernel patches are all made so that you can simply do:

cd patch -p1 < ../patchfile

What the -p1 option to the patch command says is "Strip the part of the pathname up through the first forward slash and then try to apply the patch to the file with the stripped down pathname."

If all this seems incredibly complex and annoying, you might want to try using BitKeeper. See the end of this lesson for a brief introduction to BitKeeper.

Creating a patch

The first thing to remember is to always keep an untouched, pristine version of the kernel source somewhere. Don't compile in it, don't edit any files in it, don't do anything to it - just copy it to make your working copy of the source tree. The original kernel source should be in a directory named linux.vanilla or linux.orig, and your working directory should be in the same directory as the original source. 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 a patch using diff. Assuming that your working tree is named linux.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 new kernel source are now in patchfile. NOTE: Do not ever create a patch 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 one will bother trying out your patch since it's hard to apply.

Now that you've created a patch - read it! It's almost guaranteed that your patch includes files that you don't want as part of your patch, such as old editor backup files, object files, or random cruft you created during development. To get rid of these files, you can tell diff to ignore certain files, you can delete the files, or you can hand-edit the diff. Be sure you understand the patch format before you hand-edit a patch, or you can easily create a patch that won't apply. One useful command for getting rid of most of the extra files created during a kernel build is:

make mrproper

But remember, this deletes your .config file and forces you to do a complete recompile of your kernel.

Also, make sure that your patch goes in the correct direction. Are your new lines the ones with "+"'s in front of them? And, make sure those are the changes you wanted to send. It's surprisingly easy to make a diff against the wrong source tree entirely.

After you think you've got a final version of the patch, apply it to a a copy of your pristine source tree (don't ruin your only copy of the pristine source tree). If it doesn't apply without any errors, redo the patch.

Once again, if this seems awfully complex, you may want to try BitKeeper, described at the end of this lesson.

Submitting a patch

After you've created a patch, you'll hopefully want to share it with other people. Ideally, you'll test the patch yourself, get other people to test it too, and have other people read the patch itself. In summary, you want your patch to be bug-free, well-written, and easy to apply.

Testing

Always compile and test your patches yourself. You'll see people posting "totally untested" patches to linux-kernel, but don't fall for it - a totally untested patch is likely to be a useless patch. Kernel maintainers have more than once released a kernel which doesn't compile at all. No one is perfect - always test your patches.

Coding style

Be sure that your code fits in with the code around it and follows the kernel coding style conventions. See the file Documentation/CodingStyle for specific directions, although looking at other source files is often the best way to figure out what the current conventions are.

Easy to apply

If it's difficult to apply your patch, it almost certainly won't be accepted. In addition to creating the patch with the proper level of directories, you need to create it against the kernel that is identical (or nearly so) to the kernel that other people will be applying your patch to. So, if you want person XYZ to apply your patch, find out what version of the kernel person XYZ is using and try to get something as close to that as possible. Usually this is the latest 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 latest version released, then you should recreate your patch against 2.6.9-rc4. The easiest way to do this is to apply your patch from 2.6.9-rc2 to 2.6.9-rc4 and fix up any changes that occurred between the two versions, then rediff against 2.6.9-rc4.

Who to submit your patch to

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 the area you are working on, and you will begin to get an idea of who the appropriate person is. Some general rules of thumb:

Try to find the person most specifically involved in maintaining the part of the kernel you are changing. If you make a change to the foo driver in the bar subsystem, and the foo driver has a maintainer, you should probably submit your patch to the foo maintainer, and only to the bar subsystem maintainer if the foo maintainer is ignoring you.

The file in the toplevel kernel source directory, MAINTAINERS, is frequently out of date, but often helpful anyway. No one will fault you if you send your patch to the person listed in the MAINTAINERS file and CC linux-kernel. When in doubt, this is always the safest route to take.

And finally, ask a friend! Send mail to the linuxchix lists asking for advice on who to submit a patch to. We can help.

Distributing your patch

Most patches are small enough to be included in an email. While some maintainers refuse to accept patches in attachments, and some refuse MIME encoded attachments, all maintainers will accept a patch that is included in the body of a text-only email. Make sure your mail client isn't mangling your patch - if you aren't sure, email your patch to yourself and apply it to make sure other people will be able to apply it to. Most Linux mailing lists like patches with a meaningful English-language subject, 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), put it on a web page or ftp site where other people can download it, and put the URL in your email.

Political considerations

If all that mattered is that your patch was well-formed, correct, and fixed a bug, submitting a patch would be a lot simpler. Instead, your patch needs to be tasteful, timely, interesting, and considerate of the maintainer's ego. Most of the time, a simple bugfix will be immediately accepted. Occasionally though, you'll run into bigger problems. The important thing to remember is that you can't work around the Linux maintainer system, you have to work through it. Read a few threads on linux-kernel in which people tried to wheedle their patch into the kernel (I've tried - and failed). If your patch isn't accepted, listen to what other people are saying about it and try to fix the problems with it. The most often rejected patch is the feature patch - adding a new feature that is considered tasteless by the other maintainers. Don't waste your time trying to get that patch accepted, just maintain it separately. If enough people find the patch useful, you'll gain a reputation as being a useful kernel hacker among all the people who download and use your patch.

Sometimes, a maintainer just can't accept a patch because of his or her ego. When this happens, the only option is to maintain a better version of the code independently of the main kernel. Often, externally maintained code that proves to be better will replace the in-kernel code after a while, which is one way to become a maintainer.

The alternative to diff and patch - BitKeeper

BitKeeper is currently being used by many kernel developers as a replacement for diff and patch. It simplifies a lot of kernel development tasks, such as updating to the latest version, creating patches, and applying patches. For more information, see the BitKeeper website:

Or "BitKeeper for Kernel Developers"

转自:

阅读(1198) | 评论(0) | 转发(0) |
0

上一篇:using select on a fifo

下一篇:vi使用进阶

给主人留下些什么吧!~~