Initramfs and dracut

an open wristwatch, showing it's cogs and wheels

In order to keeps blog posts small and easy to read, I sometimes skip up some details. In the series on my shenanigans with CPU vulnerabilites and the Intel microcode, I did not specify how I handled the initramfs side of things. This post will double as a cheat-sheet for next time I need to move a system disk from a computer to another.

What's the initramfs, anyway ?

Well, Wikipedia really explains it well, so instead of badly paraphrasing it, I'll just quote thes lines from the Initial ramdisk page :

In Linux systems, initrd (initial ramdisk) is a scheme for loading a temporary root file system into memory, to be used as part of the Linux startup process. initrd and initramfs refer to two different methods of achieving this. Both are commonly used to make preparations before the real root file system can be mounted.

The initramfs and the Intel microcode

Why do I care about the initramfs for the Intel microcode ? The reason is, as stated in its article on loading the microcode from the OS, Intel explains that the microcode must be installed in the initramfs to be updated at startup.

The article then explains how to update the microcode for multiple distributions, especially for Fedora and Ubuntu. On the Fedora side, the article make use of the following command (as root) :

dracut -f -vvv

In the dracut manual page, we can learn :

  • -f or --force overwrite the existing initramfs file ;
  • -vvv increases verbosity (a lot).

Looking at the content of the initramfs file can be done with two ways. The first one is by uncompressing the file, which is simply a CPIO archive, sometimes compressed. For example (as root) :

mkdir /tmp/initramfs
cp /boot/initramfs-$(uname -r).img /tmp/initramfs/
cd /tmp/initramfs
mv initramfs-$(uname -r).img{,.gz}
gunzip initramfs-$(uname -r).img.gz
cpio -idv < initramfs-$(uname -r).img

If your initramfs is not compressed, you can skip the mv/gunzip part, or adapt it if this using another compression algorithm.

Now the initramfs is unarchived in /tmp/initramfs, and its content can be analyzed.

If no "thorough analysis" is required, the lsinitrd (available in the dracut package in Fedora) command can be run as root. Not only does it show the content of the initramfs with owner/group, mode and size, but it also displays the arguments and modules used in the dracut command for generating it.

generic and host-only initramfs

One neat trick I used once in dracut is the ability to generate generic or host-only initramfs. What's the difference ? In the first case, the generic initramfs can be used on multiple computers with different hardware because it contains all the modules that were compiled for the associated Linux kernel. The initramfs is therefore quite big on the filesystem. On the other hand, the host-only initramfs will only keep the modules corresponding to detected hardware, which is slimmer, but less portable. There are even two modes, depending on how strict you want to be.

Some examples :

  • dracut -f --no-hostonly will generate a generic initramfs for the running kernel ;
  • dracut -f --host-only will generate a host-only initramfs for the running kernel ; without further information, the "sloppy" mode is used ;
  • dracut -f --hostonly-mode=strict will, this time, be very strict on what's added to the initramfs and can make the system unbootable for minor hardware changes.

The generic mode is really useful and I used it in two use-cases :

  • I replaced the CPU and motherboard in my main desktop PC (therefore replacing a lot of components, including the storage controller);
  • I added a HBA in a server, which was faster than the integrated SATA ports, so I wanted to move my system SSD to it.

If you want to read more on dract and Fedora, have a look at InitRAMFS, Dracut, and the Dracut Emergency Shell from Fedora Magazine.

I hope you enjoyed this post ! If you did, please share it on your favorite social networks :-)

Photo by Lukas Tennie on Unsplash.