How to compile a kernel for Ubuntu Jaunty – Revised

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 my previous article. Lots ot the text in this article will look extremely similar to my previous article, but there are some big changes. If you already got the kernel source using git you will have to read my article on how to update the kernel sources to the latest version at my article Ubuntu Jaunty kernel sources changes.
Lets get started with creating our own custom kernel for Ubuntu Jaunty from scratch.


I’ll be using git to get the latest kernel version. 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 suggest adding my Launchpad repository to your system. The repository holds the latest version of git and is usually updated within a day of a new release of git, follow the instructions of the article Update Package: git 1.6.4 for Ubuntu Jaunty to add my repository.

I am compiling the i386 version, if you want to compile for amd64 you need replace i386 for amd64 throughout this article.


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 kernel-wedge
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

cd /d1/packaging/kernel/jaunty
git clone 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.master/changelog|more

Press q to get back to the prompt.
This results in something like this:

linux (2.6.28-15.52) 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   Thu, 27 Aug 2009 15:09:06 +0200

linux (2.6.28-15.51) jaunty-proposed; urgency=low

The latest version is the first version after the UNRELEASED section. In this case it is 2.6.28-15.52. 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-15.51 -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.master/config/i386/config .config
cat debian.master/config/i386/config.generic >> .config

If you want to compile a kernel for a server replace generic for server.

To make the modifications:

make menuconfig

When 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-15.50

ls debian.master/abi
cp debian.master/abi/2.6.28-15.50/i386/generic debian.master/abi/2.6.28-15.50/i386/core2
cp debian.master/abi/2.6.28-15.50/i386/generic.modules debian.master/abi/2.6.28-15.50/i386/core2.modules
cp ../config.core2 debian.master/config/i386/

We need to edit the following files

  • debian.master/scripts/misc/getabis
  • debian.master/rules.d/

In the next few parts I’ll explain what you need to change

File: debian.master/scripts/misc/getabis

Search for the line:

getall i386 generic server

Change it in:

getall i386 generic server core2

File: debian.master/rules.d/

Search for the line:

flavours        = generic server

Change it in:

flavours        = generic server core2

We need to make the compilation process aware of our own flavor we want to compile.

cp debian.master/control.d/vars.generic debian.master/control.d/vars.core2

If you want to compile a kernel for a server replace generic for server.

You can edit the file and make it your own.

arch="i386 amd64"
target="Geared toward Core2 systems."
bootloader="grub | lilo (>= 19.1)"
provides="kvm-api-4, redhat-cluster-modules, ivtv-modules, ndiswrapper-modules-1.9"

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.


It’s finally time for compiling but before we can start the compilation process there is one more step to do. I didn’t put this in the Preparations section as you need to the following step whether you make changes to the configuration or not

fakeroot debian/rules clean

To start the compilation.

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. 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


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-15-core2_2.6.28-15.51_i386.deb
dpkg -i linux-headers-2.6.28-15-core2_2.6.28-15.51_i386.deb linux-headers-2.6.28-11_2.6.28-11.51_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.
I wrote up an article how to update your custom kernel if a newer version of the Jaunty kernel has been released.

This article is filed under the categories Ubuntu » Compile a kernel and has the following tags associated with it: , , , , .

