Ubuntu Jaunty has been released a few days ago so it’s time write up an article on how to compile your own kernel for Ubuntu Jaunty.
As of Ubuntu Jaunty’s kernel 2.6.28-15.49 the kernel developers have made changes to the kernel source. The changes have such a big impact on how to compile a kernel for Ubuntu Jaunty that I had to revise this article. I wrote up a new article, I strongly suggest following the new article. I’m keeping this article for historic references.
I’ll be using git to get the latest kernel version. As I have described in previous articles, this is my favorite way to get the sources and it is in my opinion the fastest way to make changes later on when you want to update your own kernel to the latest version. I am compiling the i386 version, if you want to compile for amd64 you need replace i386 for amd64 throughout this article.
I suggest adding my Launchpad repository to get the latest version of git, follow the instructions of the article Updated git packages for Ubuntu Jaunty to add my repository.
Preparations
Let’s get started on preparing our machine for compiling our own kernel for Ubuntu Jaunty.
Open a terminal.
sudo su - apt-get install fakeroot build-essential apt-get install crash kexec-tools makedumpfile apt-get build-dep linux apt-get install git-core libncurses5 libncurses5-dev
Create a directory where you would like to build your kernel, this directory will hold the kernel source in a sub directory and all the deb files will end up in this folder. I choose /d1/packaging/kernel/jaunty .
Getting the source
/d1/packaging/kernel/jaunty git clone git://kernel.ubuntu.com/ubuntu/ubuntu-jaunty.git source
The source code is installed in the directory source.
We will create a branch in which we will be doing our modifications. That way the master branch will stay in tact which will make future updates a whole lot easier.
To see the latest version:
cd source cat debian/changelog|more
Press q to get back to the prompt.
This results in something like this:
linux (2.6.28-12.43) UNRELEASED; urgency=low CHANGELOG: Do not edit directly. Autogenerated at release. CHANGELOG: Use the printchanges target to see the curent changes. CHANGELOG: Use the insertchanges target to create the final log. -- Stefan Bader <stefan.bader@canonical.com> Thu, 16 Apr 2009 20:11:13 +0200 linux (2.6.28-11.42) jaunty; urgency=low
The latest version is the first version after the UNRELEASED section. In this case it is 2.6.28-11.42. Sometime there is no UNRELEASED section and in that case the latest version is the first version you see.
You could select any version you see in the changelog but for the sake of this article we’ll use the latest version.
git checkout Ubuntu-2.6.28-11.42 -b core2
This will create a branch called core2.
Creating a new config
I’ll be using the method of creating a new flavor, this adds a bit more work but you can always compile the original kernels.
Important: If you upgraded to Jaunty from a previous version of Ubuntu by using the update-manager or by hand using apt-get/aptitude and you were running a custom kernel you will need to create a new config based on the config of Jaunty. I used my “old” config file and ran into several strange behaviors.
To create a clean config:
cp debian/config/i386/config .config cat debian/config/i386/config.generic >> .config
If you want to compile a kernel for a server replace generic for server.
To make the modifications:
make menuconfigWhen you’re done we make a backup of the config file.
mv .config ../config.core2
Now we need to clean up the git tree
git reset --hard git clean -xdf
Getting ready for compilation
Because we are going to be creating a new flavor based on a existing flavor (generic in my case) we need to create some extra files. During compilation the process checks the previous release for some settings, as we’re creating a local flavor it doesn’t exist in the source, so we’re creating it. The previous release in this case is 2.6.28-11.42, you can the previous release
ls debian/abi
cp debian/abi/2.6.28-11.41/i386/generic debian/abi/2.6.28-11.41/i386/core2 cp debian/abi/2.6.28-11.41/i386/generic.modules debian/abi/2.6.28-11.41/i386/core2.modules cp ../config.core2 debian/config/i386/
We also need to edit some files
- debian/scripts/misc/getabis
- debian/rules.d/i386.mk
- debian/control.stub
- debian/control
In the next few parts I’ll explain what you need to change
File: debian/scripts/misc/getabis
Search for the line:
getall i386 generic server
Change it in:
getall i386 generic server core2
File: debian/rules.d/i386.mk
Search for the line:
flavours = generic server
Change it in:
flavours = generic server core2
Files: debian/control.stub and debian/control
For both files we need to copy three sections:
- Package: linux-image-2.6.28-11-generic
- Package: linux-headers-2.6.28-11-generic
- Package: linux-image-debug-2.6.28-11-generic
A section is defined from the line Package to the next line starting with Package.
In the copied sections we need to replace “generic” with “core2″ on all the lines that start with Package.
Now we need to commit our changes in the git repository
git add . git commit -a -m "Core2 modifications"
The text after -m is the message you add to your commit.
Compilation
It’s finally time for compiling.
CONCURRENCY_LEVEL=2 NOEXTRAS=1 skipabi=true skipmodule=true fakeroot debian/rules binary-core2
Because I have a Dual Core I want to utilize both processors by setting the CONCURRENCY_LEVEL. Set this to the amount of processors you have, if you have only one, just skip it completely. No matter grab yourself some coffee while we’re compiling.
It’s wise to also run the following.
CONCURRENCY_LEVEL=2 NOEXTRAS=1 skipabi=true skipmodule=true fakeroot debian/rules binary-indep
Installation
After the compilation is finished we’ll have several deb files in the parent directory. To install the files
cd .. dpkg -i linux-image-2.6.28-11-core2_2.6.28-11.42_i386.deb dpkg -i linux-headers-2.6.28-11-core2_2.6.28-11.42_i386.deb linux-headers-2.6.28-11_2.6.28-11.42_all.deb
Check your bootloader if the newly installed kernel is the default one, for grub edit the file /boot/grub/menu.lst
Reboot and enjoy your newly installed kernel.
In the next few days I’ll also post an article on how to update your custom if a newer version of the Jaunty kernel has been released.



