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
- Get an original initrd.img from a boot ISO and put it into /tmp/initrd.img-original
- Create a temp environment where we can extract the initrd:
$ mkdir -p /scratch/initrd-mod/{initrd,modules}
- 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.