Linux基础: 解密module_init幕后的故事
来源:互联网 发布:海外代购报告 淘宝 编辑:程序博客网 时间:2024/05/21 10:41
在Linux底下写过driver模块的对这个宏一定不会陌生。module_init宏在MODULE宏有没有定义的情况下展开的内容是不同的,如果这个宏没有定义,基本上表明阁下的模块是要编译进内核的(obj-y)。
1.在MODULE没有定义这种情况下,module_init定义如下:
#define module_init(x) __initcall(x);
因为
#define __initcall(fn) device_initcall(fn)
#define device_initcall(fn) __define_initcall("6",fn,6)
#define __define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __used \
__attribute__((__section__(".initcall" level ".init"))) = fn
所以,module_init(x)最终展开为:
static initcall_t __initcall_##fn##id __used \
__attribute__((__section__(".initcall" level ".init"))) = fn
更直白点,假设阁下driver所对应的模块的初始化函数为int gpio_init(void),那么module_init(gpio_init)实际上等于:
static initcall_t __initcall_gpio_init_6 __used __attribute__((__section__(".initcall6.init"))) =gpio_init;
就是声明一类型为initcall_t(typedef int (*initcall_t)(void))函数指针类型的变量__initcall_gpio_init_6并将gpio_init赋值与它。
这里的函数指针变量声明比较特殊的地方在于,将这个变量放在了一名为".initcall6.init"节中。接下来结合vmlinux.lds中的
.initcall.init : AT(ADDR(.initcall.init) - (0xc0000000 -0x00000000)) {
__initcall_start = .;
*(.initcallearly.init) __early_initcall_end = .; *(.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_end = .;
}
以及do_initcalls:
static void __init do_initcalls(void)
{
initcall_t *call;
for (call = __initcall_start; call < __initcall_end; call++)
do_one_initcall(*call);
/* Make sure there is no pending stuff from the initcall sequence */
flush_scheduled_work();
}
那么就不难理解阁下模块中的module_init中的初始化函数何时被调用了:在系统启动过程中start_kernel()->rest_init()->kernel_init()->do_basic_setup()->do_initcalls()。
- Linux基础: 解密module_init幕后的故事
- Linux基础: 解密module_init幕后的故事
- Linux基础: 解密module_init幕后的故事
- Linux基础: 解密module_init幕后的故事
- Linux基础: 解密module_init幕后的故事
- 解密module_init幕后的故事
- 解密module_init幕后的故事
- Linux基础: 解密module_init幕后…
- [Linux driver]解密module_init
- emit,幕后的故事
- Git幕后的“故事”
- Git幕后的“故事”
- 解密module_init
- 解密module_init
- 解密module_init
- 解密module_init
- 解密module_init
- 解密module_init
- Xutils源码文件下载方法的调用流程
- void及void指针含义的深刻解析
- HDU——5062 Beautiful Palindrome Number
- jQuery验证控件jquery.validate.js使用说明+中文API
- 47JavaScript-1 变量 with语句 数组 字符串 定时器
- Linux基础: 解密module_init幕后的故事
- 对自己大学专业学习的期望和目标
- NMLOLO
- android开发之Notification_通知栏消息
- C++ namespace
- 4.3 创建控制台应用程序
- linux 源码安装出现createdb: could not connect to database template1: FATAL: role "postgres" does not exis
- 深入理解java虚拟机
- Qsort()函数