Working with “initramfs” and “initrd” in Linux

Ahmed MansouriAhmed Mansouri
6 min read

In Linux, the initrd (initial RAM disk) and initramfs (initial RAM File System) are different methods we can use to load a temporary root file system to the RAM or system memory for successful booting. Initramfs/initrd is used as the first root filesystem that your machine has access to.

In many situations , you will find yourself needing to:

  • Check if a driver or a module exists in the initramfs/initrd or not

  • Add a new driver/module to an initramfs/initrd file

  • Remove a driver/module from an initramfs/initrd file

I — File name :

The file name changes from a Linux distribution to another and from a version to another, and for the new Linux distribution versions you will generally find the file with these names under the “/boot directory

  • RHEL/CentOS/Fedora/Ubuntu/Debian ..
initramfs-<kernel-version>.img
  • SUSE SLES
initrd-<kernel-version>

Note /!\ : SUSE SLES is also using initramfs , however it is stored as /boot/initrd. More details can be found in this link.

For the current kernel version in your server, the file name can be getting using the following expression :

initramfs-$(uname -r).img

initrd-$(uname -r)

The command uname -r is used to get the current kernel name.

Examples :

  • RHEL machine :

Example : initramfs-4.18.0–372.9.1.el8.x86_64.img

[root@ip-172-31-39-129 ~]#  ls -la /boot/
total 171228
dr-xr-xr-x.  5 root root     4096 Jun 26 09:32 .
dr-xr-xr-x. 17 root root      224 May  3  2022 ..
-rw-r--r--.  1 root root   195982 Apr 16  2022 config-4.18.0-372.9.1.el8.x86_64
drwxr-xr-x.  3 root root       17 May  3  2022 efi
drwx------.  4 root root       65 May  3  2022 grub2
-rw-------.  1 root root 62262494 May  3  2022 initramfs-0-rescue-ffffffffffffffffffffffffffffffff.img
-rw-------.  1 root root 61798085 May  3  2022 initramfs-4.18.0-372.9.1.el8.x86_64.img
-rw-------.  1 root root 25783296 Jun 26 09:32 initramfs-4.18.0-372.9.1.el8.x86_64kdump.img
drwxr-xr-x.  3 root root       21 May  3  2022 loader
lrwxrwxrwx.  1 root root       49 May  3  2022 symvers-4.18.0-372.9.1.el8.x86_64.gz -> /lib/modules/4.18.0-372.9.1.el8.x86_64/symvers.gz
-rw-------.  1 root root  4359450 Apr 16  2022 System.map-4.18.0-372.9.1.el8.x86_64
-rwxr-xr-x.  1 root root 10460528 May  3  2022 vmlinuz-0-rescue-ffffffffffffffffffffffffffffffff
-rwxr-xr-x.  1 root root 10460528 Apr 16  2022 vmlinuz-4.18.0-372.9.1.el8.x86_64
-rw-r--r--.  1 root root      170 Apr 16  2022 .vmlinuz-4.18.0-372.9.1.el8.x86_64.hmac

[root@ip-172-31-39-129 ~]# uname -r
4.18.0-372.9.1.el8.x86_64
  • SUSE machine :

Example : initrd-4.4.180–94.153-default

ip-172-31-29-209:~ # ls -la /boot
total 36320
drwxr-xr-x  3 root root     4096 Jun 26 09:27 .
drwxr-xr-x 23 root root     4096 Jun 26 09:27 ..
-rw-r--r--  1 root root       65 Feb  1  2022 .vmlinuz-4.4.180-94.153-default.hmac
-rw-r--r--  1 root root        0 Mar  3  2022 0x40e2938e
-rw-r--r--  1 root root  3280251 Feb  1  2022 System.map-4.4.180-94.153-default
lrwxrwxrwx  1 root root        1 Jun 26 09:25 boot -> .
-rw-r--r--  1 root root     1725 Nov 15  2018 boot.readme
-rw-r--r--  1 root root   163622 Feb  1  2022 config-4.4.180-94.153-default
drwxr-xr-x  6 root root     4096 Jun 26 09:27 grub2
lrwxrwxrwx  1 root root       29 Mar  3  2022 initrd -> initrd-4.4.180-94.153-default
-rw-------  1 root root  8752104 Jun 26 09:26 initrd-4.4.180-94.141-default
-rw-------  1 root root 10004276 Jun 26 09:26 initrd-4.4.180-94.153-default
-rw-r--r--  1 root root       11 Jun 26 09:27 mbrid
-rw-r--r--  1 root root   323914 Feb  1  2022 symvers-4.4.180-94.153-default.gz
-rw-r--r--  1 root root      377 Feb  1  2022 sysctl.conf-4.4.180-94.153-default
-rw-r--r--  1 root root  1484762 Mar  3  2022 unicode.pf2
-rw-r--r--  1 root root  7025166 Feb  1  2022 vmlinux-4.4.180-94.153-default.gz
lrwxrwxrwx  1 root root       30 Mar  3  2022 vmlinuz -> vmlinuz-4.4.180-94.153-default
-rw-r--r--  1 root root  6115040 Feb  1  2022 vmlinuz-4.4.180-94.153-default
ip-172-31-29-209:~ # 
ip-172-31-29-209:~ # uname -r
4.4.180-94.153-default

II — List the content of the initramfs/initrd file

— In order to check the content of the initramfs/initrd file , use the command below (this is used for both initramfs and initrd):

# lsinitrd

This command will give you the content of the initramfs/initrd of the current loaded kernel (means the one given by the uname -r command)

— Because the server can have multiple initramfs/initrd files (for each kernel version installed there is a file created for it), and in order to check the content of a specific file, use the command as below :

# lsinitrd  /path/<file-name>

— In order to check if a driver/module exists in the file, use *egrep* :

# lsinitrd  /path/<file-name> | egrep -i "<module-name>"

Let’s take an example :

For EC2 Nitro instances , they need “ena”, “nvme” and “nvme-core” drivers in order to boot correctly. And if the OS is using LVMs (Logical Volumes), then the initramfs/initrd should have the “lvm” module also added . So let’s check them for the following initramfs file :

# lsinitrd  /boot/initramfs-4.18.0-372.9.1.el8.x86_64.img | egrep -i "ena|nvme|lvm"

→ Here we can see that “ena”, “nvme” and “nvme-core” drivers exist in the initramfs file , however the “lvm” module doesn’t exist.


III — Add a driver/module to an initramfs/initrd file :

Let’s try for example here to add the “lvm” module to the previous initramfs file :

  • Let’s first see if the LVM is installed :
[root@ip-172-31-39-129 ~]# rpm -aq | grep lvm
[root@ip-172-31-39-129 ~]#
  • The LVM2 package is not installed , let’s install it :
[root@ip-172-31-39-129 ~]# yum install lvm2 -y
[root@ip-172-31-39-129 ~]#
[root@ip-172-31-39-129 ~]# rpm -aq | grep lvm 
lvm2-libs-2.03.14-9.el8.x86_64
lvm2-2.03.14-9.el8.x86_64

The lvm2 package is now installed

  • Let’s see if it was added automatically to the initramfs file or not:
# lsinitrd /boot/initramfs-4.18.0-372.9.1.el8.x86_64.img | egrep -i "lvm"

The module will not be added to the initramfs file until we add it manually.

  • Okay , let’s now add the lvm module to our initramfs file
  1. Create a file under the /etc/dracut.conf.d/ directory and give it a name with .confas suffix
# echo 'add_dracutmodules+=" lvm "'> /etc/dracut.conf.d/lvm.conf

Note /!\ : The module name should be surrounded with white spaces.

2. Re-generate the initramfs for the current kernel (we will see with more details how to regenerate files in the next section):

[root@ip-172-31-39-129 ~]# dracut -f

3. Let’s check again the presence of the lvm module :

# lsinitrd /boot/initramfs-4.18.0-372.9.1.el8.x86_64.img | egrep -i "lvm"

The lvm module is now present in our initramfs file :)


IV — Re-generate the initramfs/initrd file:

Here we will see how to re-gerenerate the initramfs file for the different cases

Note /!&nbsp; : make sure to backup the initramfs/initrd file before generating the new one if you are not sure about what you are doing!!!

  • Create the initramfs for the current kernel:
# dracut -f
or
# dracut initramfs-$(uname -r).img $(uname -r)
  • If you need to re-generate it for a specific kernel version (replace the version appropriately):
# dracut -f /boot/initramfs-4.18.0-372.9.1.el8.x86_64.img 4.18.0-372.9.1.el8.x86_64
  • If you need to re-generate all initramfs files , use the command :
# dracut -v --force --regenerate-all

Note : the "-f"or “--force” is for overriding the initramfs files


V — How to remove a module from an initramfs/initrd file :

I’m going to give two options that can be used in order to remove a module from an initramfs/initrd file :

(In this example we will remove the lvm module that we added previously from the initramfs file )

** Option 1 ** : Use the “--omit” option during the regeneration of the initramfs file :

  1. Let’s first here moving the initramfs file :
# cd /boot/
# mv initramfs-4.18.0-372.9.1.el8.x86_64.img  initramfs-4.18.0-372.9.1.el8.x86_64.img.bkp

2. Regenerate the initramfs file with the --omit option

# dracut -f /boot/initramfs-4.18.0-372.9.1.el8.x86_64.img 4.18.0-372.9.1.el8.x86_64 --omit lvm

3. Let’s check if the lvm module exists in the new initramfs file :

# lsinitrd  /boot/initramfs-4.18.0-372.9.1.el8.x86_64.img | grep lvm
Arguments: -f --omit 'lvm'
#

The module was removed correctly from the initramfs file

** Option 2 ** : Use of the parameter “omit_dracutmodules+=” under the directory /etc/dracut.conf.d/ :

  1. Create a config file under the directory /etc/dracut.conf.d/ containing the following :
# echo 'omit_dracutmodules+=" lvm "'> /etc/dracut.conf.d/omit_lvm.conf

2. Regenerate the initramfs file :

# dracut -f

3. Let’s try to check if the lvm module exists in the new initramfs file

# lsinitrd | grep lvm

The module was removed correctly :)


If you found the post enjoyable, don’t hesitate to show your support by clapping/liking or leaving a comment and following me 😁 — Thanks

0
Subscribe to my newsletter

Read articles from Ahmed Mansouri directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ahmed Mansouri
Ahmed Mansouri

System, Cloud and DevOps Linkedin : www.linkedin.com/in/ahmed-mansouri-a54637141