14

Injecting kernel modules in initrd.gz for the Debian Installer

 3 years ago
source link: http://www.linux-admins.net/2014/02/injecting-kernel-modules-in-initrdgz.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Injecting kernel modules in initrd.gz for the Debian Installer

I manage a PXE infrastructure running Cobbler that I use to kickstart Debian and RedHat servers. I had to install Wheezy on few Dell R720's that had some NIC's with drivers not in the Wheezy initrd image file, so the PXE was failing. I decided to rebuild the initrd image file with the new drivers that I was able to find from source. The process is as follows:

First check the version of the linux kernel and the initrd that is used by the Wheezy installer:

[root@server1 ~] file /srv/www/cobbler/ks_mirror/debian_wheezy-x86_64/install/linux /srv/www/cobbler/ks_mirror/debian_wheezy-x86_64/install/linux: Linux kernel x86 boot executable bzImage, version 3.2.0-4-amd64 (debian-kernel@li, RO-rootFS, swap_dev 0x2, Normal VGA

[root@server1 ~] file /srv/www/cobbler/ks_mirror/debian_wheezy-x86_64/install/initrd.gz /srv/www/cobbler/ks_mirror/debian_wheezy-x86_64/install/initrd.gz: gzip compressed data, was "initrd", from Unix, last modified: Thu Dec 12 06:18:41 2013, max compression

I actually got the latest versions of the kernel and initrd from here:

[root@server1 ~] wget http://ftp.de.debian.org/debian/dists/wheezy/main/installer-amd64/current/images/netboot/debian-installer/amd64/linux [root@server1 ~] wget http://ftp.de.debian.org/debian/dists/wheezy/main/installer-amd64/current/images/netboot/debian-installer/amd64/initrd.gz

To extract the files from the initrd image run the following:

[root@server1 ~/initrd] gzip -cd /srv/www/cobbler/ks_mirror/debian_wheezy-x86_64/install/initrd.gz | cpio -id 57790 blocks [root@server1 ~/initrd] ls -la total 68 drwxr-xr-x 16 root root 4096 Feb 27 16:01 . drwx------ 21 root root 4096 Feb 27 16:05 .. drwxr-xr-x 2 root root 4096 Feb 27 15:21 bin drwxr-xr-x 2 root root 4096 Feb 27 15:21 dev drwxr-xr-x 11 root root 4096 Feb 27 15:21 etc -rwxr-xr-x 1 root root 456 Feb 27 15:21 init drwxr-xr-x 2 root root 4096 Feb 27 15:21 initrd drwxr-xr-x 13 root root 4096 Feb 27 15:21 lib lrwxrwxrwx 1 root root 4 Feb 27 15:21 lib64 -> /lib drwxr-xr-x 2 root root 4096 Feb 27 15:21 media drwxr-xr-x 2 root root 4096 Feb 27 15:21 mnt drwxr-xr-x 2 root root 4096 Feb 27 15:21 proc drwxr-xr-x 2 root root 4096 Feb 27 15:21 run drwxr-xr-x 2 root root 4096 Feb 27 15:21 sbin drwxr-xr-x 2 root root 4096 Feb 27 15:21 sys drwxrwxr-x 2 root root 4096 Feb 27 15:21 tmp drwxrwxr-x 6 root root 4096 Feb 27 15:21 usr drwxrwxr-x 6 root root 4096 Feb 27 15:21 var

Now, if the kernel you are currently running matches the kernel that you are trying to build the driver for, then you can just compile the driver from source (./configure && make) and replace the .ko file that is in the initrd image file that you've just unpackaged. In this example I am compiling the Intel e1000 driver, so replacing it is simple:

[root@server1 ~/initrd] find . -name e1000.ko ./lib/modules/3.2.0-4-amd64/kernel/drivers/net/ethernet/intel/e1000/e1000.ko [root@server1 ~/initrd] cp /usr/src/intel/driver/e1000.ko lib/modules/3.2.0-4-amd64/kernel/drivers/net/ethernet/intel/e1000/

If the kernel you are currently running does not match the kernel for the installer then you have to install the kernel headers for that version, edit the Make file and find or add an option similar to this:

[root@server1 ~/initrd] cd /usr/src/intel/driver/ [root@server1 /usr/src/intel/driver] cat Make ... BUILD_KERNEL=3.2.0-4-amd64 make ... [root@server1 /usr/src/intel/driver] ./configure && make

Once you have replaced the kernel module it's time to rebuild the initrd image and replace the old one so that Cobbler can sync it and tftp can serve it:

[root@server1 ~/initrd] find . | cpio -o -H newc | gzip > ../initrd.gz [root@server1 ~/initrd] cp ../initrd.gz /srv/www/cobbler/ks_mirror/debian_wheezy-x86_64/install/

If you are not replacing an already existing driver in the initrd image, then you can just copy the .ko file somewhere in the extracted image and edit the init script file that's in the / of the initrd image:

[root@server1 ~/initrd] cp /usr/src/intel/driver/newmodule.ko lib/modules/3.2.0-4-amd64/kernel/drivers/net/ethernet/ [root@server1 ~/initrd] vim init

#!/bin/sh -e # used for initramfs export PATH . /lib/debian-installer/init-debug debugshell "just booted"

mount /run mkdir -p /run/lock mount /proc mount /sys /lib/debian-installer/start-udev

init='/bin/busybox init' for i in $(cat /proc/cmdline); do case $i in init=/init|init=init) # Avoid endless loop : ;; init=*) init=${i#init=} ;; noshell) sed -i '/^tty[23]/s/^/#/' /etc/inittab ;; esac done debugshell "before init" ### Add the bellow modprobe modprobe /lib/modules/3.2.0-4-amd64/kernel/drivers/net/ethernet/newmodule.ko exec $init

In some cases you might have to get the latest PCI ID file, that contains all known ID's used in PCI devices and replace the one in the initrd file:

[root@server1 ~/initrd] find . -name pci.ids* ./usr/share/misc/pci.ids.gz [root@server1 ~/initrd] rm -f usr/share/misc/pci.ids.gz [root@server1 ~/initrd] wget http://pciids.sourceforge.net/v2.2/pci.ids.gz -O usr/share/misc/pci.ids.gz --2014-02-27 22:42:45-- http://pciids.sourceforge.net/v2.2/pci.ids.gz Resolving pciids.sourceforge.net... 216.34.181.96 Connecting to pciids.sourceforge.net|216.34.181.96|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 215672 (211K) [application/x-gzip] Saving to: "usr/share/misc/pci.ids.gz"

100%[======================================================================================================================================================================================================================================>] 215,672 --.-K/s in 0.02s

2014-02-27 22:42:45 (8.26 MB/s) - "usr/share/misc/pci.ids.gz" saved [215672/215672]

To add a firmware blob, you can copy the bin file to /usr/local/lib/firmware the same way like the driver, but just make sure to run update-initramfs -u

This is a nice and simple way of adding kernel drivers to the initrd image file for PXE booting new severs.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK