【Detailed Explanation of Linux Driver Basics】| Declaration and Description of Linux Modules

img
Personal homepage: Dong Ge talks about technology
I am Dong Ge, a new star creator in the embedded field
Creation concept: Focus on sharing high-quality embedded articles, so that everyone can read something!
img


image-20230406223702990

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_AUTHORetc. MODULE_DESCRIPTIONHow MODULE_LICENSEare MODULE_ALIASthese 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_ALIASthese 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_INFOthe macro definition and pass in the corresponding string parameters.

Then the key lies in MODULE_INFOthe definition of this macro!

 

3、MODULE_INFO

The definition of viewing MODULE_INFOis 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_INFOthe 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_XXXXHow do we view the information we have set? by lsmod xxx.kocommand

[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 Kernelinternal MODULE_INFOdetailed 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.

 

img

Like + follow, never get lost

img

Guess you like

Origin blog.csdn.net/dong__ge/article/details/130003509