The Debian kernel handbook is a useful reference which works with wheezy.
This page describes how to compile your own modified kernel from the linux-2.6 source package, rather than the debianized source tarball provided in linux-source-2.6.xx. Hopefully it will be integrated into the kernel handbook someday. See also BuildingKernelFromUpstreamSources and HowToRebuildAnOfficialDebianKernelPackage, which, despite its name, seems to address similar problems.
My initial purpose was to build two images, very similar to linux-image-2.6.18-4-686 and linux-image-2.6.18-4-xen-686, but patched to properly support an Intel-based [MacBookPro].
The first image would be easy to produce by using the method to build a custom kernel from the debian kernel source. However the second one would be a little more difficult, since there is no xen patch which is easily applyable to a debian kernel source. So I decided to reuse the linux-2.6 source package.
This method mostly follows the instructions detailed in the rebuilding an official Debian kernel package section of the debian kernel handbook. The only modification is showing how to apply your patch in the build process.
Here's how I did it.
Get the source and tools
Follow the initial steps detailed in the handbook. Stop before invoking debian/rules. Additionally install package devscripts. In this example I will assume that the version of the downloaded source package was 2.6.18.dfsg.1-12etch2
Add changes in a new revision
It is good to create a new revision when you change the package, to distinguish it from the original. You also get a place to document your changes - in the changelog, which will subsequently be available in /usr/share/doc/linux-image-*/changelog.Debian.gz - for free. No need for long cryptic version strings which try to document all applied changes by themselves.
Add a patch
First, copy the patch you require into the debian/patches directory - it should be possible to apply it from within the root of the source tree, using patch -p1. In my case the filename was debian/patches/mactel.patch
Make the patch apply during build
Then, add a new patch series file, which contains the name of the patch, and is named after the revision we are creating. I usually add a suffix, which makes the version larger than the original (this way APT will not try to reinstall the package from the archive), but smaller than the new official package, which will let me notice when I need to update my package.
In this case, I created a file called debian/patches/series/12etch2.0.mactel with the following contents:
that is, the name of the patch to apply, relative to the debian/patches directory
Add any config options
The kernel config file is created dynamically from a number of snippets scattered around the debian/arch/ directory. I needed to add two new config options together with the patch. Since I was going to build only a 686 and xen-686 flavors on the i386 architecture, it was suficient to add the following two lines at the end of the debian/arch/i386/config.686 file:
since this file is used by both flavours I needed to build.
Create a new revision
We need the revision and the name of the series file to match, so invoke the following command when in the debian/ directory:
dch -v 2.6.18.dfsg.1-12etch2.0.mactel
And describe the changes in the editor which gets invoked.
Prepare for the build
First, since we modified some key files in the debian directory, we need to regenerate the control file. Do this using:
fakeroot debian/rules debian/control
The command fails, but that's on purpose, as described in the message which is produced.
Subsequently, as described in the handbook, you need to invoke the following command to prepare the build environment:
fakeroot debian/rules debian/build debian/stamps
Build the packages
I was then able to build the packages using:
script -c 'DEBIAN_KERNEL_JOBS=2 time fakeroot make -f debian/rules.gen binary-arch_i386_xen_686 binary-arch_i386_none_686 binary-arch_i386_xen_real binary-arch_i386_none_real' ../typescript.2007072001
which is nice, as it saves the typescript of the build for later investigation in case it fails for some reason. The environment variable setting DEBIAN_KERNEL_JOBS=2 causes a parallel build, which is more efficient if you have more than one CPU.
After a (long) while, it produced the following files (grouped with according to targets which produced them):
linux-image-2.6.18-4-xen-686_2.6.18.dfsg.1-12etch2.0.mactel_i386.deb linux-modules-2.6.18-4-xen-686_2.6.18.dfsg.1-12etch2.0.mactel_i386.deb linux-headers-2.6.18-4-xen-686_2.6.18.dfsg.1-12etch2.0.mactel_i386.deb xen-linux-system-2.6.18-4-xen-686_2.6.18.dfsg.1-12etch2.0.mactel_i386.deb
The patch I needed to apply was relatively unintrusive, but if your changes modify the kernel's ABI (Binary Interface), by modifying some data structures or function declarations, then the build procedure is going to detect it and fail (possibly in a very verbose manner). You then need to copy the new ABI description file and create a new custom abi-ID.FLAVOR file in your arch directory. FIXME: possibly some more changes will be needed.
When I ran across this error, "ABI has changed!", 'I did not understand what the original author was talking about in the above paragraph. However, I was able to get it to work by simply changing the abiname value in debian/arch/defines. I changed it from "abiname: 6" to "abiname: 6-custom". This allowed it to continue successfully.
. This is covered in more detail on HowToRebuildAnOfficialDebianKernelPackage under the heading Add a patch to linux-2.6 and build new kernel packages
In my case, the debian-provided xen patch had a small and luckily easy to fix clash with the mactel patch in the drivers/Makefile file. I was able to fix it by modifying the xen patch by hand to insert the necessary line at the end of the file, instead right next to the line which the mactel patch needed to modify.