The root filesystem (rootfs) is the main filesystem for an UNIX-like operative system. It contains the very critical files needed for the whole system to work (for instance, the init process), so if the root filesystem gets corrupted, the system will not work at all!
The root filesystem is the first filesystem the kernel mounts at boot, and it is never unmounted.
A rootfs can be used on several different types of storage devices (disks, flashes, and so on). A filesystem can stay in the RAM or even over the network, and according to the storage device where it's placed on, it can have different formats. This is because it has to take into account some special feature of the underlying storage media. In a typical GNU/Linux system, a rootfs type can be (mostly) EXT3/EXT4 or JFFS2/UBIFS. The first two formats are the standard Linux filesystems used into hard disks, USB storage devices, microSDs, and other block devices, while the JFFS2 and UBIFS are filesystems used on fla devices (nowadays, NAND flashes).
Apart from the format we're using in our system, we can find the same files and directory set in a root filesystem. Here is the typical listing on both my host PC and one developer kit of this book (see the uname output to distinguish the architecture):
$ uname -aLinux ubuntu1510 4.2.0-35-generic #40-Ubuntu SMP Tue Mar 15 22:15:45 U TC 2016 x86_64 x86_64 x86_64 GNU/Linux$ ls /bin dev initrd.img lib64 mnt root srv usr vmlinuz.oldboot etc initrd.img.old lost+found opt run sys varcdrom home lib media proc sbin tmp vmlinuzroot@wb:~# uname -aLinux wb 4.4.7-armv7-x6 #1 SMP Sun Apr 17 18:41:21 CEST 2016 armv7l GN U/Linuxroot@wb:~# ls /bin dev home lost+found mnt proc run srv tmp varboot etc lib media opt root sbin sys usr
As we can see, they're almost the same (apart some files), and we can write the same directories. I can write a complete chapter on these directories and the files they hold, but this not the scope of this book. However, I can spend some paragraphs to explain the directories we're going to refer to in this book.
In particular, we'll see the following directories: /dev that is related to the system's devices or peripherals, /proc and /sys that are related to special virtual filesystem where we can get/set some system's settings, and /run and other directories related to the temporary filesystem.
The /dev directory
This is the directory where all devices (apart from the net devices) are mapped, that is, where the block or character special files (used to address all the relative peripherals into the system) are usually placed.
At very beginning of the UNIX era, this directory was simply a standard directory with several block and character files (one per possible device connected to the system). However, during the evolution of UNIX (and Linux), this solution become very inefficient (due the very large peripheral numbers). So, Linux developers implemented different solutions to address this problem until the current one that uses a special temporary filesystem named devtmpfs.
The devtmpfs filesystem is just like the temporary filesystem, but it lets the kernel create a tmpfs instance very early at kernel initialization, before any driver-core device is registered. This is because each device must be mapped here as soon as it is activated by its relative driver.
We can take a look at this using the findmnt command:
We can recognize some known devices such as the serial ports (ttyS0, ttyS1, and so on), the I2C busses (i2c-0 and i2c-1), the real-time clock (rtc), and so on. Other devices are located into sub directories as disks:
You can use your host PC or embedded device to walk around the /dev directory and discover other block or character devices. You can see the device type just using the ls command with the -l option arguments:
root@wb:~# ls -l /dev/mmcblk0* brw-rw---- 1 root disk 179, 0 Jan 1 1970 /dev/mmc blk0 brw-rw---- 1 root disk 179, 1 Jan 1 1970 /dev/mmc blk0p1 root@wb:~# ls -l /dev/ttyS* crw-rw---- 1 root dialout 4, 64 Jan 1 1970 /dev/t tyS0 crw-rw---- 1 root dialout 4, 65 Jan 1 1970 /dev/t tyS1 crw-rw---- 1 root dialout 4, 66 Jan 1 1970 /dev/t tyS2 crw-rw---- 1 root dialout 4, 67 Jan 1 1970 /dev/t tyS3 crw-rw---- 1 root dialout 4, 68 Jan 1 1970 /dev/t tyS4 crw-rw---- 1 root dialout 4, 69 Jan 1 1970 /dev/t tyS5
The block devices have a b character at the beginning of the first column of the ls output, while the character ones have a c. So, in the preceding output, we can see that /dev/mmcblk0xx are block devices while /dev/ttySx are character ones.
The tmpfs
The temporary filesystem (tmpfs) is a filesystem stored on top of volatile memory instead of a persistent storage device. Due to this fact, on reboot, everything in tmpfs will be lost.
Even if it may look really strange that a vanishing filesystem can be useful, it really is! In fact, it is used where the system needs quick read, write, and delete operations on several files that are to be recreated on every boot. These files are exactly the ones under the /run directory, that is, where (almost) every distribution stores temporary files related to its running services (daemons).
On the Wandboard, we have the following tmpfs filesystems:
You may notice that there are other places where tmpfs are used!
The procfs
The proc filesystem (procfs) is a virtual filesystem that holds information about the processes (and other system information) in a hierarchical file structure. This allows the user to find the necessary information quickly by looking at a well-defined point of the system where all information is pretty ordinated.
A virtual filesystem is a filesystem that contains virtual files (files stored nowhere filled with information created on the fly when they get accessed) used to export information about various kernel subsystems, hardware devices, and associated device drivers to user space. In addition to providing this information, these exported virtual files are also used for system configuration and device management.
The standard mount point of this filesystem is the /proc directory, as shown here:
Then, in this directory, we can find all process-related information. For instance, if we wish to have some information about the init process, the first process executed into the system (that is, the process with PID 1), we should have a look at the /proc/1 directory as shown here:
root@wb:~# ls /proc/1attr cpuset limits net root statmautogroup cwd loginuid ns sched statusauxv environ map_files oom_adj schedstat syscallcgroup exe maps oom_score sessionid taskclear_refs fd mem oom_score_adj setgroups timerscmdline fdinfo mountinfo pagemap smaps uid_mapcomm gid_map mounts personality stack wchancoredump_filter io mountstats projid_map stat
Here is located all information regarding the init process. For example, we can find the environment:
This information can be retrieved for every process running into the system. For instance, we can get the information regarding our Bash shell by discovering its PID first:
root@wb:~# pidof bash588
Tip
My Wandboard is running just one instance of the Bash process, so I am sure that the preceding PID is referred to my shell.
Then, we can look at /proc/588 directory:
root@wb:~# ls /proc/588/attr cpuset limits net root statmautogroup cwd loginuid ns sched statusauxv environ map_files oom_adj schedstat syscallcgroup exe maps oom_score sessionid taskclear_refs fd mem oom_score_adj setgroups timerscmdline fdinfo mountinfo pagemap smaps uid_mapcomm gid_map mounts personality stack wchancoredump_filter io mountstats projid_map stat
Now, we can check out the shell's environment by looking at the /proc/588/environ file:
However, the procfs, as already shown in Managing the kernel messages section Chapter 2 , Managing the System Console, where we used it to set the kernel console logging level, can be used to get/set other information regarding the system settings in general. For instance, we can get the listing of the currently loaded modules into the kernel by reading the file /proc/modules:
root@wb:~# cat /proc/modulesbrcmfmac 254455 0 - Live 0xbf4d0000elbrcmutil 9092 1 brcmfmac, Live 0xbf4c2000cfg80211 536448 1 brcmfmac, Live 0xbf3e0000caam_jr 17297 0 - Live 0xbf34a000snd_soc_fsl_ssi 15476 2 - Live 0xbf342000...
Alternatively, we can read how many interrupts we have got per CPU since the boot from the /proc/interrupts file:
This file is really important when we work with the hardware since we can have an idea whether our device is generating interrupts or not. Also, we can have information regarding the correct interrupt handlers' configurations (we'll see these features in the upcoming chapters when we talk about the peripherals).
Also, we can get the actual device tree configuration by reading the contents of the /proc/device-tree directory as follows:
root@wb:~# ls /proc/device-tree#address-cells cpus memory #size-cellsaliases display-subsystem model socchosen gpu-subsystem name soundclocks interrupt-controller@00a01000 regulators sound-spdifcompatible __local_fixups__ rfkill __symbols__
Referring to our preceding sample driver, we can retrieve the pulse device's tree settings by reading into the /proc/device-tree/pulses/ directory as shown here (note that this time, we switch back to the SAMA5D3 Xplained):
root@a5d3:~# tree /proc/device-tree/pulses/ /proc/device-tree/pulses/ +-- compatible +-- name +-- oil | +-- gpios | +-- label | +-- name | \-- trigger \-- water +-- gpios +-- label +-- name \-- trigger 2 directories, 10 files
Then, we can check the data by reading the several files. Here are the trigger settings:
This is a nice feature to have in a system, but not all kernel developers agree that this information should be stored in the procfs because a proc filesystem should report processes' information only. That's why, the sysfs shown in the next paragraph was born (in reality, this is not the only reason).
Tip
You may get further information by surfing the Internet or just reading the file Documentation/filesystems/procfs.txt from Linux's source tree.
The sysfs
The system filesystem (sysfs) is a virtual filesystem that exports information about all kernel subsystems, system's buses, and the hardware devices with their relative device drivers. This filesystem is deeply related to the device tree concept (as shown here) and the power system management, and it mainly resolves the problem to have a unified method of representing driver-device relationships and how to correctly put them in the power-saver mode.
From our point of view, the sysfs is really important since by using it, we can get/set most peripherals settings and we can get access to the peripherals data too.
The default mount point of this filesystem is the /sys directory as shown below:
It stores all devices' information grouped by the device class, that is, a logical set of devices that perform a common task in the system: graphics devices, sound devices, hardware monitor (hwmon) devices, and so on.
Referring to our preceding sample driver, we can retrieve the pulse class settings by reading into the /sys/class/pulse/ directory as shown here (note that we switch back to the SAMA5D3 Xplained again):
For instance, we can get information regarding the framebuffer (these devices will not be presented in this book, however they refer to a graphic hardware-independent abstraction layer to show graphical data on a computer display) by taking a look at the /sys/class/graphics/fb0/ directory:
root@wb:~# ls /sys/class/graphics/fb0/bits_per_pixel console device name rotate subsystemblank cursor mode pan state ueventbl_curve dev modes power stride virtual_size
Then, we can get the valid graphic modes using the command here:
Alternatively, we can get some information about a hwmon device (these devices will not be presented in this book, however they are used to monitoring some environment data, such as temperatures, and so on. of the system or external peripheral ones) on the Wandboard in the directory here:
root@wb:~# ls /sys/class/hwmon/hwmon0/name power subsystem temp1_crit temp1_input uevent
Then, by looking at the hwmon device, we can get the name, the critical temperature, and the current system's temperature using the command here:
Returned data are in m°C, that is they are, respectively, 95°C and 28.318°C.
In the upcoming chapters, when we present the several devices a developer can find in its embedded board and how they can get access to them, we will use this filesystem often.