To boot Linux, you only need two things:
- The Linux kernel itself, and
- A root filesystem with an
init
program of some sort.
As any book about embedded Linux will tell you, the init
process will typically configure devices, launch other programs and generally set up what you think of as the Linux environment.
Many O/S distributions, including Android, use a small RAM disk as the initial root filesystem and the init
program will enumerate the devices and typically mount other filesystems.
In previous kernel versions, the RAM disks were typically ext2
filesystems, but the current convention is to use the initramfs
file format, which is essentially a cpio
archive.
To speed the boot, the cpio
archive is typically gzip
ped and when used with the U-Boot boot loader, wrapped with a U-Boot header containing a CRC by the mkimage
tool.
In the course of working with an O/S that uses a RAM disk, you will often want to extract the content at least to examine it. You may also want to modify some of the contents and re-create it, but you can't do this directly.
In this post, I'll walk through the process of doing just that.
I'll use the file uramdisk.img
from the SD card tree of the images provided in the Freescale Android release R13.4-Beta release.
If you run file
on the image, you'll see it reported as a PPC/U-Boot
image file:
~/$ file uramdisk.img
uramdisk.img: u-boot/PPCBoot image
That's because mkimage
adds 64 bytes of header. We can use dd
to strip it like so: ~$ dd bs=1 skip=64 if=uramdisk.img of=uramdisk-no-header.img
167778+0 records in
167778+0 records out
167778 bytes (168 kB) copied, 0.91557 s, 183 kB/s
~$ ls -l uramdisk*
-rw-r--r-- 1 ericn ericn 167842 2012-09-07 12:21 uramdisk.img
-rw-r--r-- 1 ericn gitosis 167778 2012-09-07 12:25 uramdisk-no-header.img
~$ file uramdisk-no-header.img
uramdisk-no-header.img: gzip compressed data, from Unix
As you can see, after stripping the 64-byte header, file
identifies the image as a gzip
ped data.If we unzip it, we'll see that it's a
cpio
archive and we can list its content: ~$ zcat uramdisk-no-header.img > uramdisk-uncompressed.img
~$ file uramdisk-uncompressed.img
uramdisk-uncompressed.img: ASCII cpio archive (SVR4 with no CRC)
~$ cpio -t
You can extract them like so:
~$ mkdir myramdisk
bash: ../uramdisk-uncompressed.img: No such file or directory
~$ cd myramdisk/
~/myramdisk$ sudo cpio -i --no-absolute-filenames
Note the use of sudo
above. You'll generally want to do that in order to preserve root
ownership.
Also note that I tail
ed the file default.prop
, which is a file you might want to hack in an Android image. In particular, ro.secure
and ro.debuggable
are two properties that you might want to set differently when you're working with an Android image.
If you edit that file, you can re-create the RAM disk using these steps:
~/myramdisk$ shopt -s dotglob
~/myramdisk$ sudo find . | sudo cpio -H newc -o | gzip > ../uramdisk.cpio.gz
551 blocks
~/myramdisk$ mkimage -A arm -O linux -T ramdisk -n "Initial Ram Disk"
-d ../uramdisk.cpio.gz ../uramdisk.img.new
Image Name: Initial Ram Disk
Created: Fri Sep 7 12:47:00 2012
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 169051 Bytes = 165.09 kB = 0.16 MB
Load Address: 0x00000000
Entry Point: 0x00000000
The second command-line above is a little hairy, with a four-stage pipeline that lists all files (including those beginning with dot because of the preceding shopt
) and hands them off to cpio
. Note that the -H newc
is needed for historical reasons. Since cpio
sends its output to stdout
, we pipe that to gzip
and the gzipped output to a new file named uramdisk.cpio.gz
.
The last command is the mkimage
U-Boot tool, which adds the 64-byte U-Boot header back onto the output.
I hoped this quick note helps you understand the basics of a RAM disk. We'll likely make use of this in future posts, and want it around for reference.