实践二

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实践二相关的知识,希望对你有一定的参考价值。

 

 

linux内核模块的程序结构有:模块加载函数(必须),模块卸载函数(必须),模块许可证声明(必须),模块参数(可选),模块导出符号(可选),模块作者的等信息声明(可选)。

一个内核模块应该至少包含两个函数。一个“开始”(初始化)的函数被称为init_module(),当内核模块被insmod 加载时被执行,还有一个“结束”(要完成与模块加载函数相反的功能)的函数被称为cleanup_module() ,当内核模块被rmmod 卸载时被执行。实际上,从内核版本2.3.13 开始我们就可以为开始和结束函数起任意的名字了。这可以通过宏module_init()module_exit()实现,需要注意的地方是函数必须在宏的使用前定义,否则会有编译错误。

模块许可证声明描述内核模块的许可权限,格式为MODULE_LICENSE("Dual BSD/GPL")Linux可接受的 LICENSE 包括”GPL","GPL v2""GPL and additional rights""Dual BSD/GPL""Dual MPL/GPL""Proprietary"。可以不加,则系统默认。如果不声明 LICENSE ,模块被加载时,将收到内核的警告。

模块参数是“模块被加载的时候可以被传递给模块的值”,它本身对应模块内部的全部变量。 可以使用module_param(参数名,参数类型,/写权限)为模块定义一个参数。

内核模块可以导出符号(symbol,对应与函数或变量),这样其他模块可以使用本模块中的变量和函数。/proc/kallsyms文件对应这内核符号表,它记录了符号以及符号符号所在的内存地址。

 

 

Linux模块(module)是一些可以作为独立程序来编译的函数和数据类型的集合。内核模块给我们带来的便利是模块本身并不被编译进内核文件,可在内核运行期间动态的安装或卸载。因为如果将模块编译进内核的话,一是生产的内核文件过大,二是如果要添加或删除某个组件要重新编译整个内核。

 

Linux模块可以通过静态或动态地加载到内核空间,静态加载是指在内核启动过程中加载;动态加载是指在内核运行的过程中随时加载。我采用的是动态加载的方法。

 

一个模块被加载到内核中时,它就成为内核代码的一部分,与其他内核代码地位是一样的。模块加载如系统时,系统修改内核中的符号表,将新加载的模块提供的资源和符号加到内核符号表中,这样使模块间可进行通信。

 

 

模块可以使用如下宏导出符号到内核符号表:

    EXPORT_SYMBOL(符号名);

    EXPORT_SYMBOL_GPL(符合名);    //只是用于GPL许可权模块。

导出的符合将可以被其他模块使用,使用前声明以下既可以。

模块作者的等信息声明:

MODULE_AUTOR("作者信息");

MODULE_DESCRIPTION("模块描述信息");

MODULE_VERSION("版本信息");

MODULE_ALIAS("别名信息");

MODULE_DEVICE_TABLE("设备表信息");

对于USB,PCI等设备驱动,通常会创建一个MODULE_DEVICE_TABLE,表示驱动所支持的设备列表。

 

 

 

设计思路:任何一种编程语言的开始都是“hello world”,内核模块编程我也从“hello world”开始,写了一个类似于“hello world”的最简单内核模块——输出姓名与学号的myname.c。类

似于在一个简单的C程序中输出“hello world”要使用printf,当内核要向控制台输出一段内容则需要使用printk

 

为实现输出姓名和学号,我在模块加载函数static int __init name_init(void)中使用printk将变量namenum输出。

 

模块卸载函数中应该还原加载函数的修改,这里因为加载函数并没有对什么内容进行修改,因此卸载函数也应是空的,我写了一个printk作为卸载标识。

 

我想测试一下内核模块传入参数的功能,因此写了模块参数。模块被加载后,在/sys/module目录下将出现以此模块名命名的目录。当"参数读/写权限"0时,表示此“参数不存在sysfs文件系统下对应的文件节点”,如果此模块存在"参数读/写权限"不为0的命令行参数,在此模块的目录下将出现parameters目录,包含一系列“以参数名命名的文件节点”。同时,这些文件的权限就是通过传入module_param()"参数读/写权限",而文件的内容为参数的值。

 

步骤:

  

1、根据自己的需求编写内核模块源代码

 

2、将源代码进行编译,生成.ko文件

 

在编译内核模块时需要用到Makefile

 

 

 

3、用insmod命令加载模块

 

 

 

4、测试内核模块功能

 

 

 

5、用rmmod命令卸载模块

 

以上是关于实践二的主要内容,如果未能解决你的问题,请参考以下文章

Linux及安全实践二

requirejs实践二 加载其它JavaScript与运行

跨年夜,“牧星人”守护实践二十号卫星完成第四次变轨

Redis进阶实践之二如何在Linux系统上安装安装Redis

《软件构架实践》阅读笔记二

实战Docker入门实践二:Docker服务基本操作 和 测试Hello World