热度 2
2023-4-6 22:27
1476 次阅读|
0 个评论
1、前言 我们在编写一个模块的时候,常常使用一些宏定义来标识模块的作者,版本,以及相关信息的描述,如: MODULE_AUTHOR 、 MODULE_DESCRIPTION 、 MODULE_LICENSE 、 MODULE_ALIAS 等,那么这些宏是如何进行管理的呢? 小处诚实非小事! 今天带着大家,我们来深入分析一下这些宏定义,其内部的奥秘! 2、MODULE_XXX分析 在上面提到的 MODULE_AUTHOR 、 MODULE_DESCRIPTION 、 MODULE_LICENSE 、 MODULE_ALIAS ,这些宏定义,查看其声明,我们发现: /* For userspace: you can also call me... */ #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) /* Soft module dependencies. See man modprobe.d for details. * Example: MODULE_SOFTDEP("pre: module-foo module-bar post: module-baz") /* * The following license idents are currently accepted as indicating free * software modules * * "GPL" * "GPL v2" * "GPL and additional rights" * "Dual BSD/GPL" * "Dual MIT/GPL" * "Dual MPL/GPL" * * The following other idents are available * * "Proprietary" * * There are dual licensed components, but when running with Linux it is the * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL * is a GPL combined work. * * This exists for several reasons * 1. So modinfo can show license info for users wanting to vet their setup * is free * 2. So the community can ignore bug reports including proprietary modules * 3. So vendors can do likewise based on their own policies */ #define MODULE_LICENSE(_license) MODULE_INFO(license, _license) /* * Author(s), use "Name " or just "Name", for multiple * authors use multiple MODULE_AUTHOR() statements/lines. */ #define MODULE_AUTHOR(_author) MODULE_INFO(author, _author) /* What your module does. */ #define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) 无论是 MODULE_LICENSE 、 MODULE_AUTHOR 、还是 MODULE_DESCRIPTION ,其最终都调用了 MODULE_INFO 的宏定义,并将对应的字符串参数传入进去。 那么关键就在于 MODULE_INFO 这个宏定义了! 3、MODULE_INFO 查看 MODULE_INFO 的定义,写成了我们看不懂的形式,下面我们来逐步分析 // include/linux/module.h /* Generic info of form tag = "info" */ #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) // include/linux/moduleparam.h #define __MODULE_INFO(tag, name, info) \ static const char __UNIQUE_ID(name) \ // __used __attribute__((section(".modinfo"), unused, aligned(1))) \ // = __stringify(tag) "=" info static const char __UNIQUE_ID ( author ) \ __used __attribute__ (( section ( ".modinfo" ), unused , aligned ( 1 ))) \ = __stringify ( author ) "=" donge // #define ___PASTE(a,b) a##b // #define __PASTE(a,b) ___PASTE(a,b) static const char __UNIQUE_ID_author__COUNTER__ \ __used __attribute__ (( section ( ".modinfo" ), unused , aligned ( 1 ))) \ = __stringify ( author ) "=" donge // #define __stringify_1(x...) #x // #define __stringify(x...) __stringify_1(x) static const char __UNIQUE_ID_author0 $ modinfo arobot-rp-r8.ko filename: /home/dong/WorkSpace/arobot_buildroot/output/r8-common-vrf/build/linux-refs_remotes_origin_r8_develop/drivers/char/arobot-rp-r8.ko description: Arobot processor B driver author: Amicro license: GPL alias: of:N*T*Carobot,r8-rpC* alias: of:N*T*Carobot,r8-rp depends: intree: Y name: arobot_rp_r8 vermagic: 4 .19.123 SMP preempt mod_unload ARMv7 p2v8 OK,上文较为详细介绍了 Kernel 内部 MODULE_INFO 的详细实现,还有一些重要的知识点没有展开介绍,例如: __attribute__((section(".xxx"))) 的作用,后续再起一篇文章介绍。