Friday, April 24, 2015

Modify the initial ramfs (initramfs) archive

1 Introduction

Just a tiny note about modifying the initrd image on Debian, Unbuntu, or other Linux distributions. For glossaries about initial RAM disk, initial RAM filesystem, Root filesystem, etc, please reference the links listed in the end of the article.

2 Examing the initramfs Contents

I've noticed an error message on my Debian Jessie during boot:

/init: 401: /init: touch: not found

Mike also posts a similar issue to Debian user mailing list.

This can typically fixed by update-initramfs:

update-initramfs -u -k <version>

But it doesn't work for me this time. So i am forced to fix it manually.

Firstly, decompress the ramfs.

mkdir /tmp/initrd
cd /tmp/initrd
zcat /boot/initrd.img-3.9-1-amd64 | cpio -id

For multi-segment initramfs which actually is the concatenation of two images:

  • cpio archive, containing microcode per processor of your system
  • gzip compressed cpio archive, containing the initrd file tree

cpio can only extract the first part.

% cpio -id < /boot/initrd.img-3.16.0-4-amd64
22 blocks

You can get the actual initrd by command followed:

dd if=/boot/initrd.im\
g-3.16.0-4-amd64 of=myInitrd.img.gz bs=512 skip=22    

After examing it, the root cause is found at scripts/function _checkfs_once(). The init script wanna touch a stamp file, to notify the init system that initramfs has already run fsck. Since 'touch' is not provided in the ramfs, the script fails there.

touch $FSCK_STAMPFILE

Modify the line to the followed will fix the issue:

echo > $FSCK_STAMPFILE

3 Re-generate the intiramfs and Test

Then, update the ramfs with modified scripts.

cd /tmp/initrd
find . | cpio --create --format='newc' > /tmp/wfinitrd
gzip wfinitrd
sodu mv wfinitrd.gz /boot/wfinitrd.img
sodu reboot

Because we have chance not able to boot the system normally, it is recommended to test before switching to new ramfs. We do it by interactively from the grub menu - "e" to edit the followed line:

initrd  /boot/initrd.img-3.9-1-amd64

into the followed:

initrd  /boot/wfinitrd.img

And "b" to boot after done editing.

If everything works as expected, we're good to go.

mv /boot/initrd.img-3.9-1-amd64 /boot/bak-initrd
mv wfinitrd.img /boot/initrd.img-3.9-1-amd64
sudo reboot

Date: 2015-04-24 Fri

Author: Winfred Lu

Created: 2015-04-24 Fri 20:34

Emacs 24.4.1 (Org mode 8.2.10)

Validate

1 comment:

Anonymous said...

Just came along the same issue with /bin/touch missing in initrd: All I was missing is fsprotect [1] which for some reason is not a dependency or recommendation of initramfs-tools

[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=628796