高级部分(Bus、Class、Device、Driver)
深入,并且广泛
-沉默犀牛
这篇文章只分析Bus、Class的作用,和表示它们的结构体。不分析接口函数
Bus
Bus是处理器与一个或者多个device之间的通道。在设备模型中,所有的device都通过bus相连,这意味着,系统中的每一个device都要连接在一个Bus上,这个Bus可以是内部Bus,虚拟Bus,或者platform Bus。Bus之间可以相互穿插,比如一个USB控制器通常是一个PCI设备。以下分析代表Bus的结构体:bus_type
struct bus_type {
const char *name; //该bus的名称,会在sysfs中以目录的形式存在,
//如platform bus在sysfs中表现为"/sys/bus/platform”
const char *dev_name; //对有些设备而言(例如批量化的USB设备),设计者根本就懒得
//为它起名字的,而内核也支持这种懒惰,允许将设备的名字留空。
//这样当设备注册到内核后,设备模型的核心逻辑
//就会用"bus->dev_name+device ID”的形式,
//为这样的设备生成一个名称。
struct device *dev_root; //bus的默认父设备
struct device_attribute *dev_attrs; //以下是默认的attribute
const struct attribute_group **bus_groups;
const struct attribute_group **dev_groups;
const struct attribute_group **drv_groups;
int (*match)(struct device *dev, struct device_driver *drv); //一个由具体的bus driver实现的回调函数。
//当任何属于该Bus的device或者device_driver
//添加到内核时,内核都会调用该接口,如果
//新加的device或device_driver匹配上了自己
//的另一半的话,该接口要返回非零值,此时
//Bus模块的核心逻辑就会执行后续的处理。
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev); //probe和remove这两个函数,和device_driver中
//的非常类似,但它们的存在是非常有意义的。可
//以想象一下,如果需要probe(其实就是初始化)
//指定的device话,需要保证该device所在的
//bus是被初始化过、确保能正确工作的。这就要
//就在执行device_driver的probe前,先执行
//它的bus的probe。remove的过程相反。
//注1:并不是所有的bus都需要probe和remove接口的,因为对有些bus来说
//(例如platform bus),它本身就是一个虚拟的总线,无所谓初始化,直接
//就能使用,因此这些bus的driver就可以将这两个回调函数留空。
int (*remove)(struct device *dev);
void (*shutdown)(struct device *dev); //shutdown、sus