感谢支持
我们一直在努力

Linux关于总线、设备、驱动的注册顺序

+—-> devices
|
|
|
—————————————————————————–
struct bus_type    match() probe()
—————————————————————————–
|
|
|
+—-> drivers     probe()
驱动挂接到总线上时,与总线上的所有设备进行匹配(用bus_type.match进行匹配),
如果匹配成功,则调用bus_type.probe或者driver.probe初始化该设备;挂接到总线上
如果匹配失败,则只是将该驱动挂接到总线上。


需要重点关注的是总线的匹配函数match(),驱动的初始化函数probe()


1. platform_bus_type–总线先被kenrel注册。


2. 系统初始化过程中调用platform_add_devices或者platform_device_register,将平台设备(platform devices)注册到平台总线中(platform_bus_type)
3. 平台驱动(platform driver)与平台设备(platform device)的关联是在platform_driver_register或者driver_register中实现,一般这个函数在驱动的初始化过程调用。


通过这三步,就将平台总线,设备,驱动关联起来。


1. platform bus先被kenrel注册。
——————————————————
do_basic_setup() –>-driver_init() –>-platform_bus_init()–>bus_register()



2. 系统初始化过程中调用platform_add_devices或者platform_device_register,将平台设备(platform devices)注册到平台总线中(platform_bus_type)
——————————————————
系统启动阶段,总线的驱动链表还是空的,所以启动阶段的platform_add_devices()只负责将设备添加到总线的设备链表上。


linux-2.6.26/drivers/base/platform.c
int platform_add_devices(struct platform_device **devs, int num)
{
—-…
—-ret = platform_device_register(devs[i]);
—-…
}


int platform_device_register(struct platform_device *pdev)
{
—-device_initialize(&pdev->dev);
—-return platform_device_add(pdev);
}


int platform_device_add(struct platform_device *pdev)
{
—-…
—-pdev->dev.bus = &platform_bus_type;
—-…
—-ret = device_add(&pdev->dev);
—-…
}


device_add() –>-bus_attach_device()


void bus_attach_device(struct device *dev)
{
—-struct bus_type *bus = dev->bus;
—-int ret = 0;


—-if (bus) {
——–if (bus->p->drivers_autoprobe)
————ret = device_attach(dev);
——–WARN_ON(ret < 0);
——–if (ret >= 0)
————klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
—-}
}


如果设备和驱动匹配成功;或者设备已经注册,但是总线上没有与之相匹配的驱动,bus_attach_device()将调用klist_add_tail()将设备添加到总线的设备链表尾部。

赞(0) 打赏
转载请注明出处:服务器评测 » Linux关于总线、设备、驱动的注册顺序
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