Linux 内核模块编写

内核模块是Linux内核向外部提供的一个接口,是内核的一部分,但没有被编译到内核里面去

 linux内核之所以提供模块机制,是因为它本身是一个单内核。而单内核的最大优点就是效率高,因为所有的内容都集成在一起,但其缺点是可扩展性和可维护性相对较差,模块机制就是为了弥补这一缺陷

什么是模块,模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被链接到内核作为内核的一部分在内核空间运行,这与运行在用户空间的进程是不同的。模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或者其他内核上层的功能。

编写简单的内核模块

一个内核模块至少需要两个函数

1.module_init()    模块加载函数

  当模块被插入内核时调用它

2.module_exit()  模块卸载函数

  当模块从内核移走时调用它

任何模块都要包含的三个头文件:

#include <linux/module.h>

#include <linux/kernel.h>

#incldue <linux/init.h>

module.h头文件包含了对模块的版本控制;

kernel.h包含了常用的内核函数;

init.h包含了宏__init和__exit,宏__init告诉编译程序相关的函数和变量仅用于初始化,编译程序将标有__init的所有代码存储到特殊的内存段中,初始化结束就释放这段内存。

注:printk()函数

该函数是由内核定义的,功能和C库中的printf()类似,它把要打印的日志输

出到终端或系统日志。字符串中的<1>是输出的级别,表示立即在终端输出。

内核模块的入口函数和出口函数

 内核模块的入口函数和出口函数是模块编程中最基本的也是必须的两个函数。入口函数向内核注册模块所提供的新功能;出口函数负责注销所有由模块注册的功能。例如;


Static int _init lkm_init(void)
{
    printk(KERN_INFO “Hello World!\n”);
    return 0;
}
Static void _exit lkm_exit(void)
{
    printk(KERN_INFO “Goodbye!\n”);
}

加载模块、卸载模块和声明许可证

module_init和module_exit,这两个函数分别在加载和卸载模块时被调用。

 module_init(lkm_init);
 module_exit(lkm_exit);

声明许可证:

MODULE_LICENSE(“GPL”);

以上是hello world的.c文件编写格式


内核模块的Makefile文件

      内核模块不是独立的可执行文件,但在运行时其目标文件被链接到内核中。只有超级用户才能加载和卸载模块。

Makefile文件的基本内容如下:

1.obj-m:=module_example.o                       

#产生的module_example模块的目标文件

2.CURRENT_PATH := $(shell pwd)

#模块所在的当前路径

3.LINUX_KERNEL :=$(shell uname -r)

#linux内核源代码的当前版——本

4.LINUX_KERNEL_PATH := /user/src/linux-headers-¥(LIUNX_KERNEL)

#linux内核源代码的绝对路径

5.all:

6.        make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules

#编译模块

7.claen:

8.        make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean

#清理模块

obj-m :=这个赋值语句的含义是说明要使用目标文件module_example.o建立一个模块,最后生成的模块名为module_example.ko。.o文件是经过编译和汇编,而没有经过链接的中间文件。

注:makefile文件中,若某一行是命令,则它必须以一个Tab键开头。

装载模块

    当编译好模块,就可以用insmod命令将新的模块插入到内核中,如:

insmod module_example.ko

然后,可以用lsmod命令查看模块是否正确地插入到了内核中。模块的输出由printk()产生。该函数默认打印系统文件/var/log/messages的内容。

卸载模块

使用rmmod命令加上在insmod中看到的模块名,就可以从内核中移除该模块:

        rmmod  module_example

