SPY HILL Research
Spy-Hill.net

Poughkeepsie, New York [DIR] [UP]

Linux Kernel Build Checklist


Building a new Linux kernel from the source code can be scary the first time you do it, but it is now a fairly straightforward process. This is a brief description of the steps required to build a custom kernel.
Last updated: 21 February 2016

Listed below are the steps required to build a new Linux kernel, with some discussion about the tricky parts. But first, some preperatory points:

Before you start, you need to have enough disk storage in which to unpack the source code and build the full kernel. For a recent version of the kernel, 2.6.17, I found that 1GB was not enough room, unless I trimmed the configuration down a lot (I had started with a Fedora configuration, which builds a lot of modules.) So you'll need more space than that. You can have the space back when you are done -- only the final product (the kernel and modules) needs to be installed on the system, and they are a lot smaller than 1GB.

Use the newest stable version of the kernel. If you are willing to go through all the bother of building a new kernel then you should use the newest stable version, unless there is a good reason for using something else. (Being too lazy to download the latest revision is not a good reason.) You can always get the latest version of the kernel from http://www.kernel.org

The version number of the kernel you are building is used in many places in what follows. I have labeled it "2.6.XX.rr-vv" but you should replace this with the version of the kernel you are building. You can modify the "-vv" part yourself (see below).

You should build the kernel as a normal Unix user, but you will have to be root on install the kernel and modules, and to edit the boot loader configuration.

  1. Unpack the kernel source. The traditional place is in /usr/src but some other working directory is fine too, and you should not be using /usr for this anyway. I have used /usr/local/src/kernel. Unpacking the tarball will create a directory called "linux-2.6.XX". You can then create soft links to this named "linux-2.6" and "linux", and a link called /usr/src/linux as well. If you later have to build a third-party module (such as for a graphics card) it will likely use that last lilnk to find the proper kernel headers.

  2. If you are copying a configuration file from a previous kernel build then put the configuration file in place as /usr/src/linux/.config. A good strategy for building a custom kernel is to start with a general configuration that works and then tweak it. Fedora (and probably Red Hat) now include a configuration file with the RPM installation of a kernel. Look in the directory /boot for a file with a name like config-2.6.XX.rr-vv. Just be aware that to be compatible with a wide range of hardware configurations they turn on module building for just about everything, so you will likely want to turn things off as you go through the configuration.

  3. You can add a "-vv" part to the kernel version as a part of selecting kernel options (the next step). Whatever you enter as the "Local version" under "General setup" will be appended to the end of the version string 2.6.XX.rr. Remember a dash or underscore if you want a separator. You might want to add "smp" at the end of the kernel name if it is an SMP (symmetric multi-procsessor) kernel.

    In the past you had to edit the Makefile to change the version string. If you wish to do anything other than adding a Local version "-vv" you can do so by editing the Makfile now.

  4. Select the kernel options you want/need by saying:
    make xconfig
    (or make menuconfig if you are not using X11, or make config if you are feeling old-fashioned). This may take some time, but it's worth the effort to get a custom kernel. Don't forget to include drivers for hardware specific to your system. The help notes can actually be a help. Keep in mind that sound often only works if loaded as a module.

    You must run one of these configuration tools even if you are just copying a configuration file from a previous kernel. If you don't want to make any changes then just run the tool and then immediately save the configuration, but you must run the tool.

  5. You no longer need to say `make dep`, but if you want to start afresh then say
    make clean
    to clean up from a previous build. To completely start over from scratch you can say `make mrproper`.

  6. Compile both the kernel and the modules by saying
    make

    In the past you had to make the kernel by saying `make bzImage` and then the modules by saying `make modules`. That still works, but now the default is to just do both.

    Then, assuming that this completes with no problems [1]...

  7. Install the modules with:
    make modules_install
    This puts the modules in /lib/modules/4.4.XX.rr-vv (after erasing what is already there!) You must be root to do this.

  8. Copy the compressed kernel to /boot with:
    cp arch/x86_64/boot/bzImage /boot/vmlinuz-4.4.XX.rr-vv
    You must be root to do this. Make sure the name matches the name used in /lib/modules.

  9. Build any other modules not included with the kernel source package and install them. This could include:
    • OpenAFS
    • video drivers
    • ethernet drivers
    • modem/linmodem drivers
    These modules should be installed in the appropriate subdirectory of /lib/modules/4.4.XX.rr-vv.

    You always have to do this after `make modules_install` because that cleans out the modules directory.[2] You can do this after you reboot to the new kernel, but then don't forget to repeat the steps below after you have added new modules.

  10. Create a dependency file for the modules with
    depmod -a 4.4.XX.rr-vv
    This creates the file /lib/modules/4.4.XX.rr-vv/modules.dep

  11. Put the system map file in /boot. From the top of the source directory (where you said 'make') say
    cp System.map /boot/System.map-4.4.XX.rr-vv

    If you are booting to multiple kernels then you want to have the version number in each file name and simply remove /boot/System.map from /boot. It will then be recreated as a link to the correct version at boot time.

  12. It can be useful to save the configuration file you used to build this kernel as
    cp .config /boot/config-4.4.XX.rr-vv
    (A new kernel build option also allows you to save the configuration options inside the kernel itself. That is separate from this.)

  13. Make an initial RAM disk with the commands:
    cd /boot
    mkinitrd initrd-4.4.XX.rr-vv.img 4.4.XX.rr-vv
    (If one already exists you will need the -f flag to force an overwrite.)

    If you have any missing modules you may have to go back and rebuild the modules and kernel at this point to correct this.

  14. Update your boot loader to boot the new kernel. It is a good idea to keep previous stable kernels around for a while until you have verified that the new one really works -- test it for a while before cleaning out the old ones.

    It is best to make the new kernel an option but not the default, at least until it has been tested. How you do this depends on which boot loader you are using:

    GRUB2:
    With Grub version 2 you no longer need to edit the configuration file manually. Instead you simply give the command
        grub2-mkconfig -o /boot/grub2/grub.cfg
    and it will assemble a new grub.cfg file which includes all of the bootable kernels from /boot. You might want to back up your previous grub.cfg file first, or write the new one somewhere else and inspect it before you drop it into place. To change parameters and defaults in the new configuration file, edit the file /etc/default/grub
    GRUB:
    Edit the file /boot/grub/grub.conf to add your new kernel. It is easiest to emulate the already existing entries. Again, don't make it the default kernel until you have tested it. You do not have to run any kind of command to update the boot loader, since GRUB will find the list in this file at boot time.
    LILO:
    Edit the file /etc/lilo.conf to add your new kernel. Give the new one an alias of "test" or similar until you are really sure that it works. The appropriate line to add to this file is simply
        alias=test

    Then write LILO to the MBR with the command:

        lilo

  15. Reboot and select the test kernel and try it out.[3]

  16. If you have to build certain drivers with the running kernel (eg. nVidia driver) then build it now and then repeat the depmod and mkinitrd steps above.

  17. When the kernel works well enough, make it the default kernel by editing /boot/grub/grub.conf or /etc/lilo.conf as appropriate. Keep at least one older working kernel around too, just in case there are problems later on.

  18. Once you are sure the kernel is stable, make a new emergency boot disk with:
    mkbootdisk 4.4.XX.rr-vv
    (This will likely fail on Linux 2.6 -- it's just too big for a floppy. )

    In an emergency, if you cannot boot your system, you can use the rescue CD from the Fedora Core distribution, or a Knoppix CD, to boot to Linux and repair your installation.

Once you are satisfied that the new kernel works in all ways necessary, you can delete older versions of the kernel. To do so, (1) remove the entry from the boot loader configuration file (either /boot/grub/grub.conf or /etc/lilo.conf, (2) remove the kernel (vmlinuz-... from /boot, and (3) remove the modules subdirectory from /lib/modules.


Notes

[1] If building the modules fails with an error that says something like "nondigits in number and not hexadecimal", then you might be able to recover by saying `make mrproper`, which will erase everything so that you must start over completely. Or, on a Red Hat Linux system, you can try editing the file include/linux/modversions.h to add a line reading
#include <linux/rhconfig.h>
at the appropriate place. Details
here.

[2] If you find you are rebulding the kernel often as you tweak the settings then you can build the add-on modules once and then save them in a way that you can easily put them back in place after all the standard modules have been installed. For example, I saved the nvidia.o module for my graphics card by saying

cd /lib/modules
tar cf nvidia.tar ./2.4.25/kernel/drivers/video/nvidia.o
Then after another round of building the kernel and modules I could easily restore the nVidia module with:
tar xf nvidia.tar
The installation procedure for the nVidia drivers has improved, but unfortunately they delete all copies for other kernels when you install a driver for the current kernel, so you should save a copy this way for every working kernel you have.

[3] If you don't have a working video driver yet then you can boot temporarily to run level 3 by saying linux single at the boot: prompt, and then when you get a shell give the command telinit 3. Or, as always, edit /etc/inittab to make run level 3 the default, then change it to run level 5 when the video is working.


  Copyright © 2016 by Spy Hill Research https://www.spy-hill.net/~myers/linux/kernel-build.html (served by Islay.spy-hill.com) Last modified: 21 February 2016