Reviewing the bus device driver model, I’ve made a few notes for reference, experts can skip this.
1. A significant part of the driver framework in the Linux system revolves around the bus device driver model.
2. Involves three important structures:
struct bus_type: Bus
struct device: Device
struct device_driver: Driver
3. Core code analysis of the structures (Kernel 2.6.38)
struct bus_type
{
const char *name; // Bus name
struct bus_attribute *bus_attrs; // Bus attribute files, displayed in /sys/xxx
struct device_attribute *dev_attrs; // Device attribute files
struct driver_attribute *drv_attrs; // Driver attribute files
int (*match)(struct device*dev, struct device_driver *drv);// Function to check if driver matches device
struct subsys_private *p;
};
Among them, struct subsys_private contains a device linked list (struct klist klist_devices) and a driver linked list (struct klist klist_drivers)
struct device
{
struct kobject kobj;
const char // Device name
struct bus_type *bus; // Which bus this device is attached to
struct device_driver*driver; // Corresponding driver for this device
void *platform_data; // Platform-specific data, typically filled when porting the kernel (e.g., supporting mini2440 NAND flash, dm9000, etc.)
dev_t devt; // Device number
};
Any driver code built on the platform bus device driver model (such as platform drivers, PCI drivers, USB drivers, I2C drivers, SPI drivers, etc.) includes a struct device structure, and when these drivers register various devices with the kernel, they ultimately call:
int device_register(struct device *dev)
{
device_initialize(dev); // Perform various initializations
// Attach the device to the corresponding bus, mainly adding the device to the bus_type’s klist_devices linked list
return device_add(dev);
}
struct device_driver {
const char *name;// Driver name
struct bus_type *bus;// The bus to which this driver belongs
int (*probe) (struct device *dev);// Points to the device probe function
int (*remove) (struct device*dev);// Points to the device removal function
struct driver_private *p;
};
Similarly, any driver code built on the platform bus device driver model (such as platform drivers, PCI drivers, USB drivers, I2C drivers, SPI drivers, etc.) includes a struct device_driver structure, and when these drivers register various drivers with the kernel, they ultimately call:
int driver_register(struct device_driver *drv)
{
// Bind the driver to the corresponding bus, mainly adding the driver to the bus_type’s klist_drivers linked list
ret = bus_add_driver(drv);
}
Whether calling driver_register() to register a driver or using device_register to register a device, the kernel will invoke the bus’s match function to check if there is a suitable device_driver for the device or a suitable device for the device_driver. If the match is successful, the device_driver’s probe function will be called for further probing.
Thus, we can view drivers from a new perspective.
For more specific content on how to detect and set up probes, please refer to the related videos of Wei Dongshan’s second series on driver compilation.
Public Account Introduction
Only by creating works that please oneself can one please others. Wei Dongshan’s Embedded Linux tutorial helps you get started faster.