This is actually a very old writing. I wrote this back on 2007 in my old blog (which is now deleted). I was building my own Linux From Scratch and needed to compile the kernel as part of that. Later during our OS course we were given an assignment to add a system call in Linux kernel and as a result compiling the kernel was needed. Some of my friends were having trouble with the process. It was not a straight forward task, given the fact that most were unfamiliar with Linux itself. So I decided to write this. I know that now this may not even work for the latest kernel. Still I am keeping this here … just as a sweet memory. Building a Linux From Scratch is something that personally I consider “crazy”.
Frankly speaking, compiling Linux kernel may vary from architecture to architecture and from kernel version to version. Here is one way that you can build on i386.
- Download the latest stable kernel from kernel.org. I’m using 188.8.131.52 as an example. 184.108.40.206 can be downloaded from here.
- Extract that.
$ tar xfj linux-220.127.116.11.tar.bz2
- Move to the source directory.
$ cd linux-18.104.22.168
- Remove any *.o files from source tree. It is recommended to do this before every compilation, even when the files are just extracted.
$ make mrproper
- Configure the kernel.
$ make menuconfig
Well, this is a long process. You can do lots of things. You can optimize for specific processor, for desktop or server, build the kernel with debugging symbols, even you can add your name with kernel version :-). Explore the options as much as possible.
- Compile the kernel.
- If you have configured some parts of the kernel as loadable module (you should do that), install those modules.
# make modules_install
Modules are installed in
/lib/modules. Here is a caution: if you are building the same version as your running version (or any existing version), modules will be overwritten and you may damage your running system. So be careful before doing this. It’s better to append a custom string after kernel release (local version) during configuring.
arch/i386/boot/bzImageis the built kernel image. Copy that to your boot partition.
# cp arch/i386/boot/bzImage /boot/bzImage-22.214.171.124
- Copy the symbol map file.
# cp System.map /boot/System.map-126.96.36.199
- Your configuration is stored in
.configfile. Save that for future reference.
# cp .config /boot/config-188.8.131.52
- Create an initial ram disk for your kernel.
# mkinitrd /boot/initrd-184.108.40.206 220.127.116.11
- Modify your boot loader’s configuration file. Most of the distros use grub now.
/boot/grub/menu.lstis the grub configuration file. Modify whichever is present in your distro. On some distros both are present and one is a link to another. In that case you can work with anyone, no doubt. Add the following lines:
kernel /bzImage-18.104.22.168 ro root=LABEL=/1 rhgb quiet
What’s the meaning of all these? First line is the title which will be shown in the menu during boot time. Second line means that my boot partition is
hd0means primary master (
hda) and 7 means
hda8. (Yes, grub starts from zero). Third line shows the path of kernel image.
ro root=LABEL=/1 rhgb quietare the booting options.
LABELis specified in my
/etc/fstabfile. Fourth line is the path of initial ram disk. Both kernel and initrd paths are relative to the partition which is specified in the second line. In my system it is
Obviously these will vary from system to system. Now here is a big question: what will happen if you don’t know what is your boot partition, what is your root partition, what lies in
/etc/fstaband what are the options to the kernel?? You will get all these information from grub configuration file. How? Just see the entry of your existing running kernel :-).
And finally, if you see a panic something like “policy checking”, add
enforcing=0in the kernel option list.
- Now reboot and enjoy 🙂
Special Thanks to:
- Sayeed Hyder Sir, who was our OS course teacher and tried lots of interesting things.
- Linux from scratch project. Here is their kernel building page.