As I continue with my Linux kernel development I now reached the situation where I came across the /proc pseudo file system.
This virtual file system plays an important role and “strongly” associated with the kernel, so it is worth talking and exploring it. In this post I will go over, not too deeply and hopefully not in a shallow manner about this file system, its usages in the context (also) of device drivers.
“The Linux kernel has two primary functions: to control access to physical devices on the computer and to schedule when and how processes interact with these devices. The /proc/ directory — also called the proc file system — contains a hierarchy of special files which represent the current state of the kernel — allowing applications and users to peer into the kernel’s view of the system.
Within the /proc/ directory, one can find a wealth of information detailing the system hardware and any processes currently running. In addition, some of the files within the /proc/ directory tree can be manipulated by users and applications to communicate configuration changes to the kernel.”
Meaning, the /proc file system is a sort of “read (and also a little write) interface” towards the kernel and the device it manages.
One can cat many files under the /proc file system such as, for example, /proc/interrupts that displays real-time & up-to-date information about interrupts in the system.
- It is worth mention that some of the information in files in this file system is not so “user friendly” so to the “rescue” comes utilities that “converts” that information for a more human readable form (utilities such as top, free, lspci).
- Also it is worth to note that some of the files in this folder are only readable by the root user.
- /proc file system files usages
- As a general rule, most of the files under the /proc file system are read-only, i.e. they are meant to be used in order to get (retrieve) information. However, some of the files can be adjusted (written to) in order to alter (modify) kernel settings/configurations at run time, where most of them are under the /proc/sys sub folder. For example, in order to modify the host name of the machine one can execute the command:
which actually modifies the value of the hostname file from the /proc file system.
IMPORTANT NOTE:A useful (and very widely used) utility that is used to alter files (settings) in the kernel is the sysctl (located under /sbin/sysctl) .
- /proc file system of our interest
Coming back to the context where this post is – which is how the /proc file system is “linked” to kernel modules, it is worth to mention some files of the /proc file system that are widely used in the context of kernel module development:
This file displays a list of all modules loaded currently in the system. The lsmod utility (located under /sbin/lsmod) under the hood, reads information from this file).
This file displays the various character and block devices currently configured (not including devices whose modules are not loaded).
- Device drivers and the /proc file system
In a way, one can say that each file under the /proc file system is “tied” to a “kernel function”. Device drivers utilizes the /proc file system by “exposing” information about them via “entries” in the /proc file system which are created (and removed) by them.
The /proc file system is dynamic – so modules (drivers) can add and remove entries whenever required (typically upon loading and unloading respectively). The struct that is used to hold this information is:
- Typically when the module is loaded (i.e. – in the init_module function) the entry is created and when the module is unloaded (in the exit_module) the entry is removed.
- The file operation structure
Each module in the kernel that wishes to “expose file wise” operations (such as read/write,etc…) can expose it via the structure struct file_operations. This struct can be thought off as an interface (from OOP) that has ~25 functions, each of which the module can implement or not to (thus leaving this capability not supported).
- Kernel module implementation
The very “minimal” kernel module that creates and is “accessible” via an entry in the /proc file system is as follows:
- The only thing that this module does upon “reading” its content is to display a string with its name and the current time stamp. This can be seen when “cat-ing” the module entry in the /proc as follows:
- In this module the “load” and “unload” functions are init_module and cleanup_module respectively.
- The THIS_MODULE macro indicates that the current module (within this file) is the “owner” of the file_operations struct. This is important in order to uniquely identify it and “link” it to the correct module.
- The entry in the /proc folder is created in the init_module function and removed in the cleanup_module function. When the module is loaded, if one runs the command ls /proc, one of the entries will be indeed:
In this post I have introduced the following:
- The /proc file system and its usage.
- The struct file_operations, its main usage and purpose and a very minimal implementation and creation of it for read capabilities.
- Very minimal kernel module that creates (and removes) an entry in the /proc file system and implements the read operation by “leveraging” the entry in the /proc file system of it.
The picture: Typical Meadow landscape view, in the state of Mato Grosso do Sul, Brazil.