How to Modify Red Hat Boot Disks and Driver Disks

I don’t have time to fix the documentation that follows, so here’s a short rendition from memory of how you go about merging drivers from drvnet.img into boot.img. Again, this is from memory, so just use your best judgement. I will accept any corrections to it.

# Let’s make a working directory for us

mkdir /tmp/workspace

# Now let’s grab the bits we wish to merge with boot.img

cd /tmp/workspace
cp -a /mnt/cdrom/images/drvnet.img .
mkdir drvnet.img.dir
mount drvnet.img drvnet.img.dir -o loop,ro
mkdir stufftoadd
cd drvnet.img.dir
cp -a modules.cgz pcitable modinfo modules.dep ../stufftoadd
(Note that modinfo might be listed with some other name mod-info or
cd ../stufftoadd
mkdir modules
cd modules
zcat ../modules.cgz | cpio -idvm
umount drvnet.img.dir
rmdir drvnet.img.dir
rm drvnet.img

# Now let’s start working with boot.img

cd /tmp/workspace
cp -a /mnt/cdrom/images/boot.img .
mkdir boot.img.dir
mount boot.img boot.img.dir -o loop,rw
cp -a boot.img.dir/initrd.img .
mv initrd.img initrd.img.gz
gunzip initrd.img.gz
mkdir initrd.img.dir
mount initrd.img initrd.img.dir -o loop,rw
mkdir modifiedstuff
cd initrd.img.dir/modules
cp -a modules.cgz pcitable modinfo modules.dep ../../modifiedstuff
(Note that modinfo might be listed with some other name mod-info or
cd /tmp/workspace/modifiedstuff
mkdir modules
cd modules
zcat ../modules.cgz | cpio -idvm
cd /tmp/workspace

Now select your drivers from /tmp/workspace/stufftoadd/modules and add them to /tmp/workspace/modifiedstuff/modules.
When ready to repack modules.cgz, then use:

cd /tmp/workspace/modifiedstuff/modules
find . -type f | cpio -o -H crc | gzip -n9 >../modules.cgz

Also edit the other 3 files in /tmp/workspace/modifiedstuff: pcitable, mod-info, and modules.dep.

pcitable is responsible for autoloading of the drivers
Please don’t allow duplicate lines for any given “vendor id” and “device id” combination.
Some devices have more than one driver so choose only 1 driver.

mod-info provides text information to the user during installation about a given driver.

modules.dep, if your driver requires other modules to be loaded first then this file will cause them to load.

Once you have modified these 4 files to your satisfaction (modules.cgz, modules.dep, modinfo, pcitable) then compare the sizes with those in /tmp/workspace/initrd.img.dir/modules/. When working with these floppy images space is very tight. You may be able to get these 4 files into initrd.img; however, the initrd.img may not fit back on boot.img. Remember to make space in modules.cgz by deleting out drivers you know that you will not be using. I usually try remove the same amount that I add. Of course you don’t need to worry with space if you’re doing a pxe install.

After you are happy with the sizes then lets repack (stop if you get an error, fix it, then proceed):

cd /tmp/workspace/modifiedstuff
cp -a modules.cgz pcitable modules.dep modinfo /tmp/initrd.img.dir/modules
(Note that modinfo might be listed with some other name mod-info or
dd if=/dev/zero of=/tmp/initrd.img.dir/zero >/dev/null 2>&1
rm /tmp/initrd.img.dir/zero
cd /tmp/workspace
umount initrd.img.dir
rmdir initrd.img.dir
gzip -n9 initrd.img
mv initrd.img.gz initrd.img
mv initrd.img boot.img.dir
umount boot.img.dir
rmdir boot.img.dir

If no errors then your boot.img should now be populated with the drivers you put in.

The following is in a bit of a mess so don’t rely on the following too much for detailed instructions. Basically the only thing messed up is which directories I say I’m working with. So the content is good, just don’t create a script out of it line for line.

  1. Set up a workplace
    mkdir /tmp/unpack
    cd /tmp/unpack
  3. Grab something to work with
    cp /mnt/cdrom/images/boot.img .
  5. Dig into the disk (any of boot.img, bootnet.img,, etc…)
    mkdir disk.dir
    mount boot.img disk.dir -o loop
  7. Grab a copy of the initrd and uncompress it
    cp disk.dir/initrd.img initrd.img.gz
    gunzip initrd.img.gz
  9. Dig into the initrd
    mkdir initrd.dir
    mount initrd.img initrd.dir -o loop
  11. What is important in the initrd
  12. Initrd calls /linuxrc which then loads drivers from the modules.cgz file which resides in the /modules directory (in the same initrd file). If all you are doing is adding in modules for different hardware into one of the default Red Hat boot disks, then you only need to modify the files that exist in the /modules directory. Files of interest in the /modules directory are module-info, modules.dep, pcitable, and modules.cgz.

  13. Dig into the modules.cgz file
    mkdir /tmp/unpack/modules
    cd /tmp/unpack/modules
    zcat /tmp/unpack/initrd.dir/modules/modules.cgz | cpio -idvm
    mkdir /tmp/unpack/work
    cd /tmp/unpack/initrd.dir/modules
    cp -a * /tmp/unpack/work
    cd /tmp/unpack
  15. Modifying modules.cgz
  • Add and subtract modules to and from modules.cgz as necessary.
  • You may grab modules from one of the other boot disks available (boot.img, bootnet.img, drivers.img, drvblock.img, drvnet.img, etc).
  • Remember to keep track of how much space you are using inside modules.cgz, or your initrd may not fit back on the boot disk.
  • If the module you need is not present on one of these disk images then you will need to build the module. Building the module is easy
    • Use my kernel page (Compiling linux kernel) as a guide. Here is a summary:
      cd /usr/src/linux-2.4.7-10
      make mrproper
      make clean
      cp configs/kernel-source-2.4.7-i386-BOOT.config .config

      Use the kernel-source-2.4.x-i386-BOOT.config as a starting guideline.

      vi Makefile

      Change the extraversion line to read -10BOOT for RH72 (RH72 uses a 2.4.7-10 kernel)

      make xconfig

      Use “make xconfig” to make sure that your driver is turned on as a module, then save and exit.

      make dep modules modules_install

      You should end up with the 2.4.7-10BOOT modules residing in /lib/modules/2.4.7-10BOOT. If you get any errors don’t worry, just check if your module has been created yet or not

      find . -name sim710

      If you have a “.o” file for your driver, then you’re done. Take that .o file with you back to your /tmp/unpack/modules/2.4.7-10BOOT directory.

  • Modifying module-info
    • (Step 7 copied the “to be modified” copy of this into /tmp/unpack/work)
    • Follow the same format that exists in module-info
    • First see if there is an existing entry you can copy over from where you are getting the driver (such as from a different boot disk or from one of the drivers disks)
    • Second, see if you have an entry in your systems /boot/module-info that you can use
    • Otherwise create your own multi-line entry, such as:

    "Symbios 53C896"

  • Modifying modules.dep
    • (Step 7 copied the “to be modified” copy of this into /tmp/unpack/work)
    • Look in modules.dep (or dep-info) to see if your module depends on other modules. If your module isn’t listed in modules.dep (or if modules.dep is empty) then your module has no dependancies.
    • Follow the existing format in the file.
    • First, try to get a copy from where you got the driver (such as a boot disk or drivers disk).
    • Second, if you made your own driver then check in your systems /lib/modules/2.4.7-10/modules.dep. Please note that you should convert the format if you use information from your systems modules.dep – specifically your system will have a full path listed, please strip off this full path and only leave the drivername – further please remove all “.o” extensions.
    usb-storage: usbcore scsi_mod
    usb-ohci: usbcore
    usb-uhci: usbcore
    vfat: fat
  • Modifying pcitable
  • Automatic loading of drivers is provided by pcitable. You will need a pcitable if you want kickstart to be fully automatic. If you don’t use “pcitable” then the driver will not automatically load and you will have to pick it from a list of drivers.
    This file is a tab separated list of vendor id, device id, driver module, and description.
    A vendor id mearly identifies the vendor. For example 0x8086 represents Intel and 0x0e11 represents Compaq.
    A vendor id and device id pair represents a specific pci device that a manufacturer makes.
    A device id identifies a particular device that a manufacturer makes. A device id is useless without the corresponding vendor id.
    A pci device should have only 1 entry in pcitable. There should not be multiple lines for a given pci device (vendor id and device id pair).
    Sometimes there are two or more drivers that will work for a particular pci device (vendor id and device id). For example certain network cards are supported by both tg3 and bcm5700.

    After adding in more lines to this file, remember to delete out any duplicate lines. Sort may help you out here. Uniq will probably not help, especially if you have 2 entries with different drivers for a single device.

    You can get a copy of pcitable from many places. Usually the best place is where you copied the driver from.

    You can also maintain a “master” pcitable which you keep up to date with all new hardware entries you require. This one “master” pcitable should work for most all versions of Red Hat Linux (and Fedora) versions that support pcitable. Basically try grabbing the latest pcitable available you can find.

    If pcitable isn’t working for you then most likely your tabs have been converted to spaces, go look again. Copy/paste generally converts tabs to spaces. I suggest the following method which uses “cat” to copy entries from one pcitable to another:

    In this example our main pcitable to update is located here:


    and we will be copying entries from the following pcitable:


    First we get only the driver we’re interested in, let’s grab the tg3 entries:

    cat driverdisk/pcitable | grep ‘”tg3″‘

    Now that output looks good, let’s append that to our main pcitable. Please be careful and use the DOUBLE greater than sign and not the single. Single overwrites and double will append to.:

    cat driverdisk/pcitable | grep ‘”tg3″‘ >> initrd.img.dir/modules/pcitable

    Remember to make sure you don’t have duplicate lines elsewhere in the pcitable file. Also take into consideration that the pci device might be in there but be using a different driver. You could try editing your main pcitable in vi and use:


    Remember that :q! is the safe way out of vi if you mess things up.

    Another way of checking is (not tested but non-destructive):

    cat initrd.img.dir/modules/pcitable | awk ‘{print $1 $2}’ | wc -l
    cat initrd.img.dir/modules/pcitable | awk ‘{print $1 $2}’ | sed -e ‘s/ //g’ -e ‘s/\t//g’ | sort | uniq | wc -l

    The two lines should return the same answer. If the 2nd line is less than the first then you still have duplicate entries.

    Also you can change which driver gets loaded by changing the item in quotes. For example if you want to use the bcm5700 driver instead of the tg3 driver, then change “tg3” to be “bcm5700”. Then the bcm5700 driver will be automatically loaded (assuming the driver .o file is present).

    A substitute command in vi can be done as follows to change over from one driver to another:


  • Repacking modules.cgz
    cd /tmp/unpack/modules
    find . -type f | cpio -o -H crc | gzip -n9 >../modules.cgz
    mv ../modules.cgz .
  • Repacking initrd.img
  • Before moving modules.cgz back into the initrd, make sure that it is the same size or smaller than the original one.

    cd /tmp/unpack
    ls -ltr initrd.dir/modules/modules.cgz modules.cgz

    If the new modules.cgz is bigger than the original modules.cgz, then you will most likely get the modules.cgz back into the initrd.img; however, the initrd.img, will then probably be too big for the boot floppy. Consider throwing drivers you don’t need out of modules.cgz such as SCSI or Network Cards you don’t have or don’t plan on using. Even though there is plenty of space available in the initrd.img, there is only so much space available in the boot disk – and gzip is expecting much of the initrd.img file to be blank.

    Do the same kind of check on any of the other files you modified, such as modules.cgz, modules.dep, module-info, and pcitable, etc.

    cd /tmp/unpack
    for X in modules.dep, modules.cgz, module-info, pcitable; do \
    ls -ltr modules/$X initrd.dir/modules/$X; done

    Once you have compared the sizes of the various files then place them back into the initrd.dir.

    cd /tmp/unpack
    mv modules/modules.cgz initrd.dir/modules/modules.cgz
    mv modules/modules.dep initrd.dir/modules/modules.dep
    mv modules/module-info initrd.dir/modules/module-info
    mv modules/pcitable initrd.dir/modules/pcitable

    We need to blank out the unused portions of initrd – this is needed so gzip doesn’t try to compress data that we have already deleted out.

    cd /tmp/unpack
    dd if=/dev/zero of=initrd.dir/zero
    rm initrd.dir/zero
    Something similar to the following is expected:
    dd: writing to `initrd-everything/zero': No space left on device
    7479+0 records in
    7478+0 records out

    Unmount initrd.dir

    (This action finishes writing any cached information out to initrd.img, then it disconnects initrd.img from the initrd.dir directory. This behavior is just the same as working with a floppy under Linux – mount the floppy, work with it, unmount it – unmounting the floppy finishes writing any leftover information to the floppy, then returns to the prompt).

    cd /tmp/unpack
    umount initrd.dir

    Now gzip up initrd.img

    Note: The “file” utility can tell you if a file is compressed or not.

    cd /tmp/unpack
    gzip -9 -n initrd.img
    mv initrd.img.gz initrd.img
  • Repacking the Disk
  • Before moving the initrd.img back into the disk image, make sure that it is the same size or smaller than the original one.

    cd /tmp/unpack
    ls -ltr initrd.img disk.dir/initrd.img

    If you need more space in the disk image, you are able to remove all the disk.dir/*.msg files, but that is just about all the extra space you can get.

    Place the initrd.img back into the disk image

    cd /tmp/unpack
    mv initrd.img disk.dir/initrd.img

    Unmount the disk image – see note above on unmounting initrd.img for an understanding of why it is necessary to unmount the disk image.

    cd /tmp/unpack
    umount disk.dir
  • Troubleshooting steps if initrd.img no longer fits on the boot disk
    • Try unpacking the initrd.gz, moving out your modules/* files, blanking the empty space with “dd if=/dev/zero of=initrd.dir/zero; rm initrd.dir/zero”, then move your modules back into your initrd.dir, then repack initrd. Try putting it back onto your boot disk.
    • Thin out unneeded drivers from modules.cgz.
    • Make sure you are using maximum compression and leaving out unnecessary details:
      find 2.4.7-10BOOT/ | grep -v "BOOT/$" | cpio -o -H crc >modules.cpio
      gzip -9 -n modules.cpio
      gzip -9 -n initrd.img
  • Notes on initrd
  • Important parts of an initrd are as follows:
    When initrd boots, it immediately runs /linuxrc
    SCSI modules are located in the /lib directory
     console (5,1)
     null (1,3)
     ram (1,1)
     systty (4,0)
     tty1 (4,1)
     tty2 (4,2)
     tty3 (4,3)
     tty4 (4,4)
    Contents of linuxrc
    #!/bin/sash aliasall echo "Loading ncr53c8xx module" insmod /lib/ncr53c8xx.o
    pcitable contains information similar to "lspci" and "lspci -n"

    Here’s a script that I have and use to pull apart the bootnet.img floppy in the current directory. Once I modify the contents as I see fit (usually importing some driver from one of the other floppies into here) then I call the script which repacks everything for me. The repacking one probably can use some help in error recovery, but it works as is for now — just be careful about stuffing it too full.


    if [ ! -f bootnet.img ]; then
            echo unable to find bootnet.img in current directory, exiting...
    mkdir bootnet.img.dir
    mount bootnet.img bootnet.img.dir -o loop
    cp -a bootnet.img.dir/initrd.img initrd.img.gz
    gunzip initrd.img.gz
    mkdir initrd.img.dir
    mount initrd.img initrd.img.dir -o loop
    mkdir modules.cgz.dir
    zcat initrd.img.dir/modules/modules.cgz | (cd modules.cgz.dir && cpio -idvm)


    if [ ! -d modules.cgz.dir ]; then
            echo "Sorry, I don't understand how to reapck this..."
    # Let's repack the modules
    echo +++Repacking modules
    (cd modules.cgz.dir && find . | grep -v "BOOT/$" | cpio -o -H crc | gzip -n -9 ) >modules.cgz
    mv modules.cgz initrd.img.dir/modules/modules.cgz
    if [ $RESULT -ne 0 ]; then
            echo No room left to place modules.cgz in initrd.img
    # Lets handle initrd
    echo +++Repacking initrd
    dd if=/dev/zero of=initrd.img.dir/zero.tmp bs=1440k count=8 >/dev/null 2>&1
    if [ $? -eq 1 ]; then
            echo unknown error writing zero file to initrd.img.dir
    rm -rf initrd.img.dir/zero.tmp
    umount initrd.img.dir
    echo +++Checking initrd.img for errors
    e2fsck -f initrd.img
    if [ $RESULT -ne 0 ]; then
            echo initrd.img had errors
    gzip -n -9 initrd.img
    mv initrd.img.gz bootnet.img.dir/initrd.img
    if [ $RESULT -ne 0 ]; then
            echo No room left to place initrd.img in bootnet.img
            gunzip initrd.img.gz
            mount initrd.img initrd.img.dir -o loop
    # Cleanup
    if [ $SUCCESS == true ]; then
            echo +++Cleanup
            rm -rf modules.cgz.dir
            rmdir initrd.img.dir
            umount bootnet.img.dir
            rmdir bootnet.img.dir

    Here’s some work on automating the process of pulling a driver out of drvnet.img and placing it into bootnet.img:

    Making sure we have only 1 entry to check:
    MYMODULE_COUNT=`cat mod/modinfo | grep $MYMODULE | sed -e 's,^\t.*$,,' | grep -v "^ *$" | wc -l`
    if ($MYMODULE_COUNT > 1 -o $MYMODULE_COUNT < 1); then exit
    cat mod/modinfo | awk -v MYVAR=$MYMODULE '
       if($0 ~ MYVAR)
          PRINT="ON"; print
    Just run all the above awk line together on one line; I seperated it
    here for readability.

    Ok, here's an update, a short little script that somewhat reliably
    reads out of modinfo and complains if the user isn't specific enough
    about which module to grab
    if [ -z $1 ]; then
            echo Hey, tell me which module you want to import.
    MYMODULE_COUNT=`cat mod/modinfo | grep $MYMODULE | sed -e 's,^\t.*$,,' | grep -v "^ *$" | wc -l`
    if [ $MYMODULE_COUNT -ne 1 ]; then
    cat mod/modinfo | grep $MYMODULE | sed -e 's,^\t.*$,,' | grep -v "^ *$"
            echo No, not today, I am confused, please choose only one
    cat mod/modinfo | awk -v MYVAR=$MYMODULE 'BEGIN {PRINT="OFF"} {if(PRINT=="ON"){if(/^\t/){print}else{PRINT="OFF"}}} {if(PRINT!="ON"){if($0 ~ MYVAR) {PRINT="ON"; print}}}'

    What’s left to do is:
    work with modinfo — mostly done
    work with pcitable — should be easy as pie (cat pcitable | grep -i $MYMODULE — needs a little work especially for tg3/bcm5700)
    work with modules.dep — shouldn’t be a challenge (cat modules.dep | grep $MYMODULE)
    work with modules.cgz — (zcat modules.cgz | cpio -idvm)
    automate the unpacking of drvnet.img
    get size of new module to be inserted
    remove out enough stuff from bootnet.img to compensate for
    new driver / interracting with user to choose which to delete

    # Inspect each of the boot disks or driver disks and
    # tell me what modules are inside.
    FILELIST="`file * | grep "Linux rev 1.0 ext2 filesystem data" | sed -e 's,:.*$,,'`"
    FILELIST="$FILELIST `file * | grep "x86 boot sector, system SYSLINUX, FAT (12 bit)" | sed -e 's,:.*$,,'`"
    for X in `echo $FILELIST | sed -e 's, ,\n,g' | sort`; do
    echo -----------
    echo $X
    echo -----------
    mkdir tmp 2>/dev/null
    mount $X tmp -o loop
    INITRD=`find tmp | grep initrd`
    if [ -n "$INITRD" ]; then
            cp -a $INITRD .
            INITRD=`basename $INITRD`
            mv $INITRD ${INITRD}.gz
            gunzip ${INITRD}.gz
            mkdir initrd.dir
            mount $INITRD initrd.dir -o loop
            MODULES=`find initrd.dir | grep modules.cgz`
            if [ -n "$MODULES" ]; then
                    mkdir modules.dir
                    (cd modules.dir && zcat ../$MODULES | cpio -idvm 2>&1)
                    rm -rf modules.dir
            umount initrd.dir
            rmdir initrd.dir
            rm -rf $INITRD
            MODULES=`find tmp | grep modules.cgz`
            if [ -n "$MODULES" ]; then
                    mkdir modules.dir
                    (cd modules.dir && zcat ../$MODULES | cpio -idvm 2>&1)
                    rm -rf modules.dir
    umount tmp
    rmdir tmp

    Need more information? I found this cool link:

    If any of this information is unclear or needs changing, please comment below.

    Also see

    Leave a Comment

    This site uses Akismet to reduce spam. Learn how your comment data is processed.

    Exit mobile version