sysfs is a feature of the Linux 2.6 kernel that allows kernel code to export information to user processes via an in-memory filesystem. The organization of the filesystem directory hierarchy is strict, and based the internal organization of kernel data structures. The files that are created in the filesystem are (mostly) ASCII files with (usually) one value per file. These features ensure that the information exported is accurate and easily accessible, making sysfs one of the
most intuitive and useful features of the 2.6 kernel.
Introduction
sysfs is a mechanism for representing kernel objects, their attributes, and their relationships with each other. It provides two components:a kernel programming interface for exporting these items via sysfs, and a user interface to view and manipulate these items that maps back to the kernel objects which they represent. The table below shows the mapping between internel (kernel) constructs and their external (userspace) sysfs mappings.
First, a short but touching history describes its origins. Then crucial information about mounting and accessing sysfs is included. Next, the directory organization and layout of subsystems in sysfs is described. This provides enough information for a user to understand the organization and content of the information that is exported through sysfs, though for reasons of time and space constraints, not every object and its attributes are described.
The primary goal of this paper is to provide a technical overview of the internal sysfs interface—the data structures and the functions that are used to export kernel constructs to userspace. It describes the functions among the three concepts mentioned above Kernel Objects, Object Attributes, and Object Relationships—and dedicates a section to each one. It also provides a section for each of the two additional regular file interfaces created to simplify some common operations—Attribute Groups and Binary Attributes.sysfs is a conduit of information between the kernel and user space. There are many opportunities for user space applications to leverage this information. Some existing uses are the ability to I/O Scheduler parameters and the udev program. The final section describes a sampling of the current applications that use sysfs and attempts to provide enough inspira-
tion to spawn more development in this area.Because it is a simple and mostly abstract interface, much time can be spent describing its interactions with each subsystem that uses it.This is especially true for the kobject and driver models, which are both new features of the 2.6 kernel and heavily intertwined with sysfs. It would be impossible to do those topics justice in such a medium and are left as subjects for other documents.
The History of sysfs
sysfs is an in-memory filesystem that was originally based on ramfs. ramfs was written around the time the 2.4.0 kernel was being stabilized. It was an exercise in elegance, as it showed just how easy it was to write a simple filesystem using the then-new VFS layer. Because of its simplicity and use of the VFS, it provided a good base from which to derive other in-memory based filesystems. sysfs was originally called ddfs (Device Driver Filesystem) and was written to debug the new driver model as it was being written. That debug code had originally used procfs to export a device tree, but under strict urging from Linus Torvalds, it was converted to use a new filesystem based on ramfs.By the time the new driver model was merged into the kernel around 2.5.1, it had changed names to driverfs to be a little more descriptive.During the next year of 2.5 development, the infrastructural capabilities of the driver model and driverfs began to prove useful to other sub- systems. kobjects were developed to provide a central object management mechanism and driverfs was converted to sysfs to represent its subsystem agnosticism.
Mounting sysfs
sysfs can be mounted from userspace just like any other memory-based filesystem. The command for doing so is listed in Table 1. sysfs can also be mounted automatically on
boot using the file /etc/fstab. Most distributions that support the 2.6 kernel have entries for sysfs in /etc/fstab. An example entry is shown in Table 2. Note that the directory that sysfs is mounted on: /sys. That is the de facto standard location for the sysfs mount point. This was adopted without objection by every major distribution.
Navigating sysfs
Since sysfs is simply a collection of directories, files, and symbolic links, it can be navigated and manipulated using simple shell utilities. The author recommends the tree(1)utility. It was an invaluable aide during the development of the core kernel object infrastructure.
/sys/
-- block
-- bus
-- class
-- devices
-- firmware
-- module
‘-- power
Table 3: Top level sysfs directories
At the top level of the sysfs mount point are a number of directories. These directories represent the major subsystems that are registered with sysfs. At the time of publication, this consisted of the directories listed in Table 3. These directories are created at system startup when the subsystems register themselves with the kobject core. After they are initialized, they begin to discover objects, which are registered within their respective directories.The method by which objects register with sysfs and how directores are created is explained later in the paper. In the meantime, the curious are encouraged to meander on their own through the sysfs hierarchy, and the meaning of each subsystem and their contents follows now.
block
The block directory contains subdirectories for each block device that has been discovered in the system. In each block device’s directory are attributes that describe many things, including the size of the device and the dev_t number that it maps to. There is a symbolic link that points to the physical device that the block device maps to (in the physical device tree, which is explained later). And, there is a directory that exposes an interface to the I/O scheduler. This interface provides some statistics about about the device request queue and some tunable features that a user or administrator can use to
bus/
-- ide
-- pci
-- scsi
‘-- usb
Table 4: The bus directory
optimize performance, including the ability to dyanmically change the I/O scheduler to use.Each partition of each block device is represented as a subdirectory of the block device.Included in these directories are read-only attributes about the partitions.
bus
The bus directory contains subdirectories for each physical bus type that has support registered in the kernel (either statically compiled or loaded via a module). Partial output is listed in Table 4. Each bus type that is represented has two subdirectories: devices and drivers. The devices directory contains a flat listing of every device discovered on that type of bus in the entire system. The devices listed are actually symbolic links that point to the device’s direc-
tory in the global device tree. An example listing is shown in Table 5.
The drivers directory contains directories for each device driver that has been registered with the bus type. Within each of the drivers’ directories are attributes that allow viewing and manipulation of driver parameters, and symbolic links that point to the physical devices (in the global device tree) that the driver is bound to.
bus/pci/devices/
-- 0000:00:00.0 -> ../../../devices/pci0000:00/0000:00:00.0
-- 0000:00:01.0 -> ../../../devices/pci0000:00/0000:00:01.0
-- 0000:01:00.0 -> ../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0
-- 0000:02:00.0 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:00.0
-- 0000:02:00.1 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:00.1
-- 0000:02:01.0 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:01.0
‘-- 0000:02:02.0 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:02.0
Table 5: PCI devices represented in bus/pci/devices/
class/
-- graphics
-- input
-- net
-- printer
-- scsi_device
-- sound
‘-- tty
Table 6: The class directory
class
The class directory contains representations of every device class that is registered with the kernel. A device class describes a functional type of device. Examples of classes are shown in Table 6. Each device class contains subdirectories for each class object that has been allocated and registered with that device class. For most of class device objects, their directories contain
symbolic links to the device and driver directories (in the global device hierarchy and the bus hierarchy respectively) that are associated with that class object. Note that there is not necessarily a 1:1 mapping between class objects and physical devices; a physical device may contain multiple class objects that perform a different logical function. For example, a physical mouse device might map to a kernel mouse object, as well as a generic “input event” device and possibly a “input debug” device.
Each class and class object may contain attributes exposing parameters that describe or control the class object. The contents and format, though, are completely class dependent and depend on the support present in one’s kernel.
devices
The devices directory contains the global device hierarchy. This contains every physical device that has been discovered by the bus types registered with the kernel. It represents them in an ancestrally correct way—each device is shown as a subordinate device of the device that it is physically (electrically) subordinate to.
There are two types of devices that are exceptions to this representation: platform devices and system devices. Platform devices are peripheral devices that are inherent to a particular platform. They usually have some I/O ports, or MMIO, that exists at a known, fixed location. Examples of platform devices are legacy x86 devices like a serial controller or a floppy controller, or the embedded devices of a SoC solution. System devices are non-peripheral devices that are integral components of the system. In many ways, they are nothing like any other device. They may have some hardware register access for configuration, but do not have the capability to transfer data. They usually do not have drivers which can be bound to them. But, at least for those represented through sysfs, have some architecture-specific code that configures them and treats them enough as objects to export them. Examples of system devices are CPUs, APICs, and timers.
firmware
The firmware directory contains interfaces for viewing and manipulating firmware-
specific objects and attributes. In this case, ‘firmware’ refers to the platform-specific code that is executed on system power-on, like the x86 BIOS, OpenFirmware on PPC platforms,and EFI on ia64 platforms. Each directory contains a set of objects and attributes that is specific to the firmware “driver in the kernel.” For example, in the case of ACPI, every object found in the ACPI DSDT table is listed in firmware/acpi/ namespace/ directory.
module
The module directory contains subdirectories for each module that is loaded into the kernel.The name of each directory is the name of the module—both the name of the module object
file and the internal name of the module. Every module is represented here, regardless of
the subsystem it registers an object with. Note that the kernel has a single global namespace
for all modules. Within each module directory is a subdirectory called sections. This subdirectory contains attributes about the module sections. This information is used for debugging and generally not very interesting. Each module directory also contains at least one attribute: refcnt. This attributes displays the current reference count, or number of users, of the module. This is the same value in the fourth column of lsmod(8) output.
power
The power directory represents the underused power subsystem. It currently contains
only two attributes: disk which controls the method by which the system will suspend to disk; and state, which allows a process to enter a low power state. Reading this file displays which states the system supports.
General Kernel Information :
Code Organization :-
The code for sysfs resides in fs/sysfs/ and its shared function prototypes are in include/linux/sysfs.h. It is relatively small (~2000 lines), but it is divided up among 9 files, including the shared header file. The organization of these files is listed below. The contents of each of these files is described in the next section.
• include/linux/sysfs.h - Shared header file containing function prototypes and data structure definitions.
• fs/sysfs/sysfs.h - Internal header file for sysfs. Contains function definitions
shared locally among the sysfs source.
• fs/sysfs/mount.c - This contains the data structures, methods, and initialization functions necessary for interacting with the VFS layer.