By using your method, does that make the kernel compatible with dkms? That’s important to me as I use Virtualbox and the kernel module needs to be recompiled every time the kernel is updated, which dkms usually takes care of for me. I also use an NVidia video card as well, so how would that factor in?
I’m looking into new kernels to see if the screen brightness app on my laptop will start working.
I do believe it should work. I have never worked with dkms but the man page says:/ /build/.
build Builds the specified module/version combo for the specified ker‐
nel. If no kernel is specified it builds for the currently run‐
ning kernel. All builds occur in the directory
/var/lib/dkms/
An automatic build won’t be triggered is just the ABI number changes, but this is the same behavior as the official kernel.
Example: 2.6.28-11.42 updated to 2.6.28-11.43 won’t trigger a dkms building process.
2.6.28-11.42 updated to 2.6.28-12.34 will trigger the event.
I do not understand what to do in this part:
——————————————————-
“Files: debian/control.stub and debian/control
For both files we need to copy three sections:
Package: linux-image-2.6.28-11-generic
Package: linux-headers-2.6.28-11-generic
Package: linux-image-debug-2.6.28-11-generic
A section is defined from the line Package to the next line starting with Package.
In the copied sections we need to replace “generic” with “core2″ on all the lines that start with Package.”
——————————————————-
can someone give me a help ? thanks!
If you look at the control file you will see something like this (the versions have changed since I wrote the article):
Package: linux-image-2.6.28-14-genericArchitecture: i386 amd64
Section: base
Priority: optional
Pre-Depends: dpkg (>= 1.10.24)
Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules, ivtv-modules, ndiswrapper-modules-1.9
Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda
Conflicts: hotplug (< < 0.0.20040105-1)
Recommends: grub | lilo (>= 19.1)
Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28
Description: Linux kernel image for version 2.6.28 on x86/x86_64
This package contains the Linux kernel image for version 2.6.28 on
x86/x86_64.
.
Also includes the corresponding System.map file, the modules built by the
packager, and scripts that try to ensure that the system is not left in an
unbootable state after an update.
.
Supports Generic processors.
.
Geared toward desktop systems.
.
You likely do not want to install this package directly. Instead, install
the linux-generic meta-package, which will ensure that upgrades work
correctly, and that supporting packages are also installed.
Package: linux-headers-2.6.28-14-generic
Architecture: i386 amd64
Section: devel
Priority: optional
So you copy the lines starting with Package: linux-image-2.6.28-14-generic up to line just above Package: linux-headers-2.6.28-14-generic, you do this for all three sections.
In the copied sections you replace generic with core2 so if we would apply that to the above example it would look like this:
Package: linux-image-2.6.28-14-core2
Architecture: i386 amd64
Section: base
Priority: optional
Pre-Depends: dpkg (>= 1.10.24)
Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules, ivtv-modules, ndiswrapper-modules-1.9
Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda
Conflicts: hotplug (< < 0.0.20040105-1)
Recommends: grub | lilo (>= 19.1)
Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28
Description: Linux kernel image for version 2.6.28 on x86/x86_64
This package contains the Linux kernel image for version 2.6.28 on
x86/x86_64.
.
Also includes the corresponding System.map file, the modules built by the
packager, and scripts that try to ensure that the system is not left in an
unbootable state after an update.
.
Supports Core2 processors.
.
Geared toward desktop systems.
.
You likely do not want to install this package directly. Instead, install
the linux-generic meta-package, which will ensure that upgrades work
correctly, and that supporting packages are also installed.
Hope this helps
Thanks for the instructions but I think the link below has a better and easier instruction set to compile a debian kernel.
http://ubuntuforums.org/showthread.php?t=43065&highlight=kernel+compilation
The procedure is dated 2005 and the ‘linux-tree’ is no longer an installable
package.
When it comes to simplicity I like to know what I am compiling.
I have been compiling kernel.org kernels for 10 years and this procedure
that Peter describes is no more complicated that most of the others out there
including the one you mentioned.
Just m2c.
jt
cp debian/config/i386/config.generic >> .config
cp should be replaced with cat
Thanks for that catch
Thanks Peter
This procedure is quite easily scriptable in bash and it
works good.
jt
Thanks for the walk-thru. I needed this to disable frequency scaling on my kernel, as that un-overclocks my pin-modded processor from 2.6 Ghz to 1.8Ghz (not a small drop-off). This let me recompile my kernel the Ubuntu way, and keep it all happy in dpkg. Awesome job!
–>> Because I have a Dual Core I want to utilize both processors <> debian/rules.d/i386.mk <<–
o.O
How lost is that? Why would you do so? -.-
I know I could run the 64bit version instead of the i386 version but I do run some applications not available in the official repository.
I don’t feel like giving 64bit a shot only to determine that some of my apps don’t work and having to move back to 32bit.
Currently I use my laptop to develop web apps in PHP, Javascript. so I don’t know if I will see a huge benefit with a 64bit system. For the creation of packages it would be a big improvement.
Maybe if I have a spare computer some day I’ll give 64bit a shot.
Hi, thanks for the guide! I am now building karmic’s kernel to use in jaunty (because of Intel drivers regressions).
I just want to add that for those having problems with makedumpfile like the “get_debug_info: Can’t create a handle for a new debug session” because you removed kernel debug info while configuring it, you can pass “no_dumpfile=true” the same way you pass “skipabi=true” in the build line.
And now I got another problem. I am using “aa1″ where you used “core2″ as I want to build a kernel for my aspire one, and that (besides a heavily modified .config) seems to be the main difference to your howto. Still, I get a empty source/debian/linux-image-2.6.30-8-aa1/lib/modules/2.6.30-8-aa1 directory (only a initrd directory below it), and the modules are placed in 2.6.30-8-aa1-00009-gd8dbde1. That of course means that debian/tests/check-aliases fails unless I remove the empty 2.6.30-8-aa1 and symlink 2.6.30-8-aa1-00009-gd8dbde1 to it.
Any idea what am I doing wrong here? Maybe some config setting?
Thanks.
doh – CONFIG_LOCALVERSION_AUTO was set. Sorry for the previous comment.
Nice Backup: “mv .config ../config.core2″
Thanks for the guide. It. was very helpful to me.
Hi,
thank you for your very informative guide. At least for the karmic sources there’s a difference in the part:
Getting ready for compilation.
The copy of config should look like this:
$ cp ../config.core2 debian/i386/config.flavour.core2
For both files we need to copy three sections:
* Package: linux-image-2.6.28-11-generic
* Package: linux-headers-2.6.28-11-generic
* Package: linux-image-debug-2.6.28-11-generic
A section is defined from the line Package to the next line starting with Package.
In the copied sections we need to replace “generic” with “core2″ on all the lines that start with Package.
Copy files to where? You mean to say copy these to the same file with the changes?
Yes copy the sections, within the same file
CONCURRENCY_LEVEL=4 NOEXTRAS=1 skipabi=true skipmodule=true fakeroot debian/rules binary-core4
I have quad core so i set concurrency_level=4
but when i execute the above command im greeted with this:
/usr/bin/fakeroot: line 176: debian/rules: No such file or directory
I followed your guide to the T changing only the following:
core2 > core4
i386 > Amd64
Packages with “generic” to “core4″
what am i doing wrong here?
Sounds like you are in the wrong directory.
If you have everything in : /d1/kernel/jaunty that where you execute the command.
Hi Peter
Out of all the “compiling kernel guides” on the net, you are the only one playing with:
* debian/scripts/misc/getabis
* debian/rules.d/i386.mk
* debian/control.stub
* debian/control
where can I get official info about those files, why no one else modifies those files?
I’m wondering this now cause I never had problem compiling the kernel for debian or ubuntu and never had modified those files either. But now I’m compiling a kernel for a small distro based in debian and I get the following error:
dpkg-gencontrol -DArchitecture=i386 -isp -plinux-image-2.6.26-geode-v1 -P/usr/src/linux/debian/linux-image-2.6.26-geode-v1/
dpkg-gencontrol: error: package linux-image-2.6.26-geode-v1 not in control info
make[2]: *** [debian/stamp/binary/linux-image-2.6.26-geode-v1] Error 255
make[2]: Leaving directory `/usr/src/linux-source-2.6.26-voyage’
make[1]: *** [debian/stamp/binary/pre-linux-image-2.6.26-geode-v1] Error 2
make[1]: Leaving directory `/usr/src/linux-source-2.6.26-voyage’
make: *** [kernel_image] Error 2
It seems that I need to set up those files in a similar way as you do…
can you suggest me something ?
Thanks
For karmic, things change a little. You no longer edit control, but create a vars.core2 inside debian/control.d (I just copied vars.generic, removed the amd64 architecture entry and changed the description), and run “debian/rules debian/control” to generate the control file before building the kernel. Also, as Gunnar writes above, the config files now have a config.common.arch and a config.flavour.”flavour”.
Is there a full description of karmic files or a guide to compile kernel 2.6.31-X for karmic. I am trying to create new flavour for xps laptops, huge config changes, but I think i need to split config before start the compile.
I don’t have karmic installed, don’t have a spare computer for it. I think if you would follow the suggestions given here about Karmic, you should be able to pull it off.
The hardest part for me in building for karmic (even more thansetting up the chroot to build a lpia kernel) was the config files. You need to copy your config to (assuming the same values as the examples above) debian/config/i386/config.flavour.core2
Then you need to run “debian/scripts/misc/kernelconfig editconfig” which will do a menuconfig on all config files, allowing you to change yours or any of them, and finally will merge common stuff to the common scripts (debian/config/config.common.ubuntu & debian/config/config.common.ports, besides the ones already mentioned) and split the separate stuff into each flavour file.
PS: I am typing the config.* names as I recall them, since I am not on my pc right now.
hi,
I have done everithing changing i386 with amd64, but when I try to compile the kernel I get:
# CONCURRENCY_LEVEL=2 NOEXTRAS=1 skipabi=true skipmodule=true fakeroot debian/rules binary-core2
make: *** No rule to make target `binary-core2′. Stop.
Any ideas?
Thanks
You can’t cross compile, that is build a kernel for one architecture while running a different architecture, using this method (or at least I have not found how to do it). To build a amd64 kernel, you have to be running a amd64 distribution or a amd64 chroot. I stumbled on the same problem trying to build a lpia kernel, and solved it by creating a chroot. Just google for “chroot ubuntu” and you’ll find quite a few suggestions.
If someone has a easier solution towards cross compiling a kernel….
Guys, first thanks for your help. I finally nailed it, its even easier to compile in karmic. See my blog for procedure to do it in karmic.
Thank you Peter for the very detailed article on compiling kernels. However without sounding like a git myself, I noticed that after I had cloned the Jaunty tree, the debian directory doesn’t contain any of the files that require editing. Instead, these files are under the debian.master directory.
Are the two directories fundamentally different or do I edit the files in the debian.master directory and proceed? I tried doing that (editing the files under debian.master instead of debian) but the build stage fails (Error: couldn’t find debian/control).
Its probably a stupid mistake on my part but I’d be really grateful if you could point out where I’ve screwed up. Again, thanks for taking the time to write the detailed instructions.