2 ways to update and rebuild initrd image in CentOS/RHEL 7 and 8

How do I unpack or uncompress, and then repack or re-compress, an initrd or initramfs boot image file? How do I modify the contents of an initrd or initramfs? How do I view an initrd or initramfs? How to customize initrd in RHEL Linux. How to rebuild initrd image in RHEL 8 Linux. How to update initrd in RHEL 7 Linux. How to update initrd with XV compressed data. How to rebuild initrd image with LZMA compressed data. How to rebuild the initial ramdisk image in Red Hat Enterprise Linux. How to rebuild initial ram disk image in Red Hat Enterprise Linux. How to remake or recreate the initrd or initramfs.

What is initrd?
The initial RAM disk (initrd) is an initial root file system that is mounted prior to when the real root file system is available. The initrd is bound to the kernel and loaded as part of the kernel boot procedure. The kernel then mounts this initrd as part of the two-stage boot process to load the modules to make the real file systems available and get at the real root file system.
The initrd file contains a minimal set of directories and executables to achieve this, such as the insmod tool to install kernel modules into the kernel. In other words, it contains the necessary executables and system files to support the second-stage boot of a Linux system.
The initrd image is present under /boot directory and is owned by kernel package.
The version of the running kernel on the system will be used to identify the current initrd image used during booting process.
HINT:
There are two initrd image available with RHEL 7. The one which is created after kernel is installed on the root file system i.e. available inside /boot/initramfs-$(uname -r).img while the other one is available inside the RHEL ISO DVD which is loaded at the initial stage of system boot up. In this article we study about the steps to update and rebuild initrd available in the RHEL ISO DVD, to learn about the steps to extract and rebuild initramfs from the system you can follow this article.

Why should I update initrd?
Initrd contains many drivers for third party vendors along with many modules and executables which help OS detect the underlying hardware. It is possible that on a new hardware the initrd fails to detect the underlying hardware part such as Network Card, Storage Adapter etc. In such situations we can modify the initrd image.

Although instead of adding driver modules from third party vendor into initrd, I would recommend creating a custom DUD (Driver Update Disk) as it also performs the same task and is a better alternative rather than updating and rebuilding initrd.

NOTE:
Modifying initrd in production environment is not recommended, if you have a valid subscription then you should get in touch with your support team to handle any issue which requires initrd modification.
Rather than modifying the initrd image, you can also opt to create an updates.img file which is called at a later stage of the BOOT UP. But if your problem is related to detection failure of underlying hardware then updates.img will not help.

Which one to choose initrd.img vs updates.img?
anaconda has the capability to incorporate updates at runtime to fix any bugs or issues with the installer. These updates are generally distributed as a disk image file (referred to as updates.img in this article).

So we have two options with us to alter the boot up process with our customized changes, one with initrd and the other with updates.img

The answer to this question depends on your requirement. updates.img is called at a later stage of the boot up procedure so if you wish to include important modules to detect hardware then you should update and rebuild initrd while if you need to add some bug fixes for the RHEL OS then you can go ahead with updates.img

Check initrd content
Before we update initrd, it is a good idea to verify the existing content of our initrd image. Here I am checking the content of initrd from the RHEL 8 ISO image.

[root@rhel-8 ~]# lsinitrd /mnt/images/pxeboot/initrd.img | less
Image: /mnt/images/pxeboot/initrd.img: 58M

Version: dracut-049-10.git20190115.el8

Arguments: --nomdadmconf --nolvmconf --xz --install ‘/.buildstamp’ --no-early-microcode --add ‘fips’ --add ‘anaconda pollcdrom qemu qemu-net prefixdevname-tools’ --force

dracut modules:
bash
systemd
fips
systemd-initrd
modsign
nss-softokn
i18n
convertfs
network-legacy
network
ifcfg
url-lib
drm
plymouth

drwxr-xr-x 2 root root 0 Jan 15 2019 var/lib/nfs/rpc_pipefs
drwxrwxr-x 3 root root 0 Jan 15 2019 var/lib/nfs/statd
drwxr-xr-x 2 root root 0 Jan 15 2019 var/lib/nfs/statd/sm
drwxrwx— 2 root root 0 Jan 15 2019 var/lib/rpcbind
lrwxrwxrwx 1 root root 11 Jan 15 2019 var/lock -> …/run/lock
lrwxrwxrwx 1 root root 6 Jan 15 2019 var/run -> …/run
drwxr-xr-x 2 root root 0 Jan 15 2019 var/tmp

Here in this list you can look for the content of initrd image file.

ALSO READ:
How to extract/uncompress and rebuild initramfs for RHEL 6 and 7 with examples

Method 1: Extract initrd image
Based on the initrd file compression type the command to extract and rebuild initrd will vary. For our case in both RHEL 7 and 8 we have XZ compressed data in initrd file as shown below:

[root@rhel-8 ~]# file /mnt/images/pxeboot/initrd.img
/mnt/images/pxeboot/initrd.img: XZ compressed data

