Working with “initramfs” and “initrd” in Linux
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
- Create a file under the
/etc/dracut.conf.d/
directory and give it a name with.conf
as 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 /! : 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 :
- 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/
:
- 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
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