Click the blue text above to follow me and read beautiful articles
The Linux operating system’s kernel manages various hardware devices in the system, including buses, devices, and drivers. This article will introduce the basic concepts of buses, devices, and drivers in the Linux system, as well as their relationships. By combining the relevant /sys directory structure, readers will gain a better understanding of the hardware management mechanism in the Linux system.
Data Structures
The bus plays a bridging role in computer systems, responsible for connecting the CPU, memory, devices, and other hardware components, allowing them to communicate and collaborate. In Linux systems, common types of buses include PCI, USB, SATA, etc., each with its specific uses and characteristics.
/* Bus data structure */
struct bus_type {
const char *name; // Name of the bus type
struct device *dev_root; // Pointer to the head of the linked list of all devices on this bus
const char *drvsubdir; // Name of the subdirectory storing device drivers
const struct attribute_group **bus_groups; // Attribute groups of the bus type
const struct attribute_group **dev_groups; // Attribute groups of all devices on the bus
};
In the Linux system, each device has a unique identifier, which can be accessed through the /sys/devices directory. The subdirectories under this directory represent various devices in the system, each containing the device’s attribute information and status.
/* Device data structure */
struct device {
struct kobject kobj; // Kernel object for managing device attributes
const char *init_name; // Name of the device
struct bus_type *bus; // Pointer to the bus the device is on
struct device *parent; // Pointer to the parent device
struct device_driver *driver; // Pointer to the driver used by the device
const struct attribute_group **groups; // Device attribute groups
struct device_node *of_node; // Pointer to the device tree node
};
The driver is the software component in the system that communicates with the device, responsible for controlling the device’s operations and management. In Linux systems, drivers are typically loaded into the kernel as modules and manage bus-related driver and device information through the /sys/bus directory.
/* Driver data structure */
struct device_driver {
const char *name; // Name of the driver
struct bus_type *bus; // Pointer to the bus the driver is on
struct module *owner; // Pointer to the kernel module that owns this driver
const char *mod_name; // Name of the kernel module where the driver is located
int (*probe)(struct device *dev); // Function pointer to probe the device
int (*remove)(struct device *dev); // Function pointer to remove the device
void (*shutdown)(struct device *dev); // Function pointer to shut down the device
const struct attribute_group **groups; // Driver attribute groups
};
Device categories are classified based on device functions or characteristics, such as network devices, block devices, etc. In Linux systems, device category information can be accessed through the /sys/class directory, where each category corresponds to a subdirectory containing information about multiple devices of the same category.
struct class {
const char *name; // Name of the category
struct module *owner; // Pointer to the kernel module that owns this category
struct class_attribute *class_attrs; // List of category attributes
struct device_attribute *dev_attrs; // List of device attributes
struct bin_attribute *dev_bin_attrs; // List of device binary attributes
struct kobject *dev_kobj; // Device objects under the category
...
};
The relationship between buses, drivers, and devices is illustrated in the following diagram:
Virtual Files
The /sys
directory is a virtual file system provided by the Linux kernel, used to dynamically present information about the current system’s devices, buses, and drivers. This virtual file system is generated by the kernel based on data structures of devices, buses, and drivers, containing attribute information from these data structures.
These structures are closely related to the /sys
directory in Linux, as the /sys
directory is a virtual file system provided by the Linux kernel to dynamically present information about the current system’s devices, buses, and drivers. This virtual file system is generated by the kernel based on data structures of devices, buses, and drivers, containing attribute information from these data structures.
Specifically: the /sys/bus
directory contains subdirectories for all bus types registered with the kernel, each corresponding to a bus type, for example, /sys/bus/usb
stores information related to the USB bus.
The /sys/devices
directory contains all devices in the system, each device corresponding to a subdirectory that contains various attributes of the device, for example: /sys/devices/pci0000:00/0000:00:01.0
stores information about a PCI device.
The /sys/class
directory contains device categories, each category corresponding to a subdirectory, for example, /sys/class/net
stores information about network devices.
The /sys/module
directory contains modules loaded into the kernel, each module corresponding to a subdirectory that contains various attributes of the module, for example, /sys/module/usbcore
stores information about the USB core module.
Below is a simple example code demonstrating how to register a bus named example_bus:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
// Define bus type structure
static struct bus_type example_bus = {
.name = "example_bus", // Name of the bus type
};
static int __init example_bus_init(void)
{
int ret;
// Register bus type
ret = bus_register(&example_bus);
if (ret)
return ret;
// Create and register devices on the bus
// Device creation and registration process omitted here
return 0;
}
static void __exit example_bus_exit(void)
{
// Unregister bus type
bus_unregister(&example_bus);
}
module_init(example_bus_init);
module_exit(example_bus_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Example bus driver");
After registering the bus, a new subdirectory appears in the /sys/bus directory, named after the registered bus type. For example, if a bus type named example_bus is registered, a subdirectory named example_bus will appear in the /sys/bus directory.
In the new bus type subdirectory, it typically contains the following:
devices/: This directory contains information about all devices connected to this bus, with each device corresponding to a subdirectory.
drivers/: This directory contains information about drivers related to this bus type, with each driver corresponding to a subdirectory.
In summary, /sys/devices
, /sys/bus
, and /sys/class
represent different organizational methods for managing hardware device information in the /sys
virtual file system. Each method has its specific uses and organizational structures:
-
/sys/devices
: This is the most basic method, centered around devices, where each device corresponds to a subdirectory containing various attribute information about that device. This method is suitable for scenarios where management and operations are device-centric. -
/sys/bus
: This method is centered around bus types, where each bus type corresponds to a subdirectory containing information about devices connected to that bus. This method is suitable for scenarios where management and operations are bus-type-centric, such as USB buses, PCI buses, etc. -
/sys/class
: This method is centered around device categories, where each device category corresponds to a subdirectory containing information about multiple devices of the same category. This method is suitable for scenarios where management and operations are category-centric, such as network devices, block devices, etc.
Therefore, these three organizational methods are suitable for different management and operational needs, allowing users to choose the appropriate method to access and manage hardware device information in the system.
END
Looking forward to growing together with you
WeChat ID: Linux Workshop