≑ Menu

How to Compile Linux Kernel from Source to Build Custom Kernel

Linux kernel is the life force of all Linux family of operating systems including Ubuntu, CentOS, and Fedora.

For most part, you don’t need to compile the kernel, as it is installed by default when you install the OS. Also, when there is a critical update done to the kernel, you can use yum, or apt-get to update the kernel on your Linux system.

However you might encounter certain situation, where you may have to compile kernel from source. The following are few situation where you may have to compile Kernel on your Linux system.

  • To enable experimental features that are not part of the default kernel.
  • To enable support for a new hardware that is not currently supported by the default kernel.
  • To debug the kernel
  • Or, just to learn how kernel works, you might want to explore the kernel source code, and compile it on your own.

In this tutorial, we’ll explain how to compile Linux kernel from source.

Also, please note that if you just want to compile a driver, you don’t need to compile the kernel. You need only the linux-headers package of the kernel.

1. Download the Latest Stable Kernel

The first step is to download the latest stable kernel from kernel.org.

# cd /usr/src/

# wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.9.3.tar.xz

2. Untar the Kernel Source

The second step is to untar the kernel source file for compilation.

# tar -xvJf linux-3.9.3.tar.xz

3. Configure the Kernel

The kernel contains nearly 3000 configuration options. To make the kernel used by most people on most hardware, the Linux distro like Ubuntu, Fedora, Debian, RedHat, CentOS, etc, will generally include support for most common hardware. You can take any one of configuration from the distro, and on top of that you can add your own configuration, or you can configure the kernel from scratch, or you can use the default config provided by the kernel.

# cd linux-3.9.3

# make menuconfig

The make menuconfig, will launch a text-based user interface with default configuration options as shown in the figure. You should have installed “libncurses and libncurses-devel” packages for this command to work.

We will use the default config provided by the kernel. So select “Save” and save the config in the file name “.config”.

The following is a sample of the “.config” file:


4. Compile the Linux Kernel

Compile the main kernel:

# make

Compile the kernel modules:

# make modules

Install the kernel modules:

# make modules_install

At this point, you should see a directory named /lib/modules/3.9.3/ in your system.

5. Install the New Kernel

Install the new kernel on the system:

# make install

The make install command will create the following files in the /boot directory.

  • vmlinuz-3.9.3 – The actual kernel
  • System.map-3.9.3 – The symbols exported by the kernel
  • initrd.img-3.9.3 – initrd image is temporary root file system used during boot process
  • config-3.9.3 – The kernel configuration file

The command “make install” will also update the grub.cfg by default. So we don’t need to manually edit the grub.cfg file.

6. Boot Linux to the new Kernel

To use the new kernel that you just compiled, reboot the system.

# reboot

Since, in grub.cfg, the new kernel is added as default boot, the system will boot from the new kernel. Just in case if you have problems with the new kernel, you can select the old kernel from the grub menu during boot and you can use your system as usual.

Once the system is up, use uname command to verify that the new version of Linux kernel is installed.

$ uname -r

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

