Tuesday, February 1, 2011

How To Build Linux Kernel

Here we compile kernel source to generate a new kernel image and this new image is used at the next boot of the system.
(Mainline kernel is called as vanilla kernel)
Note: I am assuming that you, as a root user in source directory, at /usr/lib/linux-2.6.32 (linux-2.6.32 name of the kernel source directory that we obtained after unzipping). It’s a convention to place the unzipped source directory at /usr/lib but it can be any where, but to build you have to be in the source directory.

Step1: Assign kernel version tag.
To do so open the Makefile in the source directory at the path /usr/lib/linux-2.6.32/Makefile and at the top of the file you will find the field EXTRAVERSION, edit as follows

$ Vim Makefile

Modify: EXTRAVERSION = .firstbuild
*save the above changes to file.

Step2: Choose kernel configuration.

To do so type that following command. This will generate a configuration file “.config”. Any file that starts with “.” is a hidden file, to list the hidden files use option 'a' with 'ls' command.
$ make menuconfig (this pumps kernel info onto console, wait until prompt returns)

Because the Linux source code is available, it follows that you can configure and custom tailor it before compiling. Indeed, it is possible to compile support into your kernel for only the specific features and drivers you want. Configuring the kernel is a required step before building it. Kernel provides multiple tools to facilitate configuration. The simplest tool is a text-based command-line utility.
$ make config

This utility goes through each option, one by one, and asks the user to interactively select yes, no, or (for tristates) module. Because this takes a long time, unless you are paid by the hour, you should use an ncurses-based graphical utility.
$ make menuconfig

To make very simple use oldconfig option.
$ make oldconfig
Ultimately they generate .config file.
Note: refer to man pages on make, type “make help” at your terminal.

Step3: Compile the source to create kernel image (raw) and modules.
$ make
This takes around 30 min on a normal desktop, to speed up, create threads if yours is a multicore machine. To build the kernel with multiple makes jobs, use
$ make -jn
Here, n is the number of jobs to spawn. Usual practice is to spawn one or two jobs per processor.

Step4: Install the modules on file system.
To do so type the following command.
$ make modules_install
This copies the modules into disk space and adds folder at /lib/modules/[name].
Here name will be 2.6.32.firstbuild

As an example, on an x86 system using grub, you would copy arch/i386/boot/bzImage
to /boot, name it something like vmlinuz-version

$ cp arch/x86/boot/bzImage /boot/vmlinuz-2.6.32.firstbuild


The build process also creates the file System.map in the root of the kernel source tree. It contains a symbol lookup table, mapping kernel symbols to their start addresses. copy System.map to /boot, name it something like System.map-version

$cp System.map /boot/System.map-2.6.32.firstbuild

$mkinitramfs –o /boot/initrd.img-2.6.32.firstbuild  2.6.32.firstbuild
here 2.6.32.firstbuild is the name of folder that was automatically created at /lib/modules

Step7: Update Grub

$ update-grub

If you open the file grub.cfg at the path /boot/grub/grub.cfg the ###BEGIN/etc/grub.d/10_linux ### segment should look like this
$ gedit /boot/grub/grub.cfg

### BEGIN /etc/grub.d/10_linux ###
menuentry 'Ubuntu, with Linux 2.6.32.firstbuild' --class ubuntu --class gnu-linux --class gnu --class os {
insmod ext2
set root='(hd0,1)'
search --no-floppy --fs-uuid --set f57b34e4-1bf6-4135-993f-3db8881340d0
linux /boot/vmlinuz-2.6.32.firstbuild root=UUID=f57b34e4-1bf6-4135-993f-3db8881340d0 ro quiet splash
initrd /boot/initrd.img-2.6.32.firstbuild

menuentry 'Ubuntu, with Linux 2.6.32.firstbuild (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os {
insmod ext2
set root='(hd0,1)'
search --no-floppy --fs-uuid --set f57b34e4-1bf6-4135-993f-3db8881340d0
echo 'Loading Linux 2.6.32.firstbuild ...'
linux /boot/vmlinuz-2.6.32.firstbuild root=UUID=f57b34e4-1bf6-4135-993f-3db8881340d0 ro single
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-2.6.32.firstbuild

Note1: In "/boot/grub/grub.cfg" you will find fields like "timeout = -1" Change it to "timeout = 10", so that even if your new image crashes you have chance to select the generic image in the next Restart.
Note2: If the ###BEGIN/etc/grub.d/10_linux ### segment doesn’t start with your new image then you manually cut and paste the above two blocks of code from this segment and paste it below ###BEGIN as very first line.
Restart your system.

Note3: Make sure that while executing Step4 all the modules are copied, if this process stops with few modules copied, like less than a count of 10, then its clear that build was not complete, this can be a reason that you were not as root user while building the kernel and even if the error still persists, chmod 777 kernel-source/* directory. and start all the above steps.

Note4: If you encounter kernel-panic after you restart with grub updated with new kernel configuration then above Note3 can be a solution or else the source is not downloaded completely.

The above process can be simple given as :

First you should be the root user and then go to source folder and then edit the Makefile “EXTRAVERSION” filed in source directory to “.firstbuild”, and execute these commands in sequence. Make sure that you are in root.
$ make oldconfig
$ make
$ make modules_install
$ cp arch/x86/boot/bzImage /boot/vmlinuz-2.6.32.firstbuild
$ cp System.map /boot/System.map-2.6.32.firstbuild
$ mkinitramfs –o /boot/initrd.img-2.6.32.firstbuild 2.6.32.firstbuild
$ update-grub

1 comment: