Linux Installation Notes

Kernel Builds Under RedHat Linux

To build a new kernel from scratch, do the following steps. In these notes, we'll call the new kernel "2.x.y". You may want to append a revision number to the kernel, if you will have multiple kernels for a particular version, in which case, the new kernel would be "2.x.y-nn". Do everything as root.

  1. Create a new directory in the directory tree /usr/src called "/usr/src/linux-2.x.y".
  2. Unlink the "/usr/src/linux" symlink from wherever it points and link it to the new directory:

    ln -s /usr/src/linux-2.x.y /usr/src/linux

    Much of the build process uses this symlink to find the actual stuff it is working on. Make sure that "/usr/src/linux" is a link to the proper kernel version or the build process will overwrite an existing kernel.
  3. Download the new kernel source, unpack it and untar it. If you untar it while in "/usr/src", tar will put the source tree in "linux" which will cause it to end up in "/usr/src/linux", hence "/usr/src/linux-2.x.y":

    cd /usr/src
    tar -xvf /usr/src/linux-2.x.y/linux-2.x.y.tar
  4. For the rest of the process, you'll want to be in the build source tree:

    cd /usr/src/linux
  5. If you have any patches to apply, now is the time to do them, before you start building the kernel. If you build the kernel first and then apply the patches, chances are good that most of the build will only have to be done over anyway. Typically:

    patch -p1 < abc.2.x.y.nnnn.patch

    Make sure that you have the correct patches for your version of the kernel because there isn't really an undo command. You may want to try a dry run first:

    patch -p1 --dry-run < abc.2.x.y.nnnn.patch

    You may also want to create back-em-up files as the patches are applied so that they can be backed out:

    patch -p1 -b < abc.2.x.y.nnnn.patch
  6. Clean out the source tree of any previously built modules, if you wish (note that this step deletes any file that starts with ".config" so, if you care about such files, make sure you have a copy of them handy):

    make mrproper

    The first time around, you shouldn't need to do this but it couldn't hurt. If you move any modules from the loadable module directory into the kernel or out of the kernel into the module directory, you had better do this step to reset the old module definitions.
  7. If you'd like to get started from an existing kernel, copy ".config" from "/usr/src/linux-orig.kernel.tree" or "/boot" to "/usr/src/linux":

    cp ../linux-orig.kernel.tree/.config .

    At this point, you should make the old configuration. This will prompt you for any new options that were added since the version of the kernel that you copied the configuration from:

    make oldconfig

    You can also run "oldconfig" with no ".config" file present, in which case it will extract all of the kernel options from the currently running kernel and then prompt for any new options.

    If you are just creating a new version of the kernel to add an option or really know what you're doing, you can just hack the ".config" file with a text editor.

  8. Alternately, you can start from scratch by building a new configuration through one of GUI kernel configurators. Run either the X-Windows version of the configurator or the n-curses version:

    make xconfig

    or

    make menuconfig

    If you want text-only configuration, run:

    make config

    This will ask you about each configuration option in sequence.
  9. You may want to diff the original kernel configuration and the one left behind by the configurator. We do this to see if anything too crazy has been selected:

    diff .config /usr/src/linux-orig.kernel.tree/.config
  10. Build the dependency files:

    make dep

    This will ensure that all of the header files and other stuff needed for the build are present.
  11. If you would like to recompile the build from scratch at any time, you can clean out the previously built modules from the source tree:

    make clean

    However, if you move any modules from the loadable module directory into the kernel or out of the kernel into the module directory, you had better start at "make mrproper" (Step 6) to reset the old module definitions. Note that you should pay attention to the part about the ".config" file being deleted by "make mrproper".
  12. If you want a revision number for the kernel, edit the "Makefile" and change the line: "EXTRAVERSION =" to a unique revision number:

    EXTRAVERSION = -nn

    You can add any string that you want, so you can add your initials or anything else you'd like.

    Even if you don't want a unique version, number for your kernel, you should probably hack the Makefile. The standard build is given a suffix of "-nn.n.ncustom" which can screw things up later on down the road. If you don't want a suffix, at least remove the word "custom" from the suffix set in the Makefile. Typically, you would do this if you're just building the kernel itself (no modules) to make a small change that is essentially a direct replacement for your existing kernel.
  13. Build the kernel itself:

    make bzImage

    Note that, if the build of the kernel fails to find "as86", you may need to install the "dev86" RPM (found on one of your system CDs). For example:

    rpm -i ../../dev86-x.y.z-n.i386.rpm
  14. Build all of the modules used by the kernel:

    make modules
  15. Install the modules used by the kernel in the "/lib/modules" tree under this kernel's directory:

    make modules_install

    This will not overwrite any existing kernel modules. It will create a new modules directory for "/lib/modules/linux-2.x.y". You should do this step, even if you didn't build any modules.
  16. Build the module dependency tree (this should be done automatically at boot time but wouldn't you like to know that it actually works). If you asked to keep version numbers on the kernel symbols, be sure you point depmod at the system map for the kernel you've built:

    /sbin/depmod -a 2.x.y -F System.map

    The result is placed in "/lib/modules/2.x.y/modules.dep" and "modules.pcimap".
  17. Copy the new, compressed kernel to the boot directory:

    cp arch/i386/boot/bzImage /boot/vmlinuz-2.x.y

    For the time being, don't link "/boot/vmlinuz" to this new kernel. We'll test it first.
  18. Copy the system map to the boot directory:

    cp System.map /boot/System.map-2.x.y

    Don't link "/boot/System.map" to this new map. That gets done automatically at boot time.
  19. If you have a SCSI adapter and made your SCSI driver modular, build a new initrd image (note that there are few practical reasons to make the SCSI driver modular in a custom kernel). The initrd image is needed for loading your SCSI module at boot time. However, unless you have a specific reason to create an initrd image, do not create one and do not add it to lilo.conf.

    The shell script /sbin/mkinitrd can build a proper initrd image for your machine if the following conditions are met:

    • The loopback block device is available.
    • The "/etc/conf.modules" file has a line for your SCSI adapter; for example:

      alias scsi_hostadapter BusLogic

    Change to "/boot" and make the initial RAM disk with:

    cd /boot
    /sbin/mkinitrd initrd-2.x.y.img 2.a.b

    If the conditions above are not met and you wish to make the initial RAM disk by hand, perhaps using a special disk driver, change to "/boot" and make it with:

    cd /boot
    /sbin/mkinitrd --preload scsi_mod --preload sd_mod --with SpecialDriver
          initrd-2.x.y.img 2.a.b

    Note that "2.a.b" is the kernel whose modules (from "/lib/modules") should be used in the initrd image (not necessarily the same as the version number of the currently running kernel).
  20. Edit "/etc/lilo.conf" to boot the new kernel. Add a new section for the kernel so that it can be tested first, before it is installed for good. To do this, if the existing "lilo.conf" reads:

    image=/boot/vmlinuz-2.2.16-22
         label=linux
         read-only
         root=/dev/hda6

    add:

    image=/boot/vmlinuz-2.x.y
         label=test-2.x.y
         read-only
         root=/dev/hda6

    or, if you built an initrd in the step above, add:

    image=/boot/vmlinuz-2.x.y
         label=test-2.x.y
         initrd=/boot/initrd-2.x.y.img
         read-only
         root=/dev/hda6
  21. Set up lilo to use the new configuration:

    /sbin/lilo -v

    Incidentally, if you recompile the kernel at some point in the future, you should rerun lilo each time you copy a new kernel image into the /boot directory. If you skip this step, sometimes you will get lucky and it will work but sometimes you will get a failure to load the kernel. Its best to just remember to do it always.
  22. When you are happy that all is working well, make the new kernel be the default. Label the new kernel "linux" and label the original kernel something like "RedHat-orig" in "/etc/lilo.conf". For example:

    image=/boot/vmlinuz-2.x.y
         label=linux
         read-only
         root=/dev/hda6

    image=/boot/vmlinuz-2.2.16-22
         label=RedHat-orig
         read-only
         root=/dev/hda6
  23. Rerun lilo to use the new configuration:

    /sbin/lilo -v
  24. It is pretty safe to say that you can ignore the symlinks in "/boot" that point to "kernel.h", "module-info" and "vmlinuz". They don't appear to have any impact on things. Its not even clear what "module-info" does, nor the link to "vmlinuz".