How-to : Add / update a driver in an [CentOS-RHel]5 initrd.img



I recently had to update some initrd used for our PXE infrastructure. I found some blog posts on the web (here and here and here) but none of them were flawless in my case, i then decided to add my point of view on this process.

I am going to use my actual experience in this post, which was :

I had to install an old RHel55 distro on few brand new 12th generation Dell R620 / R320 servers, I choose the Broadcom BCM5720 network card, and this card requires an updated tg3 driver (version 3.133d in my case but i know the 3.129 to work fine). This post will then be about adding the updated tg3 driver on top of the kernel provided tg3 driver.

I hope it will help someone.



1) Master plan

Here is the master plan that should help you to best understand the process as a whole.

  1. Find / Download the correct driver that is known to fix you issue
  2. Get your hand on your distro initrd used by the PXE boot (find out where in this post)
  3. Extract the initrd.img and the modules.cgz archive
  4. Update the required module file (.ko) and the configuration files
  5. Re-pack the modules.cgz and the initrd.img
  6. Test your PXE using your newly built initrd.img
  7. Have a drink !



2) Find & download the correct driver

In my case it was about a Broadcom driver, i then get my browser to the “Download” section of the Broadcom website (here) and found the Linux driver.

One usually has 2 choices regarding a Linux driver download, you can either download a tgz or a packaged version (.rpm, .deb or whatever package system you use…), it is up to you. I am sure you know that the packaged version will be easier to install when using the sources (from the tgz) allows you to customise your compilation and usually gives you access to the very latest version.

Once you have your driver ready (compiled or packaged) you may want to test it on a running system that is similar to the one you are trying to install via PXE (test can be done by updating the driver on a working machine and probing to check that it actually works :)



3) Extracting the initrd.img and the modules.cgz archive

We are now going to make the required files available by extracting 2 compressed file : initrd.img and modules.cgz.

We may first create a temporary directories tree to work safe and clean : at this point you may need to know if you are going to test a lot of customization or not, because in this case you nay need to make 2 directories, one containing the original initrd.img and one in which you will make your customization. In the following example i am just going to use one directory.


3.1 extracting the initrd.img

Create the directory in which we are going to customize the original initrd.img :

mkdir -p /tmp/update_initrd/initrd

Copy the original file to the tmp dir (and cd to it) :

cp /tftpboot/RHEL55ES/initrd.img /tmp/update_initrd/
cd /tmp/update_initrd/

Now we extract the initrd.img using gunzip and cpio :

gunzip -S .img < initrd.img > initrd.img.ungzipped
cd initrd && cpio -i --make-directories < ../initrd.img.ungzipped

We now have a directory that contains the extracted initrd.img : /tmp/update_initrd/initrd/


3.2 extracting the modules.cgz

We still need to extract the modules.cgz.

cd to the modules directory :

cd modules/

Create an unpacked directory in which we are going to extract the modules.cgz :

mkdir unpacked

Extract the modules.cgz to the unpacked dir :

gunzip < modules.cgz | (cd ./unpacked && cpio -idv)

We now have all the files we need to add our updated tg3 driver.



4) Updating the required module file (*.ko) and the configuration files

Here is the real job that needs to be done : replacing the kernel module AND updating the required files, most of the issues you may face when customizing an initrd.img image will be due to the configuration files being badly or not updated.


4.1 Replacing the old driver by the new one

Replace the kernel module (tg3.ko file in the unpacked dir) by the newly built one :

cp <PATH_TO_NEW_TG3>/tg3.ko unpacked/

You may also need to copy some other module required as a dependency for the one you just built (you can find out the dependencies for a given module using the modinfo utility), in this very case we need the hwmon module (i got it from an already installed identical OS / Kernel) :

cp /lib/modules/2.6.18-194.el5/kernel/drivers/hwmon/hwmon.ko unpacked/


4.2 Updating the required text files

