Last fiddled: Feb 21, 2003.

Kickstart HOWTO for
Adding Drivers to bootnet.img &
Upgrading the Kernel on bootnet.img
(Boot Floppy Disk Image)




The following HOWTO is based on an example that shows how device drivers can be added to the Kickstart boot floppy disk image "bootnet.img", and how the kernel can be upgraded as well. It shows what I did to get the Kickstart installation working for IBM's xSeries server 345 without using an additional device driver floppy disk.

For IBM's xSeries 345 I had to add the device drivers "e1000" and "ips" to "bootnet.img". At the same time I wanted to use newer driver versions for "e1000" and "ips". This also made it necessary to upgrade the kernel on "bootnet.img" since the device drivers modules are compiled against specific kernel versions. I also had to upgrade the modules in the "stage2.img" image which can be found on Red Hat's installation CD in the directory "RedHat/base". This image is downloaded from the Kickstart server for loading the remaining modules which are required for the OS installation. These modules can only be loaded if they have been compiled against the same kernel version on "bootnet.img".

I tested the following procedure on Red Hat 7.2, 7.3, and Red Hat Advanced Server 2.1.


Links:

Red Hat's Kickstart Installation Guide for Red Hat 7.3
Linux Journal: Hacking Red Hat Kickstart


Procedure for Adding Device Drivers to bootnet.img and for Upgrading the Kernel on bootnet.img:


# Download a newer BOOT kernel version.
# For RH 7.3, the link is:
# ftp://updates.redhat.com/7.3/en/os/i386



# Define the kernel version that was downloaded which should be used on the Boot
# floppy disk.

# For RH 7.2 and 7.3 I used:
export NEW_BOOT_KERNEL_RPM="kernel-BOOT-2.4.18-24.7.x.i386.rpm"
export NEW_BOOT_KERNEL_VERSION="2.4.18-24.7.xBOOT"

# For RH AS 2.1 I used:
export NEW_BOOT_KERNEL_RPM="kernel-BOOT-2.4.9-e.16.i386.rpm"
export NEW_BOOT_KERNEL_VERSION="2.4.9-e.16BOOT"


# Install the BOOT kernel on the system only temporarily.
# Since we are only interested in the BOOT kernel modules, here is a # clean way Make sure to remove this kernel once the images have been created!

rpm -ivh $NEW_BOOT_KERNEL_RPM



# Create a directory where the images should be built.

mkdir /tmp/bootdisk
cd /tmp/bootdisk


# Insert the Red Hat CD disk1 and get the bootnet.img and stage2.img files.

mount /mnt/cdrom

cp
/mnt/cdrom/images/bootnet.img /tmp/bootdisk
cp
/mnt/cdrom/RedHat/base/stage2.img /tmp/bootdisk
umount /mnt/cdrom


# Mount the images


mkdir /tmp/bootdisk/bootnet_image
mkdir /tmp/bootdisk/stage2_image
mkdir /tmp/bootdisk/initrd_image

mount -o loop /tmp/bootdisk/bootnet.img /tmp/bootdisk/bootnet_image
mount -o loop /tmp/bootdisk/stage2.img /tmp/bootdisk/stage2_image


cp /tmp/bootdisk/bootnet_image/initrd.img /tmp/bootdisk/initrd.gz
gunzip /tmp/bootdisk/initrd.gz
mv /tmp/bootdisk/initrd /tmp/bootdisk/initrd.img
mount -o loop /tmp/bootdisk/initrd.img /tmp/bootdisk/initrd_image


# Create a temporary initrd image which will be used to update and to add
# modules.The last command creates a BOOT directory in
# /tmp/bootdisk/initrd_tmp, which contains a list of all current modules
# on the Kickstart boot disk (initrd).


