Ram disks are used very often to hold the root file system of embedded systems. They have several advantages:
- well-known
- well-supported by the Linux kernel
- simple to build
- simple to use - you can even combine the ramdisk
with the Linux kernel into a single image file
- RAM based, thus pretty fast
- writable file system
- original state of file system after each reboot = easy
recovery from accidental or malicious data corruption etc.
On the other hand, there are several disadvantages, too:
- big memory footprint:
you always have to load the complete filesystem into RAM,
even if only small parts of are actually used
- slow boot time: you have to load (and uncompress) the whole
image before the first application process can start
- only the whole image can be replaced (not individual files)
- additional storage needed for writable persistent data
Actually there are only very few situations where a ramdisk image is the
optimal solution. But because they are so easy to build and use we will discuss them here anyway.
In almost all cases you will use an
ext2
file system in your ramdisk
image. The following steps are needed to create it:
- Create a directory tree with the content of the target root filesystem.
We do this by unpacking our master tarball:
$ mkdir rootfs
$ cd rootfs
$ tar zxf /tmp/rootfs.tar.gz
- We use the
genext2fs
tool to create the ramdisk image
as this allows to use a simple
text file to describe which devices shall be created in the
generated file system image.
That means that no root
permissions are required at all.
We use the following device table
rootfs_devices.tab
:
#<name> <type> <mode> <uid> <gid> <major> <minor> <start> <inc> <count>
/dev d 755 0 0 - - - - -
/dev/console c 640 0 0 5 1 - - -
/dev/fb0 c 640 0 0 29 0 - - -
/dev/full c 640 0 0 1 7 - - -
/dev/hda b 640 0 0 3 0 - - -
/dev/hda b 640 0 0 3 1 1 1 16
/dev/kmem c 640 0 0 1 2 - - -
/dev/mem c 640 0 0 1 1 - - -
/dev/mtd c 640 0 0 90 0 0 2 16
/dev/mtdblock b 640 0 0 31 0 0 1 16
/dev/mtdr c 640 0 0 90 1 0 2 16
/dev/nftla b 640 0 0 93 0 - - -
/dev/nftla b 640 0 0 93 1 1 1 8
/dev/nftlb b 640 0 0 93 16 - - -
/dev/nftlb b 640 0 0 93 17 1 1 8
/dev/null c 640 0 0 1 3 - - -
/dev/ptyp c 640 0 0 2 0 0 1 10
/dev/ptypa c 640 0 0 2 10 - - -
/dev/ptypb c 640 0 0 2 11 - - -
/dev/ptypc c 640 0 0 2 12 - - -
/dev/ptypd c 640 0 0 2 13 - - -
/dev/ptype c 640 0 0 2 14 - - -
/dev/ptypf c 640 0 0 2 15 - - -
/dev/ram b 640 0 0 1 0 0 1 2
/dev/ram b 640 0 0 1 1 - - -
/dev/rtc c 640 0 0 10 135 - - -
/dev/tty c 640 0 0 4 0 0 1 4
/dev/tty c 640 0 0 5 0 - - -
/dev/ttyS c 640 0 0 4 64 0 1 8
/dev/ttyp c 640 0 0 3 0 0 1 10
/dev/ttypa c 640 0 0 3 10 - - -
/dev/ttypb c 640 0 0 3 11 - - -
/dev/ttypc c 640 0 0 3 12 - - -
/dev/ttypd c 640 0 0 3 13 - - -
/dev/ttype c 640 0 0 3 14 - - -
/dev/ttypf c 640 0 0 3 15 - - -
/dev/zero c 640 0 0 1 5 - - -
A description of the format of this table is part of
the manual page for the genext2fs
tool, genext2fs(8).
- We can now create an
ext2
file system image using the
genext2fs
tool:
$ ROOTFS_DIR=rootfs # directory with root file system content
$ ROOTFS_SIZE=3700 # size of file system image
$ ROOTFS_FREE=100 # free space wanted
$ ROOTFS_INODES=380 # number of inodes
$ ROOTFS_DEVICES=rootfs_devices.tab # device description file
$ ROOTFS_IMAGE=ramdisk.img # generated file system image
$ genext2fs -U \
-d ${ROOTFS_DIR} \
-D ${ROOTFS_DEVICES} \
-b ${ROOTFS_SIZE} \
-r ${ROOTFS_FREE} \
-i ${ROOTFS_INODES} \
${ROOTFS_IMAGE}
- Compress the file system image:
$ gzip -v9 ramdisk.img
rootfs.img: 55.6% -- replaced with ramdisk.img.gz
- Create an U-Boot image file from it:
$ mkimage -T ramdisk -C gzip -n 'Test Ramdisk Image' \
> -d ramdisk.img.gz uRamdisk
Image Name: Test Ramdisk Image
Created: Sun Jun 12 16:58:06 2005
Image Type: PowerPC Linux RAMDisk Image (gzip compressed)
Data Size: 1618547 Bytes = 1580.61 kB = 1.54 MB
Load Address: 0x00000000
Entry Point: 0x00000000
We now have a root file system image
uRamdisk
that can be
used with U-Boot.