Compile Linux Kernel on Ubuntu 12.04 LTS (Detailed)

  

This tutorial will outline the process to compile your own kernel for Ubuntu. It will demonstrate both the traditional process using ‘make’ and ‘make install’ as well as the Debian method, using ‘make-dpkg’. This is the detailed version of this tutorial, see Compile Linux Kernel on Ubuntu 12.04 LTS for the quick overview.  In any case, we begin by installing some dependencies:

sudo apt-get install git-core libncurses5 libncurses5-dev libelf-dev asciidoc binutils-dev linux-source qt3-dev-tools libqt3-mt-dev libncurses5 libncurses5-dev fakeroot build-essential crash kexec-tools makedumpfile kernel-wedge kernel-package

Note: qt3-dev-tools and libqt3-mt-dev is necessary if you plan to use ‘make xconfig’ and libncurses5 and libncurses5-dev  if you plan to use ‘make menuconfig’.  Next, copy the kernel sources with wget:

wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.2.17.tar.bz2

Extract the archive and change into the kernel directory:

tar -xjvf linux-3.2.17.tar.bz2 cd linux-3.2.17/

Now you are in the top directory of a kernel source tree. The kernel comes in a default configuration, determined by the people who put together the kernel source code distribution. It will include support for nearly everything, since it is intended for general use, and is huge. In this form it will take a very long time to compile and a long time to load.  So, before building the kernel, you must configure it. If you wish to re-use the configuration of your currently-running kernel, start by copying the current config contained in /boot:

cp -vi /boot/config-`uname -r` .config

Parse the .config file using make with the oldconfig flag.  If there are new options available in the downloaded kernel tree, you may be prompted to make a selection to include them or not.  If unsure, press enter to accept the defaults.

make oldconfig

Since the 2.6.32 kernel, a new feature allows you to update the configuration to only compile modules that are actually used in your system. As above, make selections if prompted, otherwise hit enter for the defaults.

make localmodconfig

The next step is to configure the kernel to your needs. You can configure the build with ncurses using the ‘menuconfig’ flag:

make menuconfig

or, using a GUI with the ‘xconfig’ flag:

make xconfig

In either case, you will be presented with a series of menus, from which you will choose the options you want to include. For most options you have three choices: (blank) leave it out; (M) compile it as a module, which will only be loaded if the feature is needed; (*) compile it into monolithically into the kernel, so it will always be there from the time the kernel first loads.

There are several things you might want to accomplish with your reconfiguration:

  • Reduce the size of the kernel, by leaving out unnecessary components. This is helpful for kernel development. A small kernel will take a lot less time to compile and less time to load. It will also leave more memory for you to use, resulting in less page swapping and faster compilations.
  • Retain the modules necessary to use the hardware installed on your system. To do this without including just about everything conceivable, you need figure out what hardware is installed on your system. You can find out about that in several ways.

Before you go too far, use the “General Setup” menu and the “Local version” and “Automatically append version info” options to add a suffix to the name of your kernel, so that you can distinguish it from the “vanilla” one. You may want to vary the local version string, for different configurations that you try, to distinguish them also.

Assuming you have a running Linux system with a working kernel, there are several places you can look for information about what devices you have, and what drivers are running.

  • Look at the system log file, /var/log/messages or use the command dmesg to see the messages printed out by the device drivers as they came up.
  • Use the command lspci -vv to list out the hardware devices that use the PCI bus.
  • Use the command lsub -vv to list out the hardware devices that use the USB.
  • Use the command lsmod to see which kernel modules are in use.
  • Look at /proc/modules to see another view of the modules that are in use.
  • Look at /proc/devices to see devices the system has recognized.
  • Look at /proc/cpuinfo to see what kind of CPU you have.
  • Open up the computer’s case and read the labels on the components.
  • Check the hardware documentation for your system. If you know the motherboard, you should be able to look up the manual, which will tell you about the on-board devices.

Using the available information and common sense, select a reasonable set of kernel configuration options. Along the way, read through the on-line help descriptions (for at least all the top-level menu options) so that you become familiar with the range of drivers and software components in the Linux kernel.

