Table of Contents
- 1) Master plan
- 2) Find & download the correct driver
- 3) Extracting the initrd.img and the modules.cgz archive
- 4) Updating the required module file (*.ko) and the configuration files
- 5) Re-packing the modules.cgz and the initrd.img files
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.
- Find / Download the correct driver that is known to fix you issue
- Get your hand on your distro initrd used by the PXE boot (find out where in this post)
- Extract the
initrd.imgand the modules.cgz archive
- Update the required module file (
.ko) and the configuration files
- Re-pack the
- Test your PXE using your newly built
- 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 :
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
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
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
3.2 extracting the modules.cgz
We still need to extract the
cd to the modules directory :
Create an unpacked directory in which we are going to 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
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 :
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
depmodin 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
- 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.
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>
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
hwmonmodule to be loaded first, you would see a line like this :
You may find out the list of dependencies with :
modinfo -F depends <path_to_module>
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.updatesfile 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
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) > ../initrd.img.new
Gzip it :
mv initrd.img.new.gz 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.
- An Archlinux page about kernel modules : Archlinux
- smshacker blog post
- Ruizs place blog post
- Dan’s Linux Blog post
More “Sysadmin” posts
- Memory leak : What is the (R)syslog facility used by fail2ban
- How-to : Fix the W: Possible missing firmware /lib/firmware/bnx2/bnx2-mips-09-6.2.1a.fw for module bnx2
- Bash scripts examples : Graylog-collector init script
- Bash tips : Adding time stamps to history command output
- How-to : Expand a RAID array using omconfig / omreport CLI
- How-to : Create a RAID array using omconfig / omreport CLI
- How-to : Check if a device is supported by any of the modules currently installed on your system
- How-To : Replace dead / faulty drive in Dell PERC RAID array
- How-to : Basic PXE infrastructure #4 – NFS server installation and setup on CentOS
- Linux command tips : systemctl
- Bash snippets & functions : Make a variable readable/reachable from outside a pipe + loop (AKA process substitution)
- How-to : Add RAW files support to [RHel-CentOS] 6.x