具体实现可以看编写一个简单的内核模块程序Hello World!-CSDN博客

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Linux内核模块编写是指在Linux操作系统编写可动态加载和卸载的内核模块,以扩展操作系统的功能或添加新的设备驱动程序。内核模块编写需要掌握C语言编程技能和Linux内核的基本知识,包括内核数据结构、系统调用、进程管理、内存管理、设备驱动等。编写内核模块需要遵循一定的规范和流程,包括编写Makefile文件、定义模块参数、注册模块、实现模块功能、编写模块文档等。内核模块编写对于Linux系统的开发和维护非常重要,可以为系统添加新的功能和设备支持,提高系统的可靠性和性能。 ### 回答2: Linux内核模块是一段能够扩展或增强Linux内核功能的代码,它可以动态地加载或卸载到内核中运行。Linux内核模块编写需要遵循一定的规范和步骤,下面是详细介绍。 一、编写和编译内核模块 1、编写内核模块源代码,通常以.c或.cpp文件为扩展名。 2、生成一个Makefile文件,编写编译和链接内核模块所需的命令。 3、进入内核源代码目录,运行make命令编译内核模块,生成模块的.ko文件。 二、加载和卸载内核模块 1、运行insmod命令加载内核模块到内核中,在加载模块时需要指定模块的路径和名称。 2、运行rmmod命令从内核中卸载内核模块,在卸载模块时需要指定模块的名称。 三、接口函数 内核模块需要实现init和exit函数,分别用于模块的初始化和卸载。例如: ``` static int __init my_module_init(void) { /* 模块初始化代码 */ return 0; } static void __exit my_module_exit(void) { /* 模块卸载代码 */ } module_init(my_module_init); module_exit(my_module_exit); ``` 四、模块参数 内核模块可以接受一些通过命令行传递的参数,在模块加载时指定。例如: ``` static char *my_string = "hello"; module_param(my_string, charp, 0); ``` 这段代码定义了一个名为my_string的字符串类型参数,初始值为"hello",模块加载时可以使用如下命令指定: ``` insmod my_module.ko my_string="world" ``` 五、调试技巧 1、使用pr_info、pr_err等宏函数输出调试信息。 2、使用printk_ratelimit限制调试信息的输出频率。 3、使用gdb对内核模块进行调试。 以上就是Linux内核模块编写的基本流程和注意事项,需要注意的是内核模块编写需要具备一定的Linux内核编程基础和相关知识。 ### 回答3: 在Linux操作系统中,内核模块是一个可以动态加载或卸载的程序。内核模块可以扩展操作系统的功能,例如添加新的设备驱动程序、实现新的系统调用、修改内核运行时行为等。而内核模块编写就是指为Linux内核添加新功能的过程。 内核模块编写可以分为以下几个步骤: 1. 准备开发环境:向Linux内核开发组申请开发账户,并下载内核源代码。编译好内核源代码,并安装相关的开发工具。 2. 编写代码:根据需求编写内核模块的源代码。在Linux内核中编写模块需要使用C语言,并按照内核代码风格格式要求来编写编写的代码最终会成为一个称之为内核对象文件的二进制文件。 3. 编译内核模块:使用内核源代码目录下的Makefile文件来编译内核模块。Makefile文件主要是用来控制编译过程的,其中包含了编译规则、库文件、头文件、链接文件等重要的指令。使用“make”命令可以执行Makefile文件中的编译规则,生成一个后缀名为.ko的内核模块二进制文件。 4. 加载内核模块:使用insmod命令来加载内核模块。加载成功后,内核会告知用户已经成功注册了一个新的驱动程序。可以使用lsmod命令来查看当前系统中已经加载的内核模块。 5. 卸载内核模块:使用rmmod命令来卸载已加载的内核模块。卸载内核模块后,内核会告知用户已经成功注销了一个驱动程序。 总之,内核模块编写操作系统内核开发的一部分,需要开发者具备扎实的C语言技能,并了解操作系统内核模块相关的底层知识。内核模块编写能够使我们更加深入地了解Linux内核,并扩展操作系统的功能。在编写内核模块时要格外小心,因为内核模块代码是运行在内核空间中的,不当操作可能会导致系统崩溃,因此需要十分谨慎。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值