Before exiting the final menu level and saving the configuration, it is a good idea to save it to a named file, using the “Save Configuration to an Alternate File” option. By saving different configurations under different names you can reload a configuration without going through all the menu options again. Alternatively, you can backup the file (which is named .config manually, by making a copy with an appropriate name.

One way to reduce frustration in the kernel trimming process (which involves quite a bit of guesswork, trial, and error) is to start with a kernel that works, trim just a little at a time, and test at each stage, saving copies of the .config file along the way so that you can back up when you run into trouble. However, the first few steps of this process will take a long time since you will be compiling a kernel with huge number of modules, nearly all of which you do not need. So, you may be tempted to try eliminating a large number of options from the start

Now we are ready to start the build. You can speed up the compilation process by enabling parallel make with the -j flag. The recommended use is ‘processor cores + 1′, e.g. 5 if you have a quad core processor:

make -j5

This will compile the kernel and create a compressed binary image of the kernel. After the first step, the kernel image can be found at arch/i386/boot/bzImage (for a x86 based processor).  Once the initial compilation has completed, install the dynamically loadable kernel modules:

sudo make modules_install

The modules are installed in a subdirectory of “/lib/modules”, named after the kernel version. The resulting modules have the suffix “.ko”. For example, if you chose to compile the network device driver for the Realtek 8139 card as a module, there will be a kernel module name 8139too.ko. The third command is OS specific and will copy the new kernel into the directory “/boot” and update the Grub bootstrap loader configuration file ”/boot/grub/grub.cfg” to include a line for the new kernel.

Finally, install the kernel:

sudo make install

This command performs many operations behind the scenes.  Examine the /etc/grub.d/ directory structure before and after you run the above commands to see the changes.  Also look in the /boot/grub/grub.cfg file for your kernel entry.

The OS specific make install, Ubuntu in this case, also creates an initrd image in the /boot directory.  If you compiled the needed drives into the kernel then you will not need this ramdisk file to aid in booting.  For extra credit remove the created initrd from the /boot/ directory as well as the references in /etc/grub.d/*.

If there are error messages from any of the make stages, you may be able to solve them by going back and playing with the configuration options. some options require other options or cannot be used in conjunction with some other options. These dependencies and conflicts may not all be accounted-for in the configuration script. If you run into this sort of problem, you are reduced to guesswork based on the compilation or linkage error messages. For example, if the linker complains about a missing definition of some symbol in some module, you might either turn on an option that seems likely to provide a definition for the missing symbol, or turn off the option that made reference to the symbol.

Reboot the system, selecting your new kernel from the boot loader menu. Watch the messages. See if it works. If it does not, reboot with the old kernel, try to fix what went wrong, and repeat until you have a working new kernel

 

Debian Method:

Instead of the compilation process of above, you can alternatively compile the kernel as installable .deb packages. This improves the portability of the kernel, since installation on a different machine is as simple as installing the packages. Rather than using ‘make’ and ‘make install’, we use ‘make-kpkg’:

fakeroot make-kpkg – -initrd – -append-to-version=-some-string-here kernel-image kernel-headers

Unlike above, you cannot enable parallel compilation with make-kpkg using the -j flag. Instead, define the CONCURRENCY_LEVEL environment variable.

export CONCURRENCY_LEVEL=3

Once the compilation has completed, you can install the kernel and kernel headers using dpkg:

sudo dpkg -i linux-image-3.2.14-mm_3.2.14-mm-10.00.Custom_amd64.deb

sudo dpkg -i linux-headers-3.2.14-mm_3.2.14-mm-10.00.Custom_amd64.deb

 

25 Comments

  1. Dr. Brown

    How do you remove a kernel installed with “make install”?

    • If compiled and installed via make install, you will need to manually remove the following entries:
      /boot/vmlinuz*KERNEL-VERSION*
      /boot/initrd*KERNEL-VERSION*
      /boot/System-map*KERNEL-VERSION*
      /boot/config-*KERNEL-VERSION*
      /lib/modules/*KERNEL-VERSION*/

      Then update the grub configuration:
      sudo update-grub2

      If compiled via the Debian method, you can see the installed kernels with the following:
      dpkg --list | grep kernel-image
      And then unistall the desired kernel package with apt-get:
      sudo apt-get remove kernel-image-your-kernel-image

      • the_incapable

        What about the files in
        /usr/src/*KERNEL-VERSION*/ ?
        I even find folders with *KERNEL-VERSION* in

        /var/lib/dkms/virtualbox-guest/
        /var/lib/dpkg/info/

        It seems that it very hard to find all places where something is installed by make install. I would recommend to use the deb-package-way if possible, because of the easier uninstallation.

  2. Roshan

    Nice tutorial…
    Can you explain –append-to-version=-some-string-here kernel-image kernel-headers in the following command ?

    fakeroot make-kpkg –initrd –append-to-version=-some-string-here kernel-image kernel-headers

    • In it simplest form, the command here is make-kpkg. It is used to build kernel packages from Linux kernel sources, in our case, we want to create both the kernel-image and kernel-headers:
      make-kpkg kernel-image kernel-headers
      We use fakeroot so we can execute in a “fake root” environment:
      fakeroot make-kpkg kernel-image kernel-headers
      The –initrd flag is used to tell make-kpkg that this image requires an initrd (initial ramdisk):
      fakeroot make-kpkg --initrd kernel-image kernel-headers
      Finally, the –append-to-version=-some-string-here is used to give the package a human recognizable name. Just replace “some-string-here” with whatever you want to defferentiate between your kernel packages:
      fakeroot make-kpkg --initrd --append-to-version=-my_awesome_kernel kernel-image kernel-headers

  3. Bill Morita

    Thanks, you have done a nice job here.
    Please correct the text in the “fakeroot” line you give in the tutorial to use “–” rather than “-’ for options.
    I notice that you use the double dash in your response on may 23.

  4. Thanks for the post, I need a little help, I want to patch RTAI to the kernel, I need it for my cnc machine, Can you tell me how?
    Thanks again.

  5. MIchael,
    Awesome tutorial for setting up the kernel for modification. On that note, how would you add large block support to 64 bit kernels (since they don’t come standard)?

  6. Awesome article here! Thank you!

  7. Hi, do you know how to solve the virtualization problem?
    I cannot load my virtualbox since it said something to do with DKMS.. it worked with official Ubuntu repo kernel.

    I suspect maybe the module was not compiled.
    Tried to find the option in make menuconfig but could not be found.

  8. linuxnewbie

    I had migration process bug in my linux kernel(3.2.x), so I searched tutorial for kernel compiling to change to higher kernel version. I had hard time to find detailed tutorial and finally I found your post. This post really helped me out. Thanks for valuable information.

  9. dear michael, I found this tutorial was very helpfull. but, when I try it, I always can’t boot up properly. it always come a messages,
    “the disk drive for / is not ready yet or not present. continue to wait or..bla..bla..bla”

    and even I pressed ‘M’ to manualy recovery, remount then I reboot again it’ll always came up..
    I really messed up with this :(.
    would you give me a hand to solve this problem, please…

    • Hi andrean, I’ve experienced this issue before for two different reasons.

      In one case, the issue was caused by a very slow to load hard drive. This machine had an nonstandard SCSI/RAID setup and increasing the grub timeout corrected the problem.

      The other case was an EFI issue. This was solved by removing the /boot/efi entry from /etc/fstab.

      When you are prompted with the “disk drive for / is not ready yet or not present” error, try pressing ‘m’ for manual recovery, then: mount -o remount, rw /

  10. Hi. First of all, thanks for the tutorial.
    Now my question. I installed the new kernel using the first method (make install), everything was ok and the command “uname -a” shows my new kernel running; but the command “dpkg –get-selections|grep linux-image” don’t show the new kernel. Is possible to register the new kernel with dpkg when the compilation was as I did?

  11. thanks for the detailed information. I was able to build a custom kernel using this post.

    I have a problem with version mismatch though, which you might know how to solve.

    I am running Ubuntu 12.04.2 (precise) and I wanted to get the source for it.
    uname -r shows I am running 3.5.0.23-39
    After editing /etc/apt/sources.list to add the deb-src lines, I ran

    $ sudo apt-get source linux-image-$(uname -r)

    Instead of getting 3.5.0.23-35, it got me 3.5.0.-25-39. This was the output of the previous apt-get

    Picking ‘linux-lts-quantal’ as source package instead of ‘linux-image-3.5.0-23-generic

    NOTICE: ‘linux-lts-quantal’ packaging is maintained in the ‘Git’ version control system at:
    http://kernel.ubuntu.com/git-repos/ubuntu/ubuntu-precise.git

    I decided to go ahead and do a build with this source despite the version mismatch. It worked. I was able to reboot. When I ran a “uname -r”, it showed that it is running another kernel version – 3.5.7.4.

    I am aware that the distro kernels are different from the mainline kernels.
    Do you know if this kernel mismatch is fine ? If not, what do I need to do to fix it ? .

    • Prasad

      Sandeep sir, I am facing difficulties to connect internet in Thoshiba satellite C850 with Ubuntu 12.04. Eth0 & Wifi is not working. Can i solve this problem with a new kernel installation/ updation.

  12. Hi Michael,

    Thanks for very useful information.
    Need one help . I am trying to make changes in one of module inside USB called NCM. Please can you tell me the steps for incremental build. I do not want to recompile complete kernel .

  13. Gianmarco

    my computer doesn’t find commands like make oldconfig or make menuconfig,,,what can i do?

    • Gianmarco

      when i extract the archive i get an error
      “tar: cd: not found in the archive”

      • @Gianmarco – after “tar -xjvf linux-3.2.17.tar.bz2″, the string beginning “cd…” is another command, thusly: “cd linux-3.2.17/” (ie; Change Directory to where the source has been unzipped by the previous command). Enter it separately. Have fun!

  14. Ishit Patel

    Hi! Awesome Tutorial but i have a question…i want to do this I.T. project…i have to make my own Linux…From scratch.but what should I do…

    1.Compile your own kernel
    2.boot it
    3.put some GUI in it (preferably KDE)
    4.put some useful Softwares

    please correct me if i am wrong.i am currently compiling the kernel as i write…i used the procedure with 3.10.4 kernel…first extracted it then used the ‘make menuconfig’ and then saved it and then used the ‘make&&make modules_install&&make install’

    what should i do next

  15. di maria

    i have a question related to rtai.
    which rtai should i download for Linux ubuntu 3.5.0-23-generic
    and how can I parch it

  16. Nice, I just did My first compile. I also had a little help from some engineer friends I work with. We were having some difficulties with a Tape drive set up where I needed to be able to load the sg.ko module. I know it is compiled into the standard build of Ubuntu 12.04, but it was not functioning properly. Also if you guys want to build a new kernal from source on a machine that is running you can do apt-get source linux-image-’uname -r’-generic instead of using the wget method to download source.

  17. Best kernel build howto ever!

Trackbacks/Pingbacks

  1. Compile Linux Kernel on Ubuntu 12.04 LTS | MitchTech - [...] This is a quick overview of the compilation process, for a more thourough walkthrough, see Compile Linux Kernel on …
  2. make install command stuck at run-parts - feed99 - [...] trying to compile my own linux kernel. I have followed all the instructions at the following link Compile Linux …
  3. axe fx and linux - [...] 121 Unfortunately I don't know much about ubuntu, but I …
  4. Want to get into compiling the Kernel but still dont know where to start! - [...] compile unless you really have a good reason. https://help.ubuntu.com/community/Kernel/Compile http://mitchtech.net/compile-linux-k...-lts-detailed/ I too enjoyed Ubuntu 10.04 Lucid …
  5. linux kernel 3.8.8のコンパイル(ubunut12.04) | bobuhiro11's diary - [...] 参考 : Compile Linux Kernel on Ubuntu 12.04 LTS (Detailed) [...]
  6. trying to install easycap usb video capture device - [...] I don't know how to do it but I found this tutorial: http://mitchtech.net/compile-linux-k...-lts-detailed/ [...]
  7. [ubuntu] Help required to build ubuntu 12.04 kernel with custom requirements | WyldePlayground.netWyldePlayground.net - - [...] URL: http://mitchtech.net/compile-linux-k…-lts-detailed/ [...]
  8. [ubuntu] Help required to build ubuntu 12.04 kernel with custom requirements | Ubuntu InfoUbuntu Info - [...] URL: http://mitchtech.net/compile-linux-k…-lts-detailed/ [...]
  9. [ubuntu] Help required to build ubuntu 12.04 kernel with custom requirements | James n Sheri.comJames n Sheri.com - [...] URL: http://mitchtech.net/compile-linux-k…-lts-detailed/ [...]
  10. Failed to enable MSI-X | Ubuntu InfoUbuntu Info - […] I tried to make a copy of my kernel so I can use the copy of the .config to …

Leave a Reply