Patching a Kernel (201.3)

Candidates should be able to properly patch a kernel to add support for new hardware. This objective also includes being able to properly remove kernel patches from already patched kernels.

Key files, terms and utilities include:

Patching a kernel

In general a patchfile contains the differences between two versions of a file produced by the diff command. The patch command is used to apply the contents of the patchfile to update the file from the old version to a newer version.

Patching the kernel is very straightforward:

  1. Place patchfile in the /usr/src directory.
  2. Change directory to /usr/src.
  3. Uncompress the patchfile using gunzip or bunzip2
  4. Use the patch utility to apply the patchfile to the kernel source:
    patch -p1 <patchfile
  5. Check for failures.
  6. Build the kernel.

If the patch utility is unable to apply a part of a patch, it puts that part in a reject file. The name of a reject file is the name of the output file plus a .rej suffix, or a # if the addition of .rej would generate a filename that is too long. In case even the addition of a mere # would result in a filename that is too long, the last character of the filename is replaced with a #.

The common options for the patch utility:

-pnumber, --strip=number
Strip the smallest prefix containing number leading slashes from each file name found in the patch file. A sequence of one or more adjacent slashes is counted as a single slash. This controls how file names found in the patch file are treated, in case you keep your files in a different directory than the person who sent out the patch. For example, supposing the file name in the patch file was /u/howard/src/blurfl/blurfl.c, then using -p0 gives the entire file name unmodified, while using -p1 gives u/howard/src/blurfl/blurfl.c.
-s, --silent, --quiet
Work silently (suppress output), unless an error occurs.
-E, --remove-empty-files
Remove output files that are empty after the patches have been applied. Normally this option is unnecessary, since patch can examine the time stamps on the header to determine whether a file should exist after patching. However, if the input is not a context diff or if patch is conforming to POSIX, patch does not remove empty patched files unless this option is given. When patch removes a file, it also attempts to remove any empty ancestor directories.
-R, --reverse
Assume that this patch was created with the old and new files reversed, so that you are basically applying the patch to the file which already contains the modifications in the patch file. The patch will attempt to swap each hunk around before applying it and rejects will come out in the swapped format. The -R option does not work with ed diff scripts because there is too little information to reconstruct the reverse operation. If the first hunk of a patch fails, patch reverses the hunk to see if it can be applied that way. If it can, you are asked if you want to have the -R option set. If it can't, the patch continues to be applied normally.

Note

This method cannot detect a reversed patch if it is a normal diff and if the first command is an append (i.e. it should have been a delete) since appends always succeed. This is due to the fact that a null context matches anywhere. Luckily, most patches add or change lines rather than delete them, so most reversed normal diffs begin with a delete, which fails, triggering the heuristic.

For more information consult the man-pages of the diff command and the patch command.

Removing a kernel patch from a production kernel

A kernel patch can be removed from a production kernel by removing it from the production kernel source tree and compiling a new kernel. In the previous topic we've learned that to remove a patch from a file, you either need to apply it again, or run patch with the -R parameter:

# patch -p1<patch-2.6.28
patching file linux/Documentation/Configure.help
Reversed (or previously applied) patch detected! Assume -R? [n] y
Copyright Snow B.V. The Netherlands