Notes on Red Hat 5.2 kernel installation (See Addendum for RH6.1)
=================================================================

Warning: We (the FreeS/WAN Project http://www.xs4all.nl/~freeswan/)
had nothing to do with designing the kernel installation process.  This
document explains some tricky points that we wish we had been told.
We don't know if these notes apply to systems other than Red Hat 5.2.
This is meant as a supplement to other kernel install guides (such as
the Red Hat 5.2 Installation Guide section 11.6).

Goal: install a new kernel on RH5.2 in such a way that it doesn't
interfere with any other kernels.  This should be repeatable: each new
kernel should have this property.  Each should remain bootable.

Problem: there are several components to a kernel, and each must be
segregated.  How are the parts kept apart?  How are they found?

All the parts live in the file system, so it all comes down to
pathnames.  Well, except for the fiddly bits in /etc/lilo.conf.  What
are the parts?

	/lib/modules/VER/	directory for kernel modules
	/boot/vmlinux-VER	the kernel
	/boot/System.map-VER	the kernel symbol table
	/boot/initrd-VER.img 	the initial ramdisk (for modules needed
				at boot time -- usually not necessary)
	/boot/boot.b		the second-stage loader
	/boot/map		the map file, an index into system index for
				all files used by boot loader (all kernels,
				all initrds, perhaps /boot/boot.b, and itself)

This list does not include /boot/module-info-VER.  That is supplied
by RedHat, and it isn't clear to me how to build it or why.

In each entry, I've used "VER" to signify a version number.  For
RH-supplied kernels, these look like 2.0.36-0.7 (the original 5.2) or
2.0.36-3 (the kernel updates).

There are also symbolic links:
	/lib/modules/preferred	created by /etc/rc.d/rc.sysinit
	/boot/System.map	created by /etc/rc.d/rc.sysinit
	/boot/module-info	created by /etc/rc.d/rc.sysinit
	/vmlinuz		created by ???
I don't know when the /vmlinuz symlink is set up and I don't know
for what it is used.

If you follow the RH procedures, documented in 11.6 of their Installation
Guide, all your VERs will be 2.0.36.  This is very bad: all your builds
will step on each other.  Worse, your new module directory will be half
picked up when you boot a stock RH kernel binary! 

It is important to know how the various parts of the built kernel are
found at booting.

- the kernel path is specified in the image= option in lilo.conf.
  (Lilo.conf may specify several and one is selected at boot time
  by default or user selection.)  The kernel is loaded by the
  boot loader.

- The initial ramdisk is a per-image option (initrd=) specified in
  lilo.conf.  (It isn't described in the RH5.2 lilo.conf(5) manpage!).
  The initial ramdisk is loaded into RAM by the boot loader.

- Since the boot loader doesn't know about the file system, it needs a
  map to figure out which absolute disk blocks to load, and where.
  This is /boot/map.  It is built by the lilo command (also known as
  the map installer).  It will have indices for the all the kernels
  that can be booted, all their initial ram disks, perhaps
  /boot/boot.b, and itself.  This is why moving the blocks of these
  files throws off the boot loader -- lilo must be rerun after even a
  cp command to one of them.

- the modules directory is found two different ways.  Unfortunately,
  they don't mesh properly:

  + at boot time, /etc/rc.d/rc.sysinit tries to figure out the correct
    subdirectory of /lib/modules, using the .rhkmvtag trick (see
    later).  It then builds a symlink /lib/modules/preferred to
    record this.  It also invokes depmod to build the module
    dependency info.  At the same time, it creates the symlinks
    /boot/System.map and /boot/module-info, using the inferred
    value for VER!

  + modprobe and friends stupidly look first in /lib/modules/2.0.36
    (more precisely, /lib/modules/`uname -r`) and then in
    /lib/modules/preferred.  So if there is a /lib/modules/2.0.36 and
    it is the wrong one, you are in trouble.

  If there is no /lib/modules/2.0.36, then both searches above will
  agree (a very Good Thing).  So I recommend strongly that you not
  have a /lib/boot/2.0.36 at boot time.  Unfortunately, you will get
  one during the kernel install process.  Be sure to rename it.  I
  suggest using 2.0.36-x (for some unique x) as VER.

- Red Hat supplied /lib/modules/VER directories contain a hidden file
  .rhkmvtag.  This file contains exactly one line.  This line is
  exactly the same as the contents of /proc/version while the
  corresponding kernel is running.  For the stock kernel, the line is:
Linux version 2.0.36 (root@porky.redhat.com) (gcc version 2.7.2.3) #1 Tue Dec 29 13:11:13 EST 1998

- At boot time, /etc/rc.d/rc.sysinit uses the .rhkmvtag files to
  figure out which of the /lib/modules/* directories matches the
  kernel.  If it could figure out the directory, it uses this
  information to set the symlinks mentioned above.  It then runs
  depmod to build the module dependency information (in
  /lib/modules/preferred/modules.dep, if it created the
  /lib/modules/preferred symlink).  I recommend looking at the code.

- The documented kernel install procedures DO NOT fill in the
  .rhkmvtag file for the new modules directory!  So you should do so
  by hand.  You have to figure out what the contents should be.  Here
  is is a command that will do the job, assuming that
  /usr/src/linux/vmlinux is the kernel associated with
  /lib/modules/2.0.36/:

	strings /usr/src/linux/vmlinux \
	| grep 'x version' >/lib/modules/2.0.36/.rhkmvtag

I've recommended (above) that you use 2.0.36-x for VER when you install
a kernel.  What should x be?  I have found that there is a hidden file
/usr/src/linux/.version which contains a counter that gets incremented
whenever you do a "make install" in the kernel (see target
newversion).  There are some other times that it gets incremented, but
I think that it all works out.  It also gets incorporated into the
resulting kernel's /proc/version, prefixed with ``#''.  This makes it
a natural.

Here is a script to do the recommended renaming:

   # VER will eventually need to be updated
   VER=2.0.36
   VERX=${VER}-`cat /usr/src/linux/.version`

   strings /usr/src/linux/vmlinux | grep 'x version' >/lib/modules/$VER/.rhkmvtag
   mv /lib/modules/$VER /lib/modules/$VERX
   mv /boot/System.map-$VER /boot/System.map-$VERX
   mv /boot/vmlinuz-$VER /boot/vmlinuz-$VERX

And, if an initrd has been built (usually it is best to arrange not to
use one -- see the Red Hat Installation Guide):

   /sbin/mkinitrd /boot/initrd-$VERX.img $VERX

Remember: a new lilo.conf entry is needed for the new kernel, and then
the lilo command will need to be rerun.

Now that kernel installs don't overwrite the results of previous ones,
you will need to manually delete the components and their lilo entry
to get rid of them.

Please send comments, additions, and corrections to:

Hugh Redelmeier
hugh@mimosa.com  voice: +1 416 482-8253


Addendum: Red Hat 6.1
=====================

The kernel supplied with RH6.1 kernel is out of date, so you might
wish to use a newer one.

Much of the description for 5.2 still applies, but the procedure is
quite different because the .version file is no longer used.  Instead,
the top-level Makefile contains a definition EXTRAVERSION which adds a
qualifier to the version for most purposes.  No manual renaming is
required.

Before building the kernel, change EXTRAVERSION by editing
/usr/src/linux/Makefile, and make an appropriate entry in /etc/lilo.conf.

EXTRAVERSION is a feature of the standard kernel sources, not just the
ones supplied by Red Hat.
