CNT5605 - 2016
Assignment 4

Assignment: Working with initrd


The objective is to modify your current initrd to replace existing functionality. In this case, we are replacing your initrd's "true" and "false" programs, written in C, with assembly language versions. The original C compilations contain a hard-coded interpreter that's not necessary and likely not desirable:

In this exercise, we will replace these two binaries with assembly language versions that do not have such an interpreter dependency.


The first step is to edit your grub defaults, /etc/default/grub, so that you have a bit more time to react; I suggest changing your timeout to 10 (or more) seconds:

After you do this, you will need to run update-grub to update the actual configuration file.

Now reboot, and hit "e" to edit. Add "break=premount" after the "ro" bit on the boot command line, to force the kernel to stop before it mounts any file systems, and thus you leaving in the initial RAM filesystem rather than your ordinary root filesystem, and then do a CTRL-X or hit F10 to continue the boot process.

Once you have booted to the "(initramfs)" prompt, do a "cd" into /bin.

Do an "ls -li" of "true" and "false" and then a "file" of each:

Note that these are currently some 600 bytes each, and they use an interpreter listed by the "file".

Now do an "exit", and let your system boot up normally.

Become root. Create a subdirectory something like "initrd-new"; I used "/root/initrd-new", but you can use "/tmp" if you like (but if you use /tmp and then have to redo anything, then you will have to redo everything since the contents of "/tmp" disappears on each reboot.)

Now you can do "cd initrd-new && zcat < /boot/initrd-SOMEVERS | cpio -i -d" to extract your current initrd to your subdirectory.

Now it's time to work with the substitute true and false code.

Change directory to somewhere that you can assemble your new code (i.e., do not do the assembly in your initrd-new/ directory), and then pull the source code for "true" and "false" in with wget:

(Or feel free to write your own assembly, if you don't like mine. ;-)

Now you will need "yasm", so install it:

Now assemble, link, and strip your binaries:

Once you have new "true" and "false" binaries (they should each be around 360 bytes in size), copy them over the versions in "initrd-new/bin". (This is critical, by the way — if you don't put the new copies into the initrd-new/ subdirectory, then they won't be there when you reboot using your initrd-new.)

Now create a new gzipped initrd with your new binaries, using "cpio" with both "-o" and "--format='newc'" (the man page for cpio's various format is here) and piping to gzip:

Copy the old version of initrd in the /boot subdirectory to an "ORIG" file, and then install your new version over the previous one in /boot:

And now reboot, again specifying "break=premount". Change directory into "/bin", and, voila, you should see your shiny new "true" and "false" programs, each at 360 bytes and statically linked with no pesky interpreter interposed:

A written journal is due for this assignment. Please turn in your journal at the beginning of class on June 10, 2016; no late journals will be accepted.