There are 4 different text files inside the modules directory. Each may need to be updated regarding the driver you are upgrading, here is a quick definition of these files that may help you :

  • module-info
    This file is not critical, it only contains basics module / driver informations.
    Excerpt from this page : It is an information file that is at least used during filing proper kernel OOPS reports. It is a list of the module entry points. It may also be used by depmod in building the tables that are used by insmod and its kith and kin. This includes dependency information for other modules needed to be loaded before any other given module, etc.
    Some extra points about module-info :

    • Is provided by the kernel rpms (built by anaconda-runtime*.rpm)
    • Is a link to module-info-kernel-version
    • Contains information about all available modules (at least those included in the default kernel config.)
    • Important to anaconda – in anaconda/utils/modlist command.
    • Might be used by kudzu to determine default parameters for modules when it creates entries in /etc/modules.conf. If you move module-info out of the way, shut down, install a new network card, and re-boot then kudzu would complain loudly. Look at the kudzu source code.


  • modules.alias
    This file contains all the hardware aliases (coded names) for which a given driver will be loaded. You may then need to update the list of aliases for the driver you are upgrading (see the change that were required in my case below).
    You may use the following command to get the values that needs to be added to this file :

    depmod -n <path_to_module>


    modinfo -F alias <path_to_module>
  • modules.dep
    The goal of this file is self-explanatory : it contains the list of modules that are required by other modules. This file’s syntax is simple : 2 fields separated by a colon, the first field may contains only one module name and the second field may contains any number of modules names. The modules listed on the right side of the colon are the dependencies required for the module from the left side of the colon.
    e.g : If the module tg3 needs the hwmon module to be loaded first, you would see a line like this :

    tg3: hwmon

    You may find out the list of dependencies with :

    modinfo -F depends <path_to_module>
  • pci.ids
    This file contains all the matches between PCI addresses and hardware names, it used by some pci utilities like lspci. You may  find the required update inside the pci.updates file that may be shipped with the driver sources…




5) Re-packing the modules.cgz and the initrd.img files

As we are now done with the updates, we just have to repack everything back as if nothing ever happened !


5.1 Repacking the modules.cgz

As usually, you should keep a untouched version of every file you modified :

mv modules.cgz ../../initrd/modules.cgz.BAK

Repack the modules.cgz archive :

cd unpacked && find 2.6.18-194.el5 | cpio -ov -H crc | gzip > ../modules.cgz


5.2 Repacking the initrd.img

Once you are done with all other files, you only have to rebuild the initrd file :

(find . | cpio --quiet -c -o) > ../

Gzip it :

mv initrd.img

Copy the newly built initrd image to your PXE tftp directory and you are done !





You should now have a PXE-able RHel5 version that works with the newest Dell server (12th gen), or at least i do have one ! I hope this post AND the posts listed below (in the Resources section) will help you understanding and building the structure of an initrd image as well as the basics concepts of Linux kernel modules.





More “Sysadmin” posts

5 thoughts on “How-to : Add / update a driver in an [CentOS-RHel]5 initrd.img

  1. Pingback: Redes Centos 7 como servidor de arranque PXE - Deshn Grupo GNU-Linux Paraguay

  2. Krzysztof

    Thanks , very nice guide.
    I was trying to do this on RHEL 6.5 initrd.img.
    However I found that folder “modules” in uncompressed initrd is empty- no txt files to update .
    I found that folder lib/2.6.32-xxxx/modules contains these txt files and other modules.
    Should then new_driver.ko be placed there instead of modules ?
    Thanks, krzysztof

    1. Pier Post author

      Thanks for your kind comment Krzysztof, I haven’t tried this on a RHel6 box so I cannot be sure about the correct modules location, the best thing to do would be to search for the old module version (regarding the new_driver.ko), and just replace it with your new version…
      However, you might be trying to add a brand new driver, in this case, as in any case, you have to locate where all kernel modules are stored.

      Oh I just thought about something, did you realize that this guide was about updating the tftp boot initrd ? I did not update the runtime initrd yet, but I am quite sure you can use dracut or some specific tools for that purpose…

      Sorry for being a bit useless here !

Leave a Reply to Pier Cancel reply

Your email address will not be published. Required fields are marked *

This site supports SyntaxHighlighter via WP SyntaxHighlighter. It can highlight your code.
How to highlight your code: Paste your code in the comment form, select it and then click the language link button below. This will wrap your code in a <pre> tag and format it when submitted.