For more of the same articles see the page Compile a kernel for Ubuntu overview
  • Deacon

    Hey Peter,

    thanks for the great post! It helped me a lot as I have never worked with git before. Looking forward to the upcoming “update the custom version” blog post… 😉

    (One remark: In the preparation section also the “kernel-wedge” package should be installed)

    • I’m glad you found the article useful and also thank you for the missing package, I changed the article accordingly,

    • If you’re having trouble compiling:

      make[1]: *** No rule to make target `binary-core2′. Stop.

      That probably means you might be running AMD64 and were copying stuff into the i386 folders. I made this mistake myself 🙂

  • Apologies for the comment on the previous article, did not see the revised version. Works for me, thank you Peter!

  • Jasmine Hasan

    Added this updated link in , since it was still only pointing to the old (intrepid) article..

  • Jasmine Hasan

    Minor addition regarding the part: `cp ../config.core2 debian.master/config/i386/`

    I’m on Karmic, and I noticed that the syntax changed to config.flavour.
    So keep that in mind if you’re on Karmic `cp ../config.core2 debian.master/config/i386/config.flavour.core2″

  • mike

    Thansk for the compilation walk-through. It’s very interesting for a linux new comer.

    However I’ve got a few problems.

    I’m trying to compile a kernel to make a minor modification on the CONFIG_SATA_PMP setting, to correct for a HW bug in AMD SB700 south bridge controller.

    See this thread:

    The installed system is unstable, to the point where it will flake-out while trying to clone git. So I’m having to use a LiveCD.

    This is the last error message I got during compilation:

    LD [M] net/ipv4/netfilter/nf_nat_proto_udplite.ko
    net/ipv4/netfilter/nf_nat_proto_udplite.ko: finalnet/ipv4/netfilter/nf_nat_proto_sctp.ko close failed: No space left on device
    : final close make[4]: *** [net/ipv4/netfilter/nf_nat_proto_udplite.ko] Error 1
    fmake[4]: *** Waiting for unfinished jobs….
    ailed: No space left on device
    make[4]: *** [net/ipv4/netfilter/nf_nat_proto_sctp.ko] Error 1
    LD [M] net/ipv4/netfilter/nf_nat_sip.ko
    make[3]: *** [modules] Error 2
    make[2]: *** [sub-make] Error 2
    make[1]: *** [/home/ubuntu/kernel/source/debian/stamps/stamp-build-core3] Error 2
    make: *** [binary-core3] Error 2

    I can’t understand why its not working. Any ideas?

    • Ritesh Sinha

      @mike: Hi Mike, I was facing a similar problem with Jaunty and the SB700. I was able to recompile the kernel with CONFIG_SATA_PMP disabled (on an installed system of course, not via a livecd). In your case, it seems that you have an out of space error. What you could do of course, is to use a Live USB stick as opposed to a CD (with an persistence overlay of 2-3 GB). Instructions to do this can be found on PenDriveLinux.

      Unfortunately, recompiling the kernel did not fix it for me, I switched to Karmic Alpha. Karmic is working great for me, the errors I had with the SB700 device have now disappeared.

  • mike

    Hi Ritesh, thanks for the advice.

    I initially tried the compilation with 2gb of RAM installed, got the out of sapce errors and then tried it with 8gb of RAM. I did get further along the compilation process with more RAM. With 2gb approx. 10 minutes and approx 16 minutes with 8gb. I thought that amount of RAM sould have been adeqaute. I was woundering, does the compilation process create a temporary directory and that it was perhaps limited to how large it could grow?

    I was also a little dubious about setting CONFIG_SATA_PMP=n. It seems like it was just a bit to easy to fix it that way.

    I’ll give the pendrive method a try. I was going to wait until Karmic was a liitle more mature but I think I’ll give it go. I’ve learnt more trying to get a broken sytem working than I would have on a system that works perfectly!!

    • The compilation process runs in the debian directory. So check the space you have on the drive that holds your git repository.

      I cleaned my latest compilation, so i can’t tell you how much space it takes up. I’ll run a compilation and tell you 🙂

      Well compilation just finished: The directory is about 3.6 GB big, this is the entire kernel directory, sources and compiled sources.

      • mike

        Hi Peter,

        Thanks for that. I’m going to mount the entire directory in RAM using tmpfs and clear as much sytem memory as possible before I begin. I’ve allocated 6GB, hopefully that should be enough. I’ll let you know how it goes. Thanks again.

        • mike

          Well, the compilation worked using Xubuntu 9.04 LiceCD. If anyone’s interested here’s what I did:

          Mounted the ramdisk: mount -t tmpfs -o size=6G,mode=0777 tmpfs /path/to/dir/
          Disabled as many processes I thought possible (though I don’t think that made much difference) and then dropped the mem caches: echo 3 > /proc/sys/vm/drop_caches

          The CONFIG_SATA_PMP=n didn’t make the slightest difference!

  • Gcarlo

    i have had an error while i have tried to compile:

    root@ubsrv904a:/dl/packaging/kernel/jaunty/source# CONCURRENCY_LEVEL=2 NOEXTRAS=1 skipabi=true skipmodule=true fakeroot debian/rules binary-core2
    make[1]: *** No rule to make target `binary-core2′. Stop.
    make: *** [binary-core2] Error 2

    where i have made a mistake?

    • Check the files:
      File: debian.master/rules.d/

      and make sure you copy
      cp debian.master/control.d/vars.generic debian.master/control.d/vars.core2

      • Gcarlo

        Im getting crazy, both getabis and files are ok, i mean in both file “core2” have been added at the end of the lines following your advices.
        vars.generic file have been copied into vars.core2 file and then i have edited vars.core2 following your advices to change 2nd and 3rd lines.

        unfortunately im still having the same error:
        root@ubsrv904a:/dl/packaging/kernel/jaunty/source# CONCURRENCY_LEVEL=2 NOEXTRAS=1 skipabi=true skipmodule=true fakeroot debian/rules binary-core2
        make[1]: *** No rule to make target `binary-core2′. Stop.
        make: *** [binary-core2] Error 2

        i really hope you could help me,
        thanx in advance

    • Did you also ran

      fakeroot debian/rules clean

      before starting the compilation?

    • Todor

      Are you by chance using ubuntu-karmic.git? If so read up, one of the comments says about how the file debian.master/config/???/config.core2 has to be renamed to debian.master/config/???/config.flavour.core2

  • tenoreamer

    I have made a kernel compilation using make-kpkg. Then I found I should compiled in ‘lzo’ instead of leaving it as a module. I make the change using make menuconfig.
    Does such a trial modification took a complete compilation after ‘make-kpkg clean’ again? Or is there any simpler way?

    Another question:
    Will ‘make-kpkg’ way for compilation be deprecated? Why?

    Thanks in advance

  • danny

    I am trying to apply a patch to my kernel, and apply the patch before running ‘make menuconfig.’ However, it seems that the ‘git reset –hard’ reverts the patch, and the resulting kernel does not have my patch in it. What do I need to do differently to apply a kernel patch to Jaunty?

    • What does the patch patch? If it adds an option to the menu, the best thing to do is after you copied the config, and do the
      git reset –hard
      git clean -xdf

      apply the patch in the “Getting ready for compilation” section again.

      I stress it really depends on the patch and what it patches.
      Should me an email through my Contact page if you need more help. If we get it working I’ll post it here when we’re done.

  • Max

    Hi Peter, Thanks for the interesting and clear HowTo. I hope you can advice me: Do I need to recompile the kernel in order to have the ATI driver (fglrx) compiled in the kernel? I am using Ubuntu/Kubuntu Jaunty. My problem is that both Gnome (2.26) or KDE (4.3.2) are veeery slow. They also sporadically stop responding when playing Amarok or when playing a movie (Kaffeine or VLC). Also, by mistake I installed the 32-bit version, instead of the 64-bit (I have an AMD 64-bit system). Any ideas? Thanks a lot.

    • I don’t think you need to recompile the kernel for the graphics driver. Just download the 32bit driver and follow their instructions on how to install it.

  • Igor

    Copying over .conf file DOES NOT WORK with KARMIC KOALA kernel! In order to configure the kernel you need to issue:

    debian.master/scripts/misc/kernelconfig editconfig

    It took me 2 days to figure that out, see:

    The whole kernel compilation scripts are poorly documented! What are you thinking ubuntu devs?!

  • Thank you very much for this great tutorial, it’s full of details. I needed to tweak kernel because of special needs I had and also I wanted to keep up with the ‘kind of’ ubuntu way of compiling it and to install it from debs. Then I found your blog, awesome one btw! Also I noticed that “skipabi=true skipmodule=true” could be replaced by AUTOBUILD=1 wich adds nodbg=1 too, but I did have to add no_dumpfile=yes so the overall compiling process could succceed, otherwise I get the error “get_debug_info: Can’t create a handle for a new debug session.”
    I used “git tag | sort -t – -k 3 -n | tail” to pick the newest versions what do you think? why not directly look at the debian.master/abi/* folders (assuming this is a fresh new pulled repo)?
    May I add that your tutorial was helpfull for me to also compile linux-backports-modules from git repo? Maybe I’ll have it translated into french and put in my homesite someday because this saved my life dude! many many thanks…

    • AUTOBUILD on the command line won’t work, you will have to edit the 0-common-vars file. This will also imply that the docs won’t be build.

      The result of the git tag and sort line does not result in the latest version.
      There are some “weird” tags in git, the result of your line is:

      The latest stable tag is : 2.6.28-16.57

      The debian.master/abi directory is actually the previous release. In the master tree of git you will see Ubuntu-2.6.31-15.50 but that is because the developers are working on 2.6.31-16.51. Sometimes when you pull the source they are not working on the next release yet and you’ll end up with the previous release.

  • thanks for this post man. really helped me. 1 question though. if i will recompile my custom kernel (i mean after the new kernel is compiled using this tutorial), do i still need to follow the same steps? thanks