File System Embedded Linux
File System Embedded Linux
Admin
Storage trade-off
The challenge with every embedded system is the limited physical resources available, especially storage space. Unlike the desktop, which has common storage ranging into gigabytes, a typical embedded system may not have this luxury. Hard drives being costly, bulky, sensitive to physical shocks and with higher power requirements are unsuitable for most embedded systems. In many such systems, the hard drive is replaced by smaller and less expensive nonvolatile storage devices such as Flash memory. Even though a typical embedded system nowadays can be with 4 MB to 256 MB of storage, systems with as little as 1 MB or 2 MB of storage capacity are not uncommon. This storage can be a volatile (runtime) memory or non-volatile (persistent) memory, depending on the device requirements. A majority of modern devices comfortably rely on Flash memory for non-volatile storage. Alternately, if a device holds an abundant amount of RAM, it can use RAM to store all of its frequent data, and designers can completely ignore or keep small amounts of permanent storage for critical data, if any.
12
NOVEMBER 2007
www.linuxforu.com
CMYK
Admin
Why a filesystem?
The embedded devices definitely need a way to store and retrieve information in a structured format; this is where the filesystem comes in. When implementing a Linux operating system on such devices, the critical issue of how to create a filesystem without a hard drive arises. The Linux kernel works hand in hand with what is called the root filesystem that contains user-space applications and the environment in which they can run. The kernel boot process deals with two kinds of root filesystems the initial root filesystem and a real root filesystem. The initial root filesystem, also known as the initial ramdisk, is created by the kernel in RAM and is used to mount and run the main root filesystem. In embedded Linux the main root filesystem can reside in RAM or in Flash, solely depending on the exact system requirements. Considering this, Linux presents support for a number of different types of filesystems specially designed for the embedded purpose.
by embedded Linux can be separated into three classes: 1. Initial filesystems required at boot timeinitrd and initramfs 2. Network-based root filesystems such as NFS 3. Flash- or RAM-based root filesystems ramfs, romfs, cramfs, JFFS2
The kernel currently has three ways to mount the root filesystem: a) A few device and filesystem drivers are built as modules and stored in initrd. The initrd must contain a binary file named / linuxrc which will load these driver modules and return to kernel so that the kernel can mount the real root filesystem. b) Initramfs, which contains a binary file, is used. This binary is responsible for all the things a kernel would do and must be called /init. Once the kernel launches /init out of initramfs, the kernel is done with its job and further activity of mounting the real root filesystem is completed by the init program. c) All required device and filesystem drivers are compiled into the kernel itself. There is no initrd or initramfs, as such, and the kernel has to mount the final root filesystem on its own. In case of the desktop Linux, either initrd or initramfs is mandatory. But for embedded Linux, any method can be implemented. Most likely, the last method may be suitable for booting embedded systems. A range of filesystems supported
www.linuxforu.com
NOVEMBER 2007
13
CMYK
Admin
initramfs
In the v2.6 kernel, developers chose to implement a new mechanism in order to simplify the way initrd works while reducing the kernel boot time. This new implementation is called initramfs. The initrd was designed to assist the kernel in further booting such that the device with the real root filesystem can be mounted. It was assumed that initrd wasnt itself going to be the real root filesystem, so it had to be unmounted. With initramfs, these assumptions dont apply and it doesnt matter where the real root filesystem is; instead, the kernel treats initramfs as the root filesystem. Later, if required, a complete root filesystem (kept on a Flash drive) can be directly mounted over initramfs. On small embedded systems, the initramfs allows the kernel to boot to a minimal state, enough to bring the system up and running. If additional storage is not available to hold a complete root filesystem, initramfs becomes the real root filesystem. Initramfs does not create a ramdisk device, but only the necessary files and directories reside in memory; so RAM consumption is very low. Limitations: Though initramfs will solve the problem associated with initrd related to the boot time and the fixed filesystem size, it has the following limitations similar to initrd. No long-term storage, since changes made are lost on the next reboot. Systems with extremely limited amounts of RAM may not afford to spare RAM to hold initramfs as the root filesystem.
information across restarts. The NFS root filesystem is mainly used because the storage is not physically located on your embedded system. Moreover, you may still require initrd or initramfs for initial booting. Limitations: Primary dependency is on an Ethernet interface, and thus tiny Linux devices with limited interfaces may not use it. Deployed embedded Linux systems rarely use remotelymounted NFS filesystems for normal operations.
based filesystem (ramfs) is developed. Initramfs is an instance of ramfs. However, like the previously described filesystems, this one also has its limitation: It does not have the ability to preserve data across system reboots as it is also RAM-based.
cramfs
cramfs is designed to be simple, small and a compressed read-only filesystem, usually kept in the system Flash. Its primary advantage is that it stores all files in a compressed format, and decompresses them onthe-fly in order to optimise storage. Each page is individually compressed, allowing random page access. All the compressed pages are kept in Flash until the kernel tries to access the page. The data is compressed using zlib routines. Occasionally, cramfs can be used as a root filesystem as shown in Figure 1. It is an excellent way to get root file system compression. It is very useful in its efficiency and is kept read-only to prevent file corruption and improve system reliability. cramfs can be used in an embedded system where RAM is in abundance and Flash size is limited. The mkcramfs utility is used to create a cramfs image from the contents of a specified directory. The limitation of this filesystem is that even though it is quite space efficient in terms of Flash usage, more RAM will be required, since all application code needs to be decompressed into RAM for execution.
ramfs
Sometime back, Linus Torvalds wrote a tiny wrapper around the Linux cache called ramfs, and other kernel developers created an improved version called tmpfs. These RAMbased filesystems can grow or shrink to fit the data they contain. Adding files to ramfs (or extending existing files) automatically allocates more memory, and deleting or truncating files frees that memory. Due to a dynamic resizable property, the ramfs is far better. Also, it is a real filesystem, which avoids unnecessary wastage of RAM, as you dont need to create a block device. The filesystem only uses the space needed to store the files on it. The ramfs is best suited for embedded Linux systems that dont require preserving the data that changes. The tmpfs filesystem is a derivative of ramfs, which gains swapping and limit checking as extra functionality.
romfs
romfs is a space-efficient, small, readonly filesystem. It is block-based, which means it makes use of block (or sector) accessible storage devices like disks and ROM/Flash drives. The rom in romfs doesnt refer to hardware ROM. This filesystem stores all data . of a file sequentially, so it allows for application programs to be executed in place (XIP). This results in a considerable reduction in memory
14
NOVEMBER 2007
www.linuxforu.com
CMYK
Admin
footprint. As data is present in an uncompressed manner, a driver does not need the overhead of a compression library, and hence access time is fast. For procedures like Linux boot, where it is needed for files to take the least possible space, romfs is really helpful. Even initial ramdisk can be created in romfs format, and then romfs can be mounted as a root filesystem. On embedded Linux devices, with significant amount of read-only memory, it makes little sense to have a writable filesystem; romfs can be a good choice in such cases. Being favourable to an embedded environment, the romfs type is very commonly used. To create a romfs binary image, a special tool called genromfs is used. Given a directory tree on a host, it will construct a filesystem image. Limitations: The romfs being read-only, it has to mount another writable filesystem like ramfs or tmpfs to provide write facility. More space is required to store data, as no compression is supported. This becomes a tradeoff for Flash constrained devices.
JFFS2
The JFFS2 is a read-write, compressed, journaling Flash filesystem that is specifically designed to be used on Flash memory devices rather than RAM devices. The journaling aspect of JFFS2 is quite dynamic and works very well on
Flash. The JFFS2 filesystem is simply a list of nodes or log entries that contain information about a file. When a JFFS2 filesystem is mounted, the entire log is scanned and then nodes are written to Flash, sequentially. It includes a garbage collection thread that combines and copies valid nodes in one block to another block, then erases partially used blocks. Valid data is never erased until it has been copied to another block; hence, existing data is never lost. The JFFS2 addresses most of the issues of Flash filesystems in that it provides compression, read-write access, automatic levelling and a hard power-down safe filesystem. The JFFS2 filesystem is safe from sudden power loss or an unclean shutdown condition and doesnt require a filesystem check on the next boot-up. It also provides an intelligent feature called wear levelling, where the filesystem lays out data and updates it in such a way that all parts of the Flash are erased a similar number of times. This can dramatically increase the lifetime of Flash memory devices. JFFS2 has the distinct advantage of storing files compressed, so uses much less Flash space. Alternately, it provides an option to take compression off and get rid of compression overhead. All these aspects result in JFFS2 becoming one of the most popular choices for an embedded Linux system. For devices that need a readwrite root filesystem, JFFS2 has become the standard choice. The JFFS2 file system image can be
created using the mkfs.jffs2 utility. Limitations: JFFS2 imposes an overhead of more CPU cycles to compress or decompress data every time data is read-written from Flash. Due to log-scanning on each mount, the JFFS2 mount time is longer. There is an in-RAM data structure for every on-Flash node, resulting in more RAM usage. Some small amount of Flash will be wasted for the journal and garbage collection system.
www.linuxforu.com
NOVEMBER 2007
15
CMYK
Admin
2.
3.
4.
5.
6.
in our case, we can allocate 2MB, 1MB and 1MB, respectively, for these three regions. Add the XIP support to the kernel while configuring, so the kernel code will be executed from Flash and need not be copied to RAM. XIP is supported because the hardware we are using has no MMU. Create the two MTD (Memory Technology Device: a Linux subsystem that provides read, write and erase access to physical memory devices such as Flash and RAM) partitions as mtd0 and mtd1, each of 1MB size for putting filesystem images on. The obvious question is: which filesystems to use on these MTD partitions? On the first partition (mtd0) put romfs as the read-only root filesystem that supports XIP. And on the second partition (mtd1), put JFFS2 as a read-write filesystem. The Linux kernel code supports romfs to be XIP. Mounting on MTD devices takes a little effort. The following patch (for a MMUless processor) may help to achieve this: http:// people.redhat.com/~dhowells/30nommu-mtd-romfs.diff Make romfs the root filesystem so that it will mount the systems / (root) directory. Then mount the JFFS2 filesystem on a particular directory like /var under the root directory.
7. As romfs is read-only, keep all the necessary and frequently used small applications in romfs imagee.g., shell commands and utilities. Using Busybox commands will be a good choice. 8. Store all the custom-made, frequently changed user applications and data on the JFFS2 filesystem that has write access. Those applications might be heavy in size but will be preserved until explicitly removed. 9. As cramfs and JFFS2 cannot be XIP due to compression, romfs seems a perfect choice as a root filesystem. However, romfs is read-only and nothing can be added to romfsso it can hold only the most required
applications. Also, its read-only nature helps XIP. Hence, making romfs XIP will execute applications from Flash itself. This will drastically save a lot of RAM space from being used. 10. As cramfs is read-only, JFFS2 is the best choice for other MTD partitions (mtd1) to be used as permanent storage, mainly for custom third-party applications. This will increase the robustness of the system. 11. The only one disadvantage in this approach is that unused space in the mtd0 and mtd1 partitions is wasted. For this system, the Flash arrangement might be something like the diagram in Figure 2.
Summary
Linux is equipped with a lot of filesystems to cater to embedded device requirements. Embedded Linux looks very flexible while playing around with these filesystems during development. There are a number of constrains to using a filesystem in embedded devices. Hence, your best choice depends on the number of compromises a device can make to use a particular filesystem.
By: Mangesh Edake and Pratik Pujar. The authors work at Oasis Technologies and can be reached at mangesh.edake@ oasistech.co.in and [email protected], respectively.
16
NOVEMBER 2007
www.linuxforu.com
CMYK