[root@rhel-8 ~]# cat /etc/redhat-release
Red Hat Enterprise Linux release 8.0 (Ootpa)
[root@rhel-7 ~]# file /mnt/images/pxeboot/initrd.img
/mnt/images/pxeboot/initrd.img: XZ compressed data

[root@rhel-7 ~]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.6 (Maipo)
So we can use the same method to extract and rebuild initrd for both RHEL 7 and 8 Linux.

IMPORTANT NOTE:
Before you extract initrd make sure you take a backup of your initrd file or you can extract at a different location without touching the original file.
We will create a temporary directory where we will extract and update initrd

[root@rhel-8 custom_initrd]# mkdir /tmp/custom_initrd
To extract initrd use the below command:

[root@rhel-8 custom_initrd]# xz -dc < /mnt/images/pxeboot/initrd.img | cpio -idmv
This will extract all the content of initrd in the current directory

[root@rhel-8 custom_initrd]# ls -l
total 44
lrwxrwxrwx. 1 root root 7 Sep 13 19:44 bin -> usr/bin
drwxr-xr-x. 2 root root 4096 Sep 13 19:44 dev
drwxr-xr-x. 14 root root 4096 Sep 13 19:44 etc
lrwxrwxrwx. 1 root root 23 Sep 13 19:44 init -> usr/lib/systemd/systemd
lrwxrwxrwx. 1 root root 7 Sep 13 19:44 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Sep 13 19:44 lib64 -> usr/lib64
drwxr-xr-x. 2 root root 4096 Jan 15 2019 proc
drwxr-xr-x. 2 root root 4096 Jan 15 2019 root
drwxr-xr-x. 2 root root 4096 Jan 15 2019 run
lrwxrwxrwx. 1 root root 8 Sep 13 19:44 sbin -> usr/sbin
-rwxr-xr-x. 1 root root 3126 Oct 8 2018 shutdown
drwxr-xr-x. 2 root root 4096 Jan 15 2019 sys
drwxr-xr-x. 2 root root 4096 Jan 15 2019 sysroot
drwxrwxr-x. 2 root root 4096 Jan 15 2019 tmp
drwxrwxr-x. 9 root root 4096 Sep 13 19:44 usr
drwxr-xr-x. 4 root root 4096 Sep 13 19:44 var

Method 2: Extract initrd image
Alternatively you can also extract the initrd using the below list of steps. To start with copy the initrd file from the RHEL 7/8 ISO DVD to a temporary directory

[root@rhel-8 custom_initrd]# cp /mnt/isolinux/initrd.img /tmp/custom_initrd/
Verify the file

[root@rhel-8 custom_initrd]# ls -lh
total 58M
-r–r--r–. 1 root root 58M Sep 13 22:03 initrd.img
Now extract the file

[root@rhel-8 custom_initrd]# unxz -S .img initrd.img
With this the initrd.img will extract and create an initrd file

[root@rhel-8 custom_initrd]# ls -lh
total 171M
-r–r--r–. 1 root root 185M Sep 13 22:03 initrd
Extract the content of this initrd in the current directory

[root@rhel-8 custom_initrd]# cat initrd | cpio -idm
cpio: .buildstamp not created: newer or same age version exists
378442 blocks
Verify the content of the initrd

[root@rhel-8 custom_initrd]# ls -lh
total 171M
lrwxrwxrwx. 1 root root 7 Sep 13 22:07 bin -> usr/bin
drwxr-xr-x. 2 root root 4.0K Sep 13 22:07 dev
drwxr-xr-x. 14 root root 4.0K Sep 13 22:07 etc
lrwxrwxrwx. 1 root root 23 Sep 13 22:07 init -> usr/lib/systemd/systemd
-r–r--r–. 1 root root 185M Sep 13 22:03 initrd
lrwxrwxrwx. 1 root root 7 Sep 13 22:07 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Sep 13 22:07 lib64 -> usr/lib64
drwxr-xr-x. 2 root root 4.0K Jan 15 2019 proc
drwxr-xr-x. 2 root root 4.0K Jan 15 2019 root
drwxr-xr-x. 2 root root 4.0K Jan 15 2019 run
lrwxrwxrwx. 1 root root 8 Sep 13 22:07 sbin -> usr/sbin
-rwxr-xr-x. 1 root root 3.1K Oct 8 2018 shutdown
drwxr-xr-x. 2 root root 4.0K Jan 15 2019 sys
drwxr-xr-x. 2 root root 4.0K Jan 15 2019 sysroot
drwxrwxr-x. 2 root root 4.0K Jan 15 2019 tmp
drwxrwxr-x. 9 root root 4.0K Sep 13 22:07 usr
drwxr-xr-x. 4 root root 4.0K Sep 13 22:07 var

Update initrd image
Now since we have successfully extracted initrd, you can go ahead and do your modification. For example you can add new driver modules from the vendor to support some new hardware or any other custom change.

