6.1 Basic Root Filesystem Structure

The top-level directories in the root filesystem each have a specific use and purpose. Many of these are meaningful only in multiuser systems in which a system administrator is in charge of many servers and/or workstations used by different users. In most embedded Linux systems, where there are no users and no administrators, the rules to build a root filesystem can be loosely interpreted. This doesn't mean that all rules can be violated, but it does mean that breaking some rules will have little to no effect on the system's proper operation. Interestingly, even mainstream commercial distributions for workstations and servers do not always adhere to the established rules for root filesystems.

The "official" rules to build a root filesystem are contained in the Filesystem Hierarchy Standard (FHS) introduced in Chapter 1. The document is less than 30 pages long and is fairly easy to read. If you are looking for answers or clarifications regarding the root filesystem, the FHS is probably the best place to start. Table 6-1 provides the complete list of root filesystem top-level directories and their content as specified by the FHS.

Table 6-1. Root filesystem top-level directories




Essential user command binaries


Static files used by the bootloader


Devices and other special files


System configuration files, including startup files


User home directories, including entries for services such as FTP


Essential libraries, such as the C library, and kernel modules


Mount point for temporarily mounted filesystems


Add-on software packages


Virtual filesystem for kernel and process information


Root user's home directory


Essential system administration binaries


Temporary files


Secondary hierarchy containing most applications and documents useful to most users, including the X server


Variable data stored by daemons and utilities

If you are using Linux for your day-to-day work, you are already familiar with some of these directories. Nevertheless, let's take a closer look at the content of a typical root filesystem for use in an embedded Linux system.

First, all the directories that pertain to providing a multiuser extensible environment, such as /home, /mnt, /opt, and /root, can be omitted. We could trim the root filesystem even further by removing /tmp and /var, but these omissions may jeopardize the operation of certain programs. I do not encourage such a minimalistic approach.

This discussion does not revolve around size issues, but rather functionality. In fact, omitting a directory entry changes little to the resulting root filesystem's size. The reason I state that /home can be omitted, for example, is that even if it were present in an embedded Linux system, it would be empty, because its content, as prescribed by the FHS, is useful only in workstation and server setups.

Depending on your bootloader and its configuration, you may not need to have a /boot directory. This will depend on whether your bootloader can retrieve kernel images from your root filesystem before your kernel is booted. You will be able to decide whether you should use a /boot directory and how to use it for your target after you read Chapter 9. Of course, you can redesign the root filesystem at any later time if need be.

The remaining directories, /bin, /dev, /etc, /lib, /proc, /sbin, and /usr, are essential.

At the extreme, you could omit /proc, which is useful only for mounting the virtual filesystem that has the same name. However, it would then become very hard to understand what is happening on your target if you needed to analyze it in the field. If you are very tight for space, you can configure your kernel without /proc support, but I encourage you to enable it whenever possible.

Two of the root directories, /usr and /var, have a predefined hierarchy of their own, much like that of the root directory. We will briefly discuss these hierarchies as we populate both directories in the steps below.

Confusing Similarities

One of the most confusing aspects of the root filesystem is the apparent similarity in purpose of some directories. In particular, newcomers often ask what difference there is between the various directories containing binaries and the various directories containing libraries.

There are four main directories for binaries on the root filesystem: /bin, /sbin, /usr/bin, and /usr/sbin. The directory in which a binary is placed largely depends on its role in the system. Binaries that are essential to both users and system administrators are in /bin. Binaries that are essential to system administration, but will never be used by ordinary users, are located in /sbin. In contrast, most nonessential user binaries are located in /usr/bin and most nonessential system administration tools are in /usr/sbin.

As for the location of libraries, the rationale is similar. The libraries required to boot the system and run the most essential commands are located in /lib, while /usr/lib contains all the other libraries. Often, packages will create subdirectories in /usr/lib to contain their own libraries. The Perl 5.x packages, for instance, have a /usr/lib/perl5 directory that contains all the Perl-related libraries and modules.

A look on your Linux workstation's own root filesystem in these directories will show you actual examples of the application of these criteria by your distribution's designers.

To work on the root filesystem, let's move into the directory we created for this purpose:

$ cd ${PRJROOT}/rootfs

We now create the core root filesystem directories required for our system:

$ mkdir bin dev etc lib proc sbin tmp usr var
$ chmod 1777 tmp

Notice that we did not create /boot. We will come back to it later and create it if it becomes necessary. Also, note that we changed the permissions for the /tmp directory to turn the "sticky bit" on. This bit in the directory permissions field will ensure that files created in the /tmp directory can be deleted only by the user that created them. Though most embedded Linux systems are single-user systems, as I said above, there are cases in which embedded applications must not run with root privileges, hence the need to follow some basic rules about root filesystem permission bits. The OpenSSH package we discuss in Chapter 10, for example, is such an application.

We can proceed with the creation of the /usr hierarchy:

$ mkdir usr/bin usr/lib usr/sbin

On a fully featured root filesystem, the /usr directory usually contains many more entries. A simple demonstration of this is easily conducted by typing ls -al /usr on your workstation. You will find directories such as man, src, and local. The FHS contains a section addressing the layout of this directory in detail. For the purposes of most embedded Linux systems, nonetheless, the three directories we created will suffice.

The last entries to create are in the /var directory:

$ mkdir var/lib var/lock var/log var/run var/tmp
$ chmod 1777 var/tmp

Here, too, this directory usually contains many more entries. Directories such as cache, mail, and spool are useful for a workstation or a server, but few embedded systems need those directories. The directories we created are the bare minimum required for the normal operation of most applications found in an embedded Linux system. Of course, if you need functionality such as web page serving or printing, then you may want to add some of the additional directories required by the applications providing this functionality. See the FHS and the documentation provided with your application to find out your actual requirements.

With the root filesystem skeleton now ready, let's place the various software components in their appropriate locations.

Running Linux with a Different root Filesystem Structure

As I said in the previous discussion, the rules for building a root filesystem are found in the FHS. Although most Linux applications and distributions depend on these rules, they are not enforced by the Linux kernel itself. In fact, the kernel source code makes very few assumptions regarding the structure of the root filesystem. It follows from this that you could build an embedded Linux system with a very different root filesystem structure. You would then have to modify the defaults of most software packages to make them comply with your new structure. Some have taken an even more extreme approach by building embedded Linux systems without any root filesystem at all. Needless to say, I don't encourage you to go down this path. The root filesystem rules I outlined above are recognized and agreed upon by all open source and free software developers. By building your embedded Linux system using other rules, you would be cutting yourself off from most open source and free software packages and their developers.