Article directory
1 Introduction
When we write a module, we often use some macro definitions to identify the author, version, and description of related information, such as: , , , MODULE_AUTHOR
etc. MODULE_DESCRIPTION
How MODULE_LICENSE
are MODULE_ALIAS
these macros managed?
Small things are honesty!
With everyone today, let's analyze these macro definitions and their internal mysteries in depth!
2. Analysis of MODULE_XXX
In the above-mentioned MODULE_AUTHOR
, , MODULE_DESCRIPTION
, MODULE_LICENSE
, MODULE_ALIAS
these macro definitions, looking at their declarations, we found:
/* 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" [GNU Public License v2 or later]
* "GPL v2" [GNU Public License v2]
* "GPL and additional rights" [GNU Public License v2 rights and more]
* "Dual BSD/GPL" [GNU Public License v2
* or BSD license choice]
* "Dual MIT/GPL" [GNU Public License v2
* or MIT license choice]
* "Dual MPL/GPL" [GNU Public License v2
* or Mozilla license choice]
*
* The following other idents are available
*
* "Proprietary" [Non free products]
*
* 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 <email>" 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)
Whether it is MODULE_LICENSE
, MODULE_AUTHOR
, or MODULE_DESCRIPTION
, it will eventually call MODULE_INFO
the macro definition and pass in the corresponding string parameters.
Then the key lies in MODULE_INFO
the definition of this macro!
3、MODULE_INFO
The definition of viewing MODULE_INFO
is written in a form that we can't understand. Let's analyze it step by step
// 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
// include/linux/compiler-gcc.h
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
// include/linux/compiler_types.h
#define ___PASTE(a,b) a##b
#define __PASTE(a,b) ___PASTE(a,b)
The above is MODULE_INFO
the complete definition of , and its purpose is to generate unique strings .
Let's take an example:
MODULE_AUTHOR(donge)
// #define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)
MODULE_INFO(author, donge)
// #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
__MODULE_INFO(author, author, donge)
//#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 __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
static const char __PASTE(__PASTE(__UNIQUE_ID_, author), __COUNTER__)[] \
__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
// __COUNTER__会被展开为一个从0开始的整数,每次调用都会加一
static const char __UNIQUE_ID_author0[] \
__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[] \
__used __attribute__((section(".modinfo"), unused, aligned(1))) \
= "author=donge"
Now that we know these macro definitions well, let's analyze the meaning of some attributes
-
aligned
: Specify the starting address alignment of the variable or structure field (in bytes) -
used
: Tells the compiler to keep a static function in the object file even if it is not referenced. -
attribute__((used))
: is marked in object files to prevent the linker from removing unused sections. -
__attribute__((section(".modinfo")))
: Compile the modified variable or function to a specific location in memory space -
__attribute__((used))
: describe static variables -
unused
: Indicates that the function or variable may not be used to avoid warning messages from the compiler. -
#和##
: We use # to change the macro parameter into a string, and use ## to paste two macro parameters together.
4. View module information
MODULE_XXXX
How do we view the information we have set? by lsmod xxx.ko
command
[r8-common-vrf dong@ubuntu ~/WorkSpace/arobot_buildroot/output/r8-common-vrf/build/linux-refs_remotes_origin_r8_develop/drivers/char]$ 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, the above has introduced the
Kernel
internalMODULE_INFO
detailed implementation in more detail, and there are still some important knowledge points that have not been introduced, such as:__attribute__((section(".xxx")))
the role of the function, and another article will be introduced later.
Like + follow, never get lost