{ 28 comments… add one }

  • Anthony June 13, 2013, 6:10 am

    Nowdays, all computer’s CPU are multicore, multithreaded. It would have been nice to show “make -j N” with N the number of (core * thread-by-core) to help built faster… otherwise it can take forever!
    ’nuff said!

  • Deepak June 13, 2013, 8:36 am

    one more reason to compile a kernel is if we want to install latest kernel whose rpm is not available yet.

  • me June 13, 2013, 8:38 am

    You make no mention of things like
    make localmodconfig
    to avoid making hundred of unnecessary modules.
    Maybe I don’t want gcc on every linux pc, how can an rpm be made.
    Your making the compile extremely slow by not including “-j #” representing the number of concurrent compiles.
    This is guide is far from complete.

  • Feiticeir0 June 13, 2013, 8:50 am

    Or if you don’t want all the bloatware that comes with predefined kernels from your distro – although it packs security and enhancement patches.

  • me June 13, 2013, 8:57 am

    If present, this is the current running config file compressed.

  • Jalal Hajigholamali June 13, 2013, 8:59 am


    Thanks a lot,

    useful article…

  • Koratsuki June 13, 2013, 9:25 am

    @Deepak: Or use new options/drivers/configs unavailable on older kernels… Nice article πŸ˜€

  • Bob June 13, 2013, 10:42 am

    Nice article. Thanks

  • John Yost June 13, 2013, 1:13 pm

    I believe make install updates the lilo.config file not grub.cfg

  • Jim Lee June 13, 2013, 3:28 pm

    I used to do steps #4 and #5 for my Debian (Sid) install but sometimes found that I needed the associated headers to satisfy dependencies for things I wanted to install or recompile afterward (like VMWare player, for example); many times those headers were not available, especially if I was compiling a bleedding-edge kernel.

    These days I just use “make deb-pkg” instead. This takes care of the compile and produces the “linux-firmware-image”, “linux-image”, “linux-headers” and “linux-libc-dev” .deb packages. A subsequent “dpkg -i *.deb” installs these packages and satisfies those dependencies.

  • Daniel June 13, 2013, 3:49 pm

    Very nice article. But you could have given a warning like “This may take some time, so don’t do it right before you are going to bed”… Now I’ll have to wait! πŸ˜€

  • chris June 15, 2013, 12:09 pm

    hi i tried to install kernel-3.9.0 but it got interupted during compiling (after entering the make command).it logged out by itself.so i logged in and assuming that the compiling was over i proceded to compile the modules and install it .
    when i entered the ‘make install ‘ command it requested to redo the make make process.and then install.

    after rebooting the resolution changed and the keyboard and mouse stopped working.
    i’m currently using the old kernel and i would like to delete the one that i installed.

  • Ethan June 16, 2013, 3:07 am

    Good to see the concise explaination by Lakshmanan.

  • Chad June 19, 2013, 11:24 am

    There’s no auto pilot here.
    And customizing kernel is not for the faint of heart , you should read quite a lot before you actually start customizing it.

  • Anonymous July 1, 2013, 10:18 am

    make bzImage;
    make modules && make modules_install

  • Gomathi August 22, 2013, 5:45 am

    The BEST!

  • YektaPardaz October 4, 2013, 10:36 am

    Thanks for nice article.

    But I have a question. How can I config kernel source for best performance on my vps? I mean is there a way to remove unnecessary modules of kernel before building it? Modules like new VGA support, new other file-system support(other than ext3 and ext4), .. . I’m looking for ways to make my custom kernel as small and fast as possible.

  • cybernard October 7, 2013, 6:21 am

    make localmodconfig

    that eliminates all modules not currently loaded in memory.

  • Quamar Niyaz March 12, 2014, 5:08 pm

    Nice and very concise tutorial!!! I think it needs two more commands to get executed after going through these steps:
    1. sudo update-initramfs -ck 3.9.3
    2. sudo update-grub

    After executing these commands, we will get initrd.img-3.9.3 in /boot directory and grub menu will be updated with new kernel boot options.

    Thanks !!!

  • Akshay March 19, 2014, 2:47 am

    When I run ‘make’ command, it shows the following error:

    make[1]: *** No rule to make target `/usr/src/linux-headers-3.8.0-29-generic/arch/x86/syscalls/syscall_32.tbl’, needed by `arch/x86/syscalls/../include/generated/uapi/asm/unistd_32.h’. Stop.
    make: *** [archheaders] Error 2

  • sandeep April 21, 2014, 9:20 am

    I am getting the following error after running make while upgrading my kernel to new kernel 3.9:

    sdp@sdp-Dell-System-Vostro-3450:/usr/src/linux_latest_dev_src_tree/linux-git$ make
    GEN usr/initramfs_data.cpio
    /usr/src/linux_latest_dev_src_tree/linux-git/scripts/gen_initramfs_list.sh: line 51: ${output}: ambiguous redirect
    make[1]: *** [usr/initramfs_data.cpio] Error 1
    make: *** [usr] Error 2
    ${output} is “”, Can you please help??

  • Suryaprathap April 23, 2014, 6:13 am

    I tried to build a kernel from source rpm.
    running os is fedora 12 (
    source rpm is kernel-

    It is successfully builded.But kernle configuration file is not generated in /boot directory.
    Can you please help me to solve this issue.

  • Mayur May 17, 2014, 12:16 am

    Once you have built you kernel from source, running ‘ strings vmlinux | grep “Linux version” ‘ should help you know the built kernel version

  • kernel June 2, 2014, 5:17 pm

    As Chris mentioned in comment 12, I did compile and reboot of my ubuntu OS and with the new kernel, keyboard and mouse are not working. Everything seems to have freeze. is there something else I should do, before I can write a module and test with this kernel?

  • poonjabi June 20, 2014, 2:18 pm

    i am making the kernel when all of a sudden, i lose a testicle and now can’t able to unstall my system. please do the needful. i can’t get on youtube.

  • su_seven June 22, 2014, 2:48 am

    how to configure the Kernel for the ARM board ,just like mini2440

  • Sudhir Baghel July 22, 2014, 10:49 pm

    When running make install, I got following (modinfo could not find) errors,

    10:14:z580:/home/yasho/kernel1/linux-3.10.49#make install
    sh /home/yasho/kernel1/linux-3.10.49/arch/x86/boot/install.sh 3.10.49 arch/x86/boot/bzImage \
    System.map “/boot”
    ERROR: modinfo: could not find module vtsspp
    ERROR: modinfo: could not find module sep3_10
    ERROR: modinfo: could not find module pax
    ERROR: modinfo: could not find module apwr3_1
    ERROR: modinfo: could not find module vmnet
    ERROR: modinfo: could not find module vsock
    ERROR: modinfo: could not find module vmci
    ERROR: modinfo: could not find module vmmon
    ERROR: modinfo: could not find module wl
    ERROR: modinfo: could not find module uvcvideo
    ERROR: modinfo: could not find module videodev
    ERROR: modinfo: could not find module v4l2_compat_ioctl32
    grubby fatal error: unable to find a suitable template

  • Mehrdad February 2, 2015, 5:39 am

    Thanks for your excellent article. But how can I add some commands. I mean exactly two commands:

    I can download the source code of curl, compile and make. But how should I know what files should I copy to the newly compiled kernel and in what places. Because I cannot use the command “make install” so that it installs itself.

    Please guide me to do so


Leave a Comment