IMPORTANT NOTE:
Do not change the directory structure of the initrd image
For the sake of this article I wish to add a udev rule file to my initrd to detect and map the NIC cards with pre-defined PCI ID

cat 20-persistent-net.rules

SUBSYSTEM==“net”, ACTION==“add”, DRIVERS=="?", BUS==“pci”, ID==“0000:01:00.0”, ATTR{dev_id}“0x0”, ATTR{type}“1”, KERNEL=="eth", NAME=“eth0”
SUBSYSTEM==“net”, ACTION==“add”, DRIVERS=="?", BUS==“pci”, ID==“0000:01:00.1”, ATTR{dev_id}“0x0”, ATTR{type}“1”, KERNEL=="eth", NAME=“eth1”
SUBSYSTEM==“net”, ACTION==“add”, DRIVERS=="?", BUS==“pci”, ID==“0000:03:00.0”, ATTR{dev_id}“0x0”, ATTR{type}“1”, KERNEL=="eth", NAME=“eth2”
SUBSYSTEM==“net”, ACTION==“add”, DRIVERS=="?", BUS==“pci”, ID==“0000:03:00.1”, ATTR{dev_id}“0x0”, ATTR{type}“1”, KERNEL=="eth", NAME=“eth3”
SUBSYSTEM==“net”, ACTION==“add”, DRIVERS=="?", BUS==“pci”, ID==“0000:04:00.0”, ATTR{dev_id}“0x0”, ATTR{type}“1”, KERNEL=="eth", NAME=“eth4”
SUBSYSTEM==“net”, ACTION==“add”, DRIVERS=="?", BUS==“pci”, ID==“0000:04:00.1”, ATTR{dev_id}“0x0”, ATTR{type}“1”, KERNEL=="eth", NAME=“eth5”
We will add this in our initrd under /usr/lib/udev/rules.d

[root@rhel-8 rules.d]# ls -l
total 124
-r–r--r–. 1 root root 7266 Jan 15 2019 10-dm.rules
-r–r--r–. 1 root root 2454 Jan 15 2019 11-dm-lvm.rules
-rw-r–r--. 1 root root 4538 Jan 15 2019 11-dm-mpath.rules
-r–r--r–. 1 root root 1794 Jan 15 2019 13-dm-disk.rules
-rw-r–r--. 1 root root 876 Sep 13 20:13 20-persistent-net.rules
-rw-r–r--. 1 root root 1622 Jan 15 2019 40-redhat.rules
-rw-r–r--. 1 root root 3679 Jan 15 2019 50-udev-default.rules

Method 1: Rebuild initrd image
If you extract initrd using Method 1 then follow this procedure to rebuild initrd image, navigate to your temporary directory where you did extract initrd image.

[root@rhel-8 rules.d]# cd /tmp/custom_initrd/

[root@rhel-8 custom_initrd]#
Execute the below command to rebuild initrd image with xz as compression format

[root@rhel-8 custom_initrd]# find . 2>/dev/null | cpio -c -o | xz -9 --format=xz > /tmp/new.img
378439 blocks
Check the compression type of your new initrd file

[root@rhel-8 custom_initrd]# ls -l /tmp/new.img
-rw-r–r--. 1 root root 53615972 Sep 13 20:24 /tmp/new.img

[root@rhel-8 custom_initrd]# file /tmp/new.img
/tmp/new.img: XZ compressed data

Method 2: Rebuild initrd image
If you perform extract initrd using Method 2 then follow this procedure to rebuild initrd image, navigate to your temporary directory where you did extract initrd image.

Remove the initrd file which was already extracted is in the same directory.

[root@rhel-8 custom_initrd]# rm -f initrd
Next rebuild initrd image using the below command:

[root@rhel-8 custom_initrd]# find . | cpio -oc > …/initrd; cd …; xz -S .img initrd
378442 blocks
Verify the new initrd image

[root@rhel-8 tmp]# ls -lh initrd.img
-rw-r–r--. 1 root root 53M Sep 13 22:15 initrd.img

Verify initrd image
Now since we successfully rebuild initrd image, let us verify the content of our new initrd and make sure our new rule file is present in this initrd image

[root@rhel-8 custom_initrd]# lsinitrd /tmp/new.img | grep 20-persistent-net.rules
-rw-r–r-- 1 root root 876 Sep 13 20:13 usr/lib/udev/rules.d/20-persistent-net.rules
So as you see our file is now part of the initrd file. So now you can use this initrd file to boot up your system.

Similarly you can verify the content of initrd which you create using the Method 2.

Lastly I hope the steps from the article to update and rebuild initrd image in CentOS/RHEL 7 and 8 Linux was helpful. So, let me know your suggestions and feedback using the comment section.

References:
How to extract and repackage the anaconda installation initrd.img from Red Hat Enterprise Linux 7 DVD iso media?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值