Adding additional/new modules to the initial ramdisk on Linux.

Recently I needed to add the support for a new network-interface to a initial ramdisk (initrd) on Linux (RHEL 5u3).

After some h4ck1ng and a number of hours on Google I was able to do add the module to the initrd. :-)

The steps I did are:

Extract initrd

  1. Get an original initrd.img from a boot ISO and put it into /tmp/initrd.img-original
  2. Create a temp environment where we can extract the initrd:

    $ mkdir -p /scratch/initrd-mod/{initrd,modules}
  3. Extract the /tmp/initrd.img-original to the temp-environment:

    $ cd /scratch/initrd-mod/initrd
    $ zcat /tmp/initrd.img-original | cpio -i

Add the module to initrd.img

Extract the modules.cgz file

The modules (.ko files) are located in the (container) modules/modules.cgz in the initrd.

Now you need to extract the modules.cgz file:

$ cd /scratch/initrd-mod/modules
$ zcat /scratch/initrd-mod/initrd/modules/modules.cgz | cpio -idvm

Add the module

Now you've to make sure you've an module compiled using the right kernel version and architecture. Copy the new .ko file into the extracted modules.cgz tree

$ cp /tmp/new-module.ko /scratch/initrd-mod/modules/{VERSION}/{ARCH}

So in my case with RHEL5u3 it is the location:

$ cp /tmp/igb.ko /scratch/initrd-mod/modules/2.6.18-128.el5/x86_64/

Repack the modules.cgz

Now we need to repack the modules.cgz file:

$ cd /scratch/initrd-mod/modules
$ find . -type f | cpio -o -H crc | gzip -n9 > /scratch/initrd-mod/initrd/modules/modules.cgz

Modify the modules.alias file

Now you need to modify the modules.alias file in order to get the module loaded properly.

The aliases can be find using modinfo:

$ /sbin/modinfo /tmp/igb.ko | grep ^alias
alias: pci:v00008086d000010D6sv*sd*bc*sc*i*
alias: pci:v00008086d000010A9sv*sd*bc*sc*i*
alias: pci:v00008086d000010A7sv*sd*bc*sc*i*
alias: pci:v00008086d000010E8sv*sd*bc*sc*i*
alias: pci:v00008086d0000150Dsv*sd*bc*sc*i*
alias: pci:v00008086d000010E7sv*sd*bc*sc*i*
alias: pci:v00008086d000010E6sv*sd*bc*sc*i*
alias: pci:v00008086d0000150Asv*sd*bc*sc*i*
alias: pci:v00008086d000010C9sv*sd*bc*sc*i*

The correct entries can be create using the following one liner (in this case for the igb module):

$ /sbin/modinfo /tmp/igb.ko | grep ^alias | awk '{ print "alias " $2 " igb" }'
alias pci:v00008086d000010D6sv*sd*bc*sc*i* igb
alias pci:v00008086d000010A9sv*sd*bc*sc*i* igb
alias pci:v00008086d000010A7sv*sd*bc*sc*i* igb
alias pci:v00008086d000010E8sv*sd*bc*sc*i* igb
alias pci:v00008086d0000150Dsv*sd*bc*sc*i* igb
alias pci:v00008086d000010E7sv*sd*bc*sc*i* igb
alias pci:v00008086d000010E6sv*sd*bc*sc*i* igb
alias pci:v00008086d0000150Asv*sd*bc*sc*i* igb
alias pci:v00008086d000010C9sv*sd*bc*sc*i* igb

Make sure you remove duplicates in the modules.aliases file.

Repack the initrd.img

Now it's time to repack the intird.img file with the new module:

$ cd /scratch/initrd-mod/initrd
$ find ./ | cpio -H newc -o | gzip -n9 > /tmp/initrd.img-modded

And put the /tmp/initrd.img-modded onto your boot disk.