要点:
1.设备注册
2.设备驱动注册
3.设备与驱动如何绑定
4.驱动如何初始化设备资源
当内核版本:linux 4.6.3
以led为例(leds-sunfire.c)
在设备树中创建led设备节点,在内核初始化时将所有节点创建出来(内核采用先创建节点,后初始化对应驱动,有设备无驱动则设备不工作,无设备则驱动初始化不起来)
当前篇幅我们只分析驱动的加载:
一.内核调用sunfire_leds_init流程:
在编译阶段通过module_init(sunfire_leds_init);将设备初始化函数sunfire_leds_init加入到对应区域,在docall时逐步调用,最终会调用到sunfire_leds_init函数:
二.驱动函数初始化流程:
static struct platform_driver sunfire_clockboard_led_driver = {
.probe = sunfire_clockboard_led_probe,
.remove = sunfire_led_generic_remove,
.driver = {
.name = "sunfire-clockboard-leds",
},
};
static struct platform_driver sunfire_fhc_led_driver = {
.probe = sunfire_fhc_led_probe,
.remove = sunfire_led_generic_remove,
.driver = {
.name = "sunfire-fhc-leds",
},
};
static struct platform_driver * const drivers[] = {
&sunfire_clockboard_led_driver,
&sunfire_fhc_led_driver,
};
static int __init sunfire_leds_init(void)
{
return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
}
static void __exit sunfire_leds_exit(void)
{
platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
}
module_init(sunfire_leds_init);
module_exit(sunfire_leds_exit);
流程图:
platform_register_drivers->driver_register->bus_add_driver->driver_attach->bus_for_each_dev->__driver_attach->driver_match_device+driver_probe_device->driver_probe_device->really_probe->drv->probe->sunfire_fhc_led_probe->sunfire_led_generic_probe->led_classdev_register