How to Compile Linux Kernel from Source to Build Custom Kernel

by Lakshmanan Ganapathy on June 13, 2013

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

# cd /usr/src/

# wget

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
  • – 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

{ 27 comments… read them below or add one }

1 Anthony June 13, 2013 at 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!

2 Deepak June 13, 2013 at 8:36 am

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

3 me June 13, 2013 at 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.

4 Feiticeir0 June 13, 2013 at 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.

5 me June 13, 2013 at 8:57 am

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

6 Jalal Hajigholamali June 13, 2013 at 8:59 am


Thanks a lot,

useful article…

7 Koratsuki June 13, 2013 at 9:25 am

@Deepak: Or use new options/drivers/configs unavailable on older kernels… Nice article :D

8 Bob June 13, 2013 at 10:42 am

Nice article. Thanks

9 John Yost June 13, 2013 at 1:13 pm

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

10 Jim Lee June 13, 2013 at 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.

11 Daniel June 13, 2013 at 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! :D

12 chris June 15, 2013 at 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 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.

13 Ethan June 16, 2013 at 3:07 am

Good to see the concise explaination by Lakshmanan.

14 Chad June 19, 2013 at 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.

15 Anonymous July 1, 2013 at 10:18 am

make bzImage;
make modules && make modules_install

16 Gomathi August 22, 2013 at 5:45 am


17 YektaPardaz October 4, 2013 at 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.

18 cybernard October 7, 2013 at 6:21 am

make localmodconfig

that eliminates all modules not currently loaded in memory.

19 Quamar Niyaz March 12, 2014 at 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 !!!

20 Akshay March 19, 2014 at 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

21 sandeep April 21, 2014 at 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/ line 51: ${output}: ambiguous redirect
make[1]: *** [usr/initramfs_data.cpio] Error 1
make: *** [usr] Error 2
${output} is “”, Can you please help??

22 Suryaprathap April 23, 2014 at 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.

23 Mayur May 17, 2014 at 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

24 kernel June 2, 2014 at 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?

25 poonjabi June 20, 2014 at 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.

26 su_seven June 22, 2014 at 2:48 am

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

27 Sudhir Baghel July 22, 2014 at 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/ 3.10.49 arch/x86/boot/bzImage \ “/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

Leave a Comment

Previous post:

Next post: