Linux的内核模块

最近学习到了这里,也记录一下

内核模块是Linux内核向外部提供的一个插口,其全称为动态可加载内核模块(Loadable Kernel Module,LKM),简称为模块。Linux内核之所以提供模块机制,是因为它本身是一个单内核(monolithic kernel)。单内核的最大优点是效率高,因为所有的内容都集成在一起,但其缺点是可扩展性和可维护性相对较差,模块机制就是为了弥补这一缺陷。

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

一般是在设备驱动程序、文件系统等地方使用模块,而对Linux内核中极为重要的地方,如进程管理和内存管理等,无法通过模块来实现,必须直接对内核进行修改来完成。

利用内核模块的动态装载性具有如下优点:
  ·将内核映象的尺寸保持在最小,并具有最大的灵活性;
  ·便于检验新的内核代码,而不需重新编译内核并重新引导。
但是,内核模块的引入也带来了如下问题:
  ·对系统性能和内存利用有负面影响;
  ·装入的内核模块和其他内核部分一样,具有相同的访问权限,因此,差的内核模块会导致系统崩溃;
  ·为了使内核模块访问所有内核资源,内核必须维护符号表,并在装入和卸载模块时修改这些符号表;
  ·有些模块要求利用其他模块的功能,因此,内核要维护模块之间的依赖性。
  ·内核必须能够在卸载模块时通知模块,并且要释放分配给模块的内存和中断等资源;
  ·内核版本和模块版本的不兼容,也可能导致系统崩溃,因此,严格的版本检查是必需的。
  尽管内核模块的引入同时也带来不少问题,但是模块机制确实是扩充内核功能一种行之有效的方法,也是在内核级进行编程的有效途径。

就比如说操作系统的驱动程序需要代码和缓冲空间。如果某驱动程序(或其他操作系统服务)不常使用,可以不必在内存中保留该代码和数据,这部分空间可以用于其他目的,这类代码有的时候称为暂时操作系统代码,它们会根据需要去调入或者是调出,因此使用这样的代码,可以在程序执行的时候去动态的改变操作系统的大小

编写一个简单的内核模块

  • 1、编译源文件
vi helloworld.c

这里写图片描述

程序中的MODULE_LICENSE(“GPL”)用于声明模块的许可证,可以将模块定义为获得GPL Version 2或更新版本许可的模块,根据GPLv2授权要求,衍生版本也就是修改后的Linux内核源代码必须公开

  • 2、编译 gcc –c helloworld.c,我们也可以去使用gcc –DMODULE –c helloworld.c,参数–DMODULE通知编译程序这是一个模块而不是一个普通文件,不过我们在代码中已声明是模块,所以可以直接用gcc –c helloworld.c

这里需要注意的是,在Linux当中如果我们需要自己去写内核模块的话,我们就要去包含linux/module.h这个头文件,这个文件包含了对模块的结构定义以及模块的版本控制,而函数init_module()和函数cleanup_module()是模块编程中最基本的也是必须的两个函数。init_module()向内核注册模块提供新功能;cleanup_module负责注销所有由模块注册的功能,以及printk函数是由Linux内核定义的,功能与用户态下的printf函数相似。字符串<1>表示消息的优先级,printk对于不同优先级的消息进行不同的处理,在这儿使用高优先级是因为默认优先级的消息可能不能显示在控制台上

  • 3、安装内核模块insmod helloworld.o,如果遇到版本不匹配问题,可使用 insmod -f helloworld.o

  • 4、查看内核模块的安装情况,验证安装成功,使用使用 lsmod 或者 cat /proc/modules 命令
    这里写图片描述

如果我们需要卸载内核模块则使用 rmmod helloworld,可以看到下面有Goodbye!的输出

这里写图片描述

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ZCMUCZX/article/details/80336798
个人分类: Linux基础
上一篇49秒的创意设计
下一篇进程交换和连续内存分配
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