详解Linux2.6内核中基于platform机制的驱动模型 (经典) (16)

各个段的优先级由链接脚本定义

#define INITCALLS       /
   *(.initcall0.init)      /
   *(.initcall0s.init)      /
   *(.initcall1.init)      /
   *(.initcall1s.init)      /
   *(.initcall2.init)      /
   *(.initcall2s.init)      /
   *(.initcall3.init)      /
   *(.initcall3s.init)      /
   *(.initcall4.init)      /
   *(.initcall4s.init)      /
   *(.initcall5.init)      /
   *(.initcall5s.init)      /
 *(.initcallrootfs.init)      /
   *(.initcall6.init)      /
   *(.initcall6s.init)      /
   *(.initcall7.init)      /
   *(.initcall7s.init)

这个__initcall_start是在文件arch/xxx/kernel/vmlinux.lds.S定义的:
__initcall_start = .;
   INITCALLS
  __initcall_end = .;


664static void __init do_initcalls(void)
 665{
 666        initcall_t *call;
 667        int count = preempt_count();
 668
 669        for (call = __initcall_start; call < __initcall_end; call++) {
.。。。。
 682
 683                result = (*call)();
 684
。。。 }               
 720        /* Make sure there is no pending stuff from the initcall sequence */
 721        flush_scheduled_work();
 722}

因此__initcall_fnx,数字越小,越先被调用,故arch_initcall优先于module_init所修饰的函数。

arch_initcall修饰的函数的调用顺序如下:
start_kernel  》 rest_init(在setup_arch之后)  》 kernel_init  》 do_basic_setup》do_initcalls(在driver_init()之后),因为platform_bus_init在此之前已经初 始化完毕了,便可将设备挂接到总线上了。

8.4    定义platform_driver
Platform bus和设备都定义好了后,需要定义一个platform driver用来驱动此设备。

对于设备来说:
290struct platform_device s3c_device_i2c = {
 291        .name             = "s3c2410-i2c",
 292        .id               = -1,
 293        .num_resources    = ARRAY_SIZE(s3c_i2c_resource),
 294        .resource         = s3c_i2c_resource,
 295};
 296
 297EXPORT_SYMBOL(s3c_device_i2c);

根据platform总线上device和driver的匹配规则可知,I2C 的platform driver的名字是s3c2410-i2c。


903/* device driver for platform bus bits */
 904
 905static struct platform_driver s3c2410_i2c_driver = {
 906        .probe          = s3c24xx_i2c_probe,
 907        .remove         = s3c24xx_i2c_remove,
 908        .resume         = s3c24xx_i2c_resume,
 909        .driver         = {
 910                .owner  = THIS_MODULE,
 911                .name   = "s3c2410-i2c",
 912        },
 913};

8.5    注册platform_driver

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwjjds.html