mkdir /tmp/bootdisk/initrd_tmp/
cp -a /tmp/bootdisk/initrd_image/* /tmp/bootdisk/initrd_tmp/
cd /tmp/bootdisk/initrd_tmp
zcat modules/modules.cgz | cpio -ivd


# Since the BOOT kernel will be upgraded, the modules need to be upgraded
# as well.Otherwise the modules can't be loaded if the versions are not
# consistent. At the same time modules can be removed if not needed to
# save space on the floppy disk.
# The following script creates a new BOOT directory in initrd_tmp which
# will contain all new upgraded modules. It first creates a list of modules
# that are currently being installed on the floppy disk. This list is used
# to find newer modules versions to be copied into the new BOOT directory
# in initrd_tmp.


mkdir /tmp/bootdisk/initrd_tmp/$NEW_BOOT_KERNEL_VERSION

cd /tmp/bootdisk/initrd_tmp
OldBootVersion=`zcat modules/modules.cgz | cpio -t |head -1 | awk -F / '{print $1}'`
ModuleList=`ls $OldBootVersion`
cd /lib/modules/$NEW_BOOT_KERNEL_VERSION/kernel
for ModuleName in $ModuleList
do
  NewModuleName=`find . -name $ModuleName`
  echo "cp $NewModuleName /tmp/bootdisk/initrd_tmp/$NEW_BOOT_KERNEL_VERSION/$ModuleName"
  cp $NewModuleName /tmp/bootdisk/initrd_tmp/$NEW_BOOT_KERNEL_VERSION/$ModuleName
done

# For IBM's xSeries servers 345, I added:
# - "e1000.o" for Intel's Gigabit Server Adapter.
# - "ips.o"
for IBM's RAID controller card

cp /lib/modules/$NEW_BOOT_KERNEL_VERSION/kernel/drivers/scsi/ips.o /tmp/bootdisk/initrd_tmp/$NEW_BOOT_KERNEL_VERSION

# For 7.2 and 7.3
cp /lib/modules/$NEW_BOOT_KERNEL_VERSION/kernel/drivers/net/e1000/e1000.o \
/tmp/bootdisk/initrd_tmp/$NEW_BOOT_KERNEL_VERSION


# For 2.1AS I had to use e1000_4412k1 due to licenses issues with
# /lib/modules/$NEW_BOOT_KERNEL_VERSION/kernel/drivers/addon/e1000/e1000.o

cp /lib/modules/$NEW_BOOT_KERNEL_VERSION/kernel/drivers/addon/e1000_4412k1/e1000_4412k1.o \
/tmp/bootdisk/initrd_tmp/$NEW_BOOT_KERNEL_VERSION/e1000.o

# I also added the BROADCOM Corporation|NetXtreme BCM5701 Gigabit Ethernet
cp /lib/modules/$NEW_BOOT_KERNEL_VERSION/kernel/drivers/addon/tg3/tg3_12e3.o \
/tmp/bootdisk/initrd_tmp/$NEW_BOOT_KERNEL_VERSION/tg3_12e3.o

# Once the server comes up you will have to replace the e1000 entries in /etc/modules.conf.
# You can use the following commands, but don't do it on your local server!
# I've put '#' at the beginning of each command to avoid this from happening.

# depmod -ae
# cat /etc/modules.conf | sed 's/ e1000$/ e1000_4412k1/' > /tmp/modules.conf
# mv /tmp/modules.conf /etc/modules.conf
# chmod 644 /etc/modules.conf
# kudzu # this command will detect the network hardware and configure it

# To save space on the floppy disk, I removed modules I don't need:

cd /tmp/bootdisk/initrd_tmp/$NEW_BOOT_KERNEL_VERSION
rm pcnet32.o
rm tulip.o
rm usb-storage.o

# Here is the list of modules I have for 2.1AS:
# e1000.o
# tg3_12e3.o
# eepro100.o
# ips.o
# fat.o
# hid.o
# input.o
# keybdev.o
# lockd.o
# nfs.o
# scsi_mod.o
# sunrpc.o
# vfat.o


# Create a new compressed module.cgz file which contains all the updated and
# added modules.


cd /tmp/bootdisk/initrd_tmp/
find $NEW_BOOT_KERNEL_VERSION | cpio -ov -H crc | gzip -c9 > \
/tmp/bootdisk/initrd_tmp/modules/modules.cgz

cd /tmp/bootdisk
rm -rf /tmp/bootdisk/initrd_tmp/*BOOT


#
Defines dependencies for added modules in
# initrd: modules/modules.dep (/tmp/bootdisk/initrd_tmp/modules/modules.dep)
# I added the following dependencies to
#
/tmp/bootdisk/initrd_tmp/modules/modules.dep :

echo "ips: scsi_mod" >>
/tmp/bootdisk/initrd_tmp/modules/modules.dep



# Make entries for the added device drivers in
# initrd: modules/module-info  (/tmp/bootdisk/initrd_tmp/modules/module-info)
# I added entries for e1000 and ips. I looked up these entries in the stage2
# image /tmp/bootdisk/stage2_image/modules/module-info.
# Make sure to use tabs!


/tmp/bootdisk/initrd_tmp/modules/module-info :
e1000
        eth
        "Intel EtherExpress/1000 gigabit"
tg3_12e3
        eth
        "BROADCOM NetXtreme BCM5701 Gigabit Ethernet"
ips
        scsi
        "IBM ServeRAID"
# Make sure to replace spaces with tabs.



# Make entries for the added device drivers in
# initrd: modules/pcitable (/tmp/bootdisk/initrd_tmp/modules/pcitable)
# This will make sure the kernel finds the appropriate driver for deviceID's.
# I copied the pcitable entries for e1000 and ips from the stage2 image.
# Make sure to use TABS and not spaces when you add entries manually!

cp /tmp/bootdisk/initrd_image/modules/pcitable /tmp/bootdisk/pcitable
grep "\"e1000\"" /tmp/bootdisk/stage2_image/modules/pcitable >> /tmp/bootdisk/pcitable
grep "\"ips\"" /tmp/bootdisk/stage2_image/modules/pcitable >> /tmp/bootdisk/pcitable
grep "\"tg\"" /tmp/bootdisk/stage2_image/modules/pcitable >> /tmp/bootdisk/pcitable
# Make sure to use TABS and not spaces when you add entries manually!


# I also had to make one additional entry for the e1000 module. The Gigabit
# Server Adapter 82546EB that comes with IBM's xSeries server 345 has the
# deviceId: 0x1014. This particular device ID is not listed in the stage2 image.
# The same applies to the NetXtreme BCM5701 Gigabit Ethernet adapter.

# You can find this number in /etc/sysconfig/hwconf on an installed server.
# So I added a line for deviceId 0x1014, otherwise the e1000 modules wouldn't
# load. Make sure to use TABS!


echo '0x8086    0x1010  "e1000" "Intel Corp.|82546EB Gigabit Ethernet Controller"' >> \
/tmp/bootdisk/pcitable

echo '0x14e4 0x16a7 "tg3_12e3" "BROADCOM Corporation|NetXtreme BCM5701 Gigabit Ethernet"' >> \
/tmp/bootdisk/pcitable
# Make sure to replace spaces with TABS!


# Sort the pcitable file and write it to your copied initrd image:
sort /tmp/bootdisk/pcitable > /tmp/bootdisk/initrd_tmp/modules/pcitable


# Create a new initrd image from scratch.
# If we don't leave enough free space on the initrd image, then it won't
# be able to load e.g. modules (+1000k free space worked for me so far).
# Remember that this is the filesystem space that will be available once
# initrd has been uncompressed during the boot process. I'm doing this to save
# some space when the image gets compressed for the floppy image. But keep in
# mind though that you won't save much space for the floppy image since empty
# space doesn't constitute to much space after it has been compressed. However,
# if you run out of space just because of 5000 bytes like I did, then this
# might help you.


INITRD_SIZE=`du -k -s /tmp/bootdisk/initrd_tmp | awk '{print $1}'`
let "NEW_INITRD_SIZE=$INITRD_SIZE + 1000"

mkdir /tmp/bootdisk/initrd_new_image
dd if=/dev/zero bs=1k count=$NEW_INITRD_SIZE of=/tmp/bootdisk/initrd_new.img
echo "y" | mke2fs /tmp/bootdisk/initrd_new.img > /dev/null
mount -o loop /tmp/bootdisk/initrd_new.img /tmp/bootdisk/initrd_new_image
cp -a /tmp/bootdisk/initrd_tmp/* /tmp/bootdisk/initrd_new_image/

sync  # I'm not sure if this is really needed.
umount /tmp/bootdisk/initrd_new_image
umount /tmp/bootdisk/initrd_image



# Copy the compressed initrd image and the newer kernel version to the bootnet
# image. If you don't have enough space left in /tmp/bootdisk/bootnet_image,
# then you need to check which module you can remove.


gzip -9 /tmp/bootdisk/initrd_new.img
cp /tmp/bootdisk/initrd_new.img.gz /tmp/bootdisk/bootnet_image/initrd.img
cp /boot/vmlinuz-$NEW_BOOT_KERNEL_VERSION /tmp/bootdisk/bootnet_image/vmlinuz


# Copy your kickstart configuration file to the new image and unmount the image.
# For information on how to create a kickstart configuration file, see
# http://www.redhat.com/docs/manuals/linux/RHL-7.3-Manual/custom-guide/ch-kickstart2.html

cp /your_ks_cfg_dir/ks.cfg /tmp/bootdisk/bootnet_image/ks.cfg
sync  #
I'm not sure if this is really needed.
umount /tmp/bootdisk/bootnet_image


# Copy the new Kickstart boot floppy disk image to the floppy disk.

dd if=/tmp/bootdisk/bootnet.img of=/dev/fd0



# Updating stage2.img

# Update the modules in the stage2 image to be consistent with the new boot
# kernel on the floppy disk. The stage2 image needs to be replaced in the
# directory /your_kickstart_directory/RedHat/base/ on the Kickstart server.
# This image is used during the OS installation to load additional modules
# like ext2, jbd, raid, etc.
# The last command creates a BOOT directory in /tmp/bootdisk/stage2_new,
# which contains a list of all current modules in the stage2 image.

cp -a /tmp/bootdisk/stage2_image /tmp/bootdisk/stage2_new
umount /tmp/bootdisk/stage2_image

cd /tmp/bootdisk/stage2_new
zcat /tmp/bootdisk/stage2_new/modules/modules.cgz | cpio -ivd


# Replace all modules.
# This script works similar to the script I used for replacing the modules
# on the bootnet image.

mkdir /tmp/bootdisk/stage2_new/$NEW_BOOT_KERNEL_VERSION
cd /tmp/bootdisk/stage2_new
OldBootVersion=`zcat modules/modules.cgz | cpio -t |head -1 | awk -F / '{print $1}'`
ModuleList=`ls $OldBootVersion`
cd /lib/modules/$NEW_BOOT_KERNEL_VERSION/kernel
for ModuleName in $ModuleList
do
  NewModuleName=`find . -name $ModuleName`
  echo "cp $NewModuleName /tmp/bootdisk/stage2_new/$NEW_BOOT_KERNEL_VERSION/$ModuleName"
  cp $NewModuleName /tmp/bootdisk/stage2_new/$NEW_BOOT_KERNEL_VERSION/$ModuleName
done
cd /tmp/bootdisk/stage2_new


# Create a new compressed module.cgz file which contains all the updated modules.

find $NEW_BOOT_KERNEL_VERSION | cpio -ov -H crc | gzip -c9 > \
/tmp/bootdisk/stage2_new/modules/modules.cgz


cd /tmp/bootdisk/
rm -rf stage2_new/$OldBootVersion
rm -rf stage2_new/$NEW_BOOT_KERNEL_VERSION


# Create a new stage2 image

mkcramfs stage2_new stage2_new.img


# Save the old stage2.img image on your kickstart server and copy the new
# stage2_new.img file to KickstartServer:/
your_kickstart_directory/RedHat/base/stage2.img

mv
<KickstartServer>:/<your_kickstart_directory>/RedHat/base/stage2.img \
<KickstartServer>:/<your_kickstart_directory>/RedHat/base/stage2.img.orig

cp stage2_new.img <KickstartServer>:/<disk_directory>/RedHat/base/stage2.img



# Remove the boot kernel from the system!

rpm -e <boot_kernel>



Copyright © 2003 PUSCHITZ.COM

The information provided in this article is distributed AS IS. Every effort has been made to provide the information as accurate as possible, but no warranty or fitness is implied. The use of this information described herein is your responsibility, and to use it in your own environments do so at your own risk.


Comments?  webmaster_at_puschitz.com