欢迎来到军工软件开发人才培养基地——学到牛牛

Linux内核模块

时间:2024-05-06 07:01:10 来源:学到牛牛

1.模块示例

首先,创建一个名为xuedaon.c的C源文件,内容如下:

#include <linux/module.h>  

#include <linux/kernel.h>  

  

static int __init xuedaon_init(void)  

{  

    printk(KERN_INFO "modules init!\n");  

    return 0;  

}  

  

static void __exit xuedaon_exit(void)  

{  

    printk(KERN_INFO "modules exit!\n");  

}  

  

module_init(xuedaon_init);  

module_exit(xuedaon_exit);  

MODULE_LICENSE("GPL"); //模块许可证(通常必须)

MODULE_DESCRIPTION(“Xuedaon Module”);    //模块描述(可选)

MODULE_VERSION(“V1.0”);    //模块版本(可选)

MODULE_ALIAS(“a simple module”);  //模块别名(可选)

MODULE_AUTHOR(“xuedaon.com”);  //模块开发作者(可选)

然后,创建一个名为Makefile的文件,内容如下:

KDIR= /lib/modules/$(uname -r)/build

default:

make -C  $(KDIR)  M=$(pwd) modules

clean:

make -C  $(KDIR)  M=$(pwd) modules

obj-m += xuedaon.o  

这个Makefile文件定义了模块的名称和源文件。obj-m指定了模块名称。

接下来,打开终端并进入包含Makefile和源文件的目录,然后运行以下命令来编译模块:

make

这将在内核源代码树的相应目录下编译模块。编译完成后,会生成一个名为xuedaon.ko的模块文件。

要加载模块,可以使用以下命令:

sudo insmod xuedaon.ko

要卸载模块,可以使用以下命令:

sudo rmmod xuedaon

要查看系统中已插入模块,可以使用以下命令:

sudo lsmod

加载模块后,可以在内核日志中看到打印的消息,可以使用dmesg命令查看内核日志。

2.Makefile内容详解

make -C $(KDIR) M=moddir modules 是一个在Linux内核开发中常用的命令,用于编译内核模块。这个命令的各个部分的意义如下:

1.make: 调用 make 工具,它是用于自动化构建的工具。

2.-C  $(KDIR): 这个选项告诉 make 工具更改到 $(KDIR)目录,并从那里开始执行。通常是内核源代码的目录。

3.M=moddir: 这个选项指定模块的源代码所在的路径。在内核开发中,有时模块的源代码并不直接位于内核源代码的相应目录下,而是位于另一个位置。使用 M= moddir可以告诉 make 工具去哪里查找模块的源代码。

4.modules: 这个目标告诉 make 工具要编译所有的模块。

综上所述,此命令为进入$(KDIR)目录,并从那里开始编译所有的模块,其中模块的源代码位于 moddir目录。

3.MODULE_LICENSE

MODULE_LICENSE() 是一个宏,通常在 Linux 内核模块的源代码中使用,用于声明模块的许可证类型。MODULE_LICENSE() 宏是用于在 Linux 内核模块中声明许可证信息的一种机制,它有助于确保模块遵循适当的许可协议并正确地与内核交互。

这个宏的目的是为了告知内核模块的许可证信息,以便内核可以正确地处理模块的许可要求。使用 MODULE_LICENSE() 宏可以帮助确保模块遵循适当的许可协议,并确保模块与内核的许可要求兼容。

例如,如果一个模块遵循 GNU General Public License (GPL),则可以在模块的源代码中使用 MODULE_LICENSE("GPL") 宏来声明这一点。这样,当内核加载和链接该模块时,它会检查模块的许可证是否与内核的许可证兼容,并根据需要进行相应的处理。

声明可以如下:

1."GPL" 是指明了 这是GNU General Public License的任意版本

2.“GPL v2” 是指明 这仅声明为GPL的第二版本

3."GPL and addtional"

4. "Dual BSD/GPL"

5.“Dual MPL/GPL"

6."Proprietary"  私有的

除非你的模块显式地声明一个开源版本,否则内核会默认你这是一个私有的模块(Proprietary)。

4.module_init和module_exit宏

module_init 是一个宏,用于在 Linux 内核模块中指定模块的初始化函数。当内核加载模块时,module_init 宏指定的函数将被调用,以便进行模块的初始化工作。

module_init 宏的语法如下:

module_init(function)

其中,function 是模块的初始化函数的名称。该函数必须具有以下原型:

int function(void)

当模块被加载时,内核将调用 module_init 宏指定的函数,并传递 NULL 作为参数。初始化函数应该返回一个整数值,表示模块的初始化状态。如果初始化成功,应该返回 0;如果初始化失败,可以返回一个负的错误代码。

module_exit 是一个宏,用于在 Linux 内核模块中指定模块的退出函数。当内核卸载模块时,module_exit 宏指定的函数将被调用,以便进行模块的清理工作。它的调用形式和module_init几乎一致,除了不用关注其返回值。

当模块被卸载时,内核将调用 module_exit 宏指定的函数,并传递 NULL 作为参数。退出函数应该执行模块所需的任何清理操作,例如释放资源或关闭设备驱动程序。