How to build an initramfs using Dracut on Linux

In a previous article we talked about listening and extracting the content of an initramfs image using standard, simple tools like gzip, dd and cpio or with dedicated scripts like lsinitramfs, lsinitrd and unmkinitramfs. In this tutorial we learn how to (re)build an initramfs on Linux using dracut.

In this tutorial you will learn:

  • What is dracut
  • How to list dracut modules
  • How to build an initramfs with dracut
  • How to build an initramfs for a specific kernel version
  • How to build an initramfs for all kernels
  • How to build an host-tailored initramfs
  • How to list files contained in the initrams and get their content
  • How to include extra files in the initramfs
  • How to change the initramfs compression method
  • How to use dracut configuration files
How to build an initramfs using dracut on Linux
How to build an initramfs using dracut on Linux

Software requirements and conventions used

Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Distribution-independent
Software Dracut
Other Root privileges
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

Introducing dracut

Dracut is a tool used to build initramfs cpio archives. It originated, and is mainly used on Fedora and the other distributions that are part of the Red Hat family, but can be used also on community distributions like Gentoo, and Archlinux. The application functionalities are organized in modules. In order to list all the dracut modules available on the system, we simply have to invoke the application with the --list-modules option, which returns an output similar to the following:

$ dracut --list-modules
bash
systemd
systemd-network-management
warpclock
fips
systemd-ac-power
systemd-ask-password
systemd-coredump
systemd-hostnamed
systemd-initrd
systemd-journald
systemd-ldconfig
systemd-modules-load
[...]

All dracut modules are located in the /usr/lib/dracut/modules.d directory. In this directory, all modules are represented as subdirectories, and contain a series of scripts. Each modules provides a specific functionality. The plymouth module, for example, (/usr/lib/dracut/modules.d/50plymouth), provides support for boot animations (it requires the “plymouth” package to be installed).



Dracut basic usage

In its most basic usage, we can invoke dracut without any option or argument. When used this way, the program tries to generate the initramfs for the kernel which is currently in use by the system using the following name pattern:

/boot/initramfs-<kernel-version>

The kernel version can be easily obtained by using the uname utility with the -r option (short for --kernel-release). We can therefore guess the name which will be used for the initramfs running the following command:

$ echo "/boot/initramfs-$(uname -r)"

If an initramfs with the same name of the one which would be generated by dracut already exists, the application will refuse to overwrite it, displaying an error similar to the following:

dracut: Will not override existing initramfs (/boot/initramfs-5.14.14-300.fc35.x86_64.img) without --force

As suggested in the message itself, in order to override an existing initramfs we have to run dracut with the --force option.

Building an initramfs for a specific kernel version

The easiest way to build an initramfs for a specific kernel version is to invoke dracut with the --kver option, and provide the kernel version the initramfs should be built for as argument:

$ sudo dracut --kver 5.14.14-300.fc35.x86_64

The initramfs will be built inside the /boot directory, using the naming pattern we saw above. If we want to build an initramfs for a specific kernel version in a custom location, we can invoke dracut with the path where the image should be created as first argument, and pass the kernel version as the second one. Just as an example, to generate an initramfs image named after the currently running kernel explicitly, in the current working directory, we would run:

$ sudo dracut . 5.14.14-300.fc35.x86_64

The command above will generate an initramfs in the directory from which it is launched, named initramfs.img.

Building initramfs for all the existing kernels

Sometimes we may want to build or re-build the initramfs for all the existing kernels on our operating system. Dracut provides a very easy way to accomplish this task. All we have to do, is to run the application and use the --regenerate-all option. The initramfs archives will be created in the default directory. As said before, if the initramfs for a specific kernel already exists, we need to pass also the --force option:

$ sudo dracut --regenerate-all --force

Creating an host-tailored initramfs



Normally, when we generate an initramfs with dracut, a generic host configuration is created. Inside the initramfs everything that could be needed to boot a generic machine is included, to ensure the maximum possible compatibility. If we want only what is actually needed for a specific machine to be put inside the initramfs, we can run dracut with the -H option (short for --hostonly). To rebuild an host-tailored initramfs for the current running kernel, we would execute this simple command:
$ sudo dracut -H --force

Listing the files contained in the initrams and get their content

In a previous tutorial we saw how we can inspect the content of an initramfs on Linux. In few words, the recommended method to perform the action on Fedora, and generally on the distributions that are part of the Red Hat family, and use dracut, is to use the lsinitrd script, passing the path of the initramfs we want to examine as argument. To inspect the content of the /boot/initramfs-5.14.14-300.fc35.x86_64.img initramfs, for example, we would run:

