原生代码里有很多进一步对 module_init 封装的宏,其实做的也就是注册驱动这件事。 例如常见的i2c驱动的起点(include\linux\i2c.h): module_i2c_driver 我们把i2c驱动的结构体 struct i2c_driver xxx 使用 module_i2c_driver(xxx) 注册就可以了,不需要再实现初始化函数或者使用 module_init 。 我们把 module_dri...
示例: module_init (i2c_init) ; static int __initcall_i2c_init6 __used __attribute__((__section__( initcall6.init )) = i2c_init ; 在initcall6.init 这个 section 里面定义了一个函数指针变量 __initcall_i2c_init6 , 指针赋值为 i2c_init 函数地址; 调用 do_basic_setup -> do_initcalls ...
c0032c34t __initcall_v4l2_i2c_drv_init6 c0032d24 t__initcall_video_init6 c0032d28 t__initcall_video2_init6 对于同一级别的 __initcall的次序 主要由MakeFile中.o文件的链接次序决定,具体看Kernel下的主Makefile --- Build vmlinux 以及kernel/driver 下的obj-y /* end */...
所有的__init函数在区段.init.text区段中,同时还在.initcall.init中还保存了一份函数指针,在初始化时内核会通过这些函数指针调用这些__init函数指针,并在整个初始化完成后,释放整个init区段(包括.init.text,.initcall.init等)。 这些函数在内核初始化过程中的调用顺序只和这里的函数指针的顺序有关。 中所述的这...
2、module_driver/module_i2c_driver 在device.h中: #definemodule_driver(__driver, __register, __unregister, ...) \ static int __init __driver##_init(void) \ { \ return __register(&(__driver) , ##__VA_ARGS__); \ } \ module_init(__driver##_init); \ static void __exit _...
MODULE_DESCRIPTION("I2C driver"); MODULE_SUPPORTED_DEVICE("I2C"); const char *g_device_name = "i2c"; static int g_major; static struct class *g_class_i2c; static struct device *g_dev_i2c; static u32 *g_base0 = NULL; static u32 g_slaveAddress = 0; // transfer timeout time in...
c0032c34t __initcall_v4l2_i2c_drv_init6 c0032d24 t__initcall_video_init6 c0032d28 t__initcall_video2_init6 对于同一级别的 __initcall的次序 主要由MakeFile中.o文件的链接次序决定,具体看Kernel下的主Makefile --- Build vmlinux 以及kernel/driver 下的obj-y /...
remove,// ...};module_i2c_driver(demo_i2c_drv);// plathform 驱动staticstructplatform_driver...
c0032c34t __initcall_v4l2_i2c_drv_init6 c0032d24 t__initcall_video_init6 c0032d28 t__initcall_video2_init6 对于同一级别的 __initcall的次序主要由MakeFile中.o文件的链接次序决定,具体看Kernel下的主Makefile --- Build vmlinux 以及kernel/driver 下的obj-y /...