什么是内核模块?

内核模块是一段根据需要装卸入内核的代码。它们在不需要重新启动电脑的情况下延伸了内核的功能
如果没有模块,我们就必须将新功能载入单片内核镜像中。

#include<linux/module.h>/*所有的模块都需要这个头文件*/
#include<linux/kernel.h>/*KERN_ALERT 作为printk的参数,用于报告消息,表示必须立即采取措施*/
#include<linux/init.h>/*宏定义,内核的初始化和注销函数就在这个文件中*/
static int donothing_init(void)
{
    printk(KERN_ALERT"This is a DoNothing module\n");
    return 0;
}
static void donothing_exit(void)
{
    printk(KERN_ALERT"DoNothing module is unloaded\n");
}
//一个普通程序一般会由main()开始,一个模块一般则是由module_init()开始
module_init(donothing_init);
//一般由module_exit()结束
module_exit(donothing_exit);
/*内核模块必须有两个方法,一个叫做(donothing_init)的“初始化”函数,
当模块内置到内核时调用;一个叫做donothing_exit函数,在结束的时候调用*/

编译内核模块

内核模块需要用特定的编译gcc选项来使他们工作。
GNU编译器集合(GNU Compiler Collection(GCC)) 是一个由GNU计划组制作的编译系统,支持多种程序语言。GCC是GNU工具链的关键组件,也是大多数类UNIX操作系统的标准编译器。

Makefile

Makefile是一个文件(默认名为“Makefile”),包含make build自动化工具用来生成目标/目标的一组指令。
Makefile起源于类Unix系统,并且仍然是此类环境中的主要软件构建机制
MaFig文件指导如何编译和链接程序。
Makefile的工作原理是,如果文件的依赖项比创建/重新创建的文件新,则只需重新创建文件。
对于大型软件项目,如果只更改了几个源文件,则使用Makefile可以显著减少构建时间。

编译内核模块Makefile

内核模块需要使用某些gcc选项进行编译才能使它们正常工作。 此外,它们还需要使用定义的某些符号进行编译。

  • 这些设置通常存储在Makefile中。
  • 它们的依赖项在Makefile中指定。
  • Makefile定义便以文件的规则
KERNEL_DIR = /usr/src/linux-headers-x.xx.x-xx-generic

obj-m:=nothing.o

all:
        make -C $(KERNEL_DIR) M=$(PWD)

obj-m: 指定构建为可加载内核模块的目标文件。 构建外部模块的命令是:
make -C<path_to_kernel_src>M=$PWD

-C $(KERNEL_DIR):内核源所在的目录。 “make”实际上会在执行时更改为指定的目录,并在完成时更改回来。
KERNEL_DIR:指内核源目录的路径。
M = $ PWD:通知make正在构建外部模块。 赋予“M”的值是外部模块所在目录的绝对路径。

在软件开发中,make是一个构建自动化工具,它通过读取名为Makefiles的文件来自动地从源代码构建可执行程序和库,这些文件指定了如何派生目标程序。
虽然集成开发环境和特定于语言的编译器功能也可用于管理构建过程,但make仍然广泛使用,尤其是在Unix和类Unix操作中系统。

除了构建程序之外,Make还可用于管理任何项目,其中某些文件必须在其他文件发生变化时自动更新。

载入模块

输入如下指令
sudo insmod ./nothing.ko

  • 它会将模块“insert”(加载)到内核中。 由于它是一个需要root权限的命令,因此使用“sudo”。
  • 在加载过程中,调用初始化函数并打印消息。
  • 当前加载到内核中的内核模块可以通过“lsmod”命令查看。

  • 加载到内核中的所有模块都列在/proc/modules中。 来吧,使用cat命令看看你的模块真的是内核的一部分。
cat /proc/modules

modinfo nothing.ko

sudo rmmod nothing.ko

rmmod-一个把模块从Linux内核移除的简单指令。

dmesg

(显示消息或驱动程序消息)是大多数类Unix操作系统上的命令,它打印内核的消息缓冲区。此命令的输出通常包含设备驱动程序生成的消息。

MODULE_DESCRIPTION()用于描述模块的功能,
MODULE_AUTHOR()声明模块的作者

Logo

更多推荐