$ sudo lsinitrd /boot/initramfs-5.14.14-300.fc35.x86_64.img

The command above, among the other things, produces a list of the files contained in the initramfs. To inspect the content of a file we can use the -f option of lsinitrd and pass the path of the file inside the initramfs as argument. Just as an example, to read the content of the etc/crypttab file which is included in the initramfs, we would run:

$ sudo lsinitrd /boot/initramfs-5.14.14-300.fc35.x86_64.img -f etc/crypttab

Including extra files in the initramfs with the –include option

Sometimes we may want to include extra files inside the initramfs. There are basically two options we can use to perform this operation: --include and --install; let’s see how they work.

Including files using –include

The --include option takes two arguments, in order:

  1. The path of the file to be included in the initramfs (source)
  2. The path the file should have inside the initramfs (destination)

Suppose we want to rebuild the initramfs for the currently running kernel, and we want to include the /custom-content.conf file as /etc/custom-content.conf inside of it. We would run:

$ sudo dracut --include /custom-content.conf /etc/custom-content.conf --force

Using the --include option we can also include the content of a directory inside the initramfs. Supposing we have the /foo directory and we want to include its content under the / directory inside the initramfs. We would run:

$ sudo dracut --include /foo / --force

Only the content of the directory will be copied inside the initramfs, and not the directory itself.

Installing files with the –install option

The --install option can also be used to include files inside the initramfs. The main difference with --include is that files are installed inside the initramfs in the same location they have in the system. When using the option, we provide the list of the files which should be included as argument; multiple files should be specified among quotes, space-separated. To regenerate the initramfs for the current running kernel and install the /custom-content.conf and /custom-content0.conf files, for example, we would run:

$ sudo dracut --install "/custom-content.conf /custom-content0.conf" --force



The files to be included must exist on the source filesystem, otherwise an error will be generated. If we are not sure if a file exists or not, we can use --install-optional, instead: files will be included only if they exist.

Controlling the initramfs compression

By default the cpio archive containing the initramfs files is compressed using gzip. We can, however, decide to use an alternative compression methods or no compression at all. We can configure this parameter using the appropriate command line options. Their are named after the algorithm which is used for the compression. Among the others:

  • –no-compress (Initramfs is not compressed)
  • –gzip
  • –bzip2
  • –lzma
  • –xz
  • –lzo
  • –lz4

Dracut configuration file

Until now we saw how to configure many aspects of the initramfs generation using dracut command line options. As an alternative, we can modify dracut behavior by using its configuration file. Before talking about some of the configurations we can setup, it is important to understand how configuration files are processed. In priority order:

  1. Runtime options
  2. Configuration files ending in “.conf” in /etc/dracut.conf.d
  3. Configuration files ending in “.conf” in /usr/lib/dracut/dracut.conf.d
  4. Configurations in /etc/dracut.conf

Command line options always override what is stated in configuration files. The main dracut configuration file is /etc/dracut.conf, but setup can be made modular using dedicated configuration files ending with the .conf suffix, which can be placed in the /usr/lib/dracut/dracut.conf.d (usually “vendor” configurations) and /etc/dracut.conf.d directories. The configuration files in the latter directory replaces those with the same name in the former. Files with the .conf suffix are processed in alphanumerical order. Directives existing in those files override those specified in /etc/dracut.conf file. For the complete list of the instructions which can be used in configuration files, please consult the manual page by running:

$ man dracut.conf

Here we report only few examples:

Configuration Explanation
dracutmodules+=”<dracut modules>” Space separated list of the modules which should be used for the initramfs
add_dracutmodules+=”<dracut modules>” Space separated list of additional modules which should be used for the initramfs
install_items+= “<file>[ <file> …]” Space separated list of files which should be installed in the initramfs
compress=”{cat|bzip2|lzma|xz|gzip|lzo|lz4|zstd|<compressor [args …]>}” Specify the compression method
hostonly=”{yes|no}” Specify whether only what is needed for the host should be included in the initramfs

Conclusions

In this tutorial we talked about dracut, the tool used build initramfs on many Linux distributions, mainly on those which are part of the Red Hat family. We saw the dracut basics, how to build an initramfs for a specific kernel version and for all the kernels installed on the system, how to build an host-tailored initramfs, how to list files inside the initramfs and how to include extra files. We also saw how to change the initramfs compression method and, finally, how to use dracut configuration files.



Comments and Discussions
Linux Forum