话说内核模块间的依赖
发布时间:2020-12-13 22:34:25 所属栏目:百科 来源:网络整理
导读:每个模块在编译时(假设模块名为xxx),会自动生成一个xxx.mod.c的文件,该文件会链接到xxx模块中去。 xxx.mod.c中定义了一个变量struct module __this_module以及此模块依赖的模块列表__module_depends。 __module_depends的定义如下,可见其内容是在加载时
每个模块在编译时(假设模块名为xxx),会自动生成一个xxx.mod.c的文件,该文件会链接到xxx模块中去。
xxx.mod.c中定义了一个变量struct module __this_module以及此模块依赖的模块列表__module_depends。 __module_depends的定义如下,可见其内容是在加载时动态生成。 static const char __module_depends[] __used __attribute__((section(".modinfo"))) = "depends="; struct module中则包含了较多的内容,包括模块名称,init与exit函数等。其中还有一个重要的成员是引用计数ref。引用计数一般是通过try_module_get增加的。 这个引用计数通常会影响模块的卸载。 sys_delete_module中会通过module_refcount获取要卸载的模块的引用计数。 要想让引用计数能正常工作,我们编写模块代码时,通常是在某个结构体的赋值代码中,加入如下一行。取决于模块的功能类型,这个结构体可能是file_operations、platform_driver、proto、proto_ops等。 .owner = THIS_MODULE 以下情形会影响模块的引用计数。模块间的依赖关系。例如,模块A依赖B。A加载时,内核要解析A引用的外部符号。见module.c中的resolve_symbol。如果发现A引用的某个外部符号在B中,就调用use_module,记录A对B的依赖。use_module会增加B的引用计数,同时将A加入到B的使用者列表中去。 各种业务流程方面也会导致引用计数变化,好在内核框架代码已经为我们做好了这一切。 例如,当用户调用C库函数open打开一个文件时,__dentry_open中会调用fops_get获取要打开的文件的file_operations。而fops_get的定义如下,这就实现了对目标模块的引用计数的增加。 #define fops_get(fops) (((fops) && try_module_get((fops)->owner) ? (fops) : NULL)) 再如,当用户创建一个socket时,__sock_create函数内会有如下代码。对实现此protocol family的模块,增加引用计数。 /* * We will call the ->create function,that possibly is in a loadable * module,so we have to bump that loadable module refcnt first. */ if (!try_module_get(pf->owner)) goto out_release; 看到没有,这些业务流程,都使用了owner成员。 所以,编写模块代码时,要是把“.owner = THIS_MODULE”这句话漏了可就歇菜了 ^_^ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |