什么是模块
概念
模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被链接到内核作为内核的一部分在内核空间运行(但它实际上并不是内核的一部分),这与运行在用户空间的进程是不同的。模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其他内核上层的功能。
模块和应用程序的区别
我们可以看出,内核模块程序不能调用libc库中的函数,它运行在内核空间,且只有超级用户可以对其运行。
另外,模块程序必须通过module_init()和module_exit()函数来告诉内核“我来了”和“我走了”。
为什么会有模块
内核模块是Linux内核向外部提供的一个插口,其全称为动态可加载内核模块(Loadable Kernel Module,LKM),我们简称为模块。Linux内核之所以提供模块机制,是因为它本身是一个单内核(monolithic kernel)。单内核的最大优点是效率高,因为所有的内容都集成在一起,但其缺点是可扩展性和可维护性相对较差,模块机制就是为了弥补这一缺陷。
模块的基本结构
struct module
{
……
/* Startup function. */
int (*init)(void); //入口
……
/* Destruction function. */
void (*exit)(void); //出口
……
};
Hello world程序
hello.c程序
Makefile
#注意M大写f小写
解析:
(注意Makefile里面要求的Tab,前面不能是空格只能是Tab)
1.Makefile文件与hello.c文件放在同一个目录
2.KERNELBUILD :=/lib/modules/$(shell uname -r)/build是编译内核模块需要的Makefile的路径,我的Ubuntu下是
/lib/modules/3.16.0-30/build
3.make -C $(KERNELBUILD) M=$(shell pwd) modules 编译内核模块。-C 将工作目录转到KERNELBUILD,调用该目录下的Makefile,并向这个Makefile传递参数M的值是$(shell pwd) modules。
编译模块
make命令调用第一个命令default,生成的hello.ko就是我们要的内核模块。
insmod装入模块
insmod命令
如果没有输出"Hello,world"可能是因为你在终端模拟器下运行的,因为在终端模拟器下时会把内核消息输出到日志文件/var/log/kern.log中。如果在字符终端运行的话就会直接打出Hello,world
使用 tail /var/log/kernel.log查看
rmmod卸载模块
rmmod命令
make clean清理
make clean命令
清理编译垃圾,hello.ko 也会清理掉。
这个用法其实是自己在Makefile里面写的。
其他补充
modutils是管理内核模块的一个软件包。可以在任何获得内核源代码的地方获取Modutils(modutils-x.y.z.tar.gz)源代码,然后选择最高级别的patch.x.y.z等于或小于当前的内核版本,安装后在/sbin目录下就会有insomod、rmmod、ksyms、lsmod、modprobe等实用程序。当然,通常我们在加载Linux内核时,modutils已经被载入。
1.insmod命令
调用insmod程序把需要插入的模块以目标代码的形式插入到内核中。在插入的时候,insmod自动调用module_init()函数运行。注意,只有超级用户才能使用这个命令,其命令格式为:#insmod [path] modulename.ko
2.rmmod命令
调用rmmod程序将已经插入内核的模块从内核中移出,rmmod会自动运行module_exit()函数,其命令格式为:#rmmod [path] modulename.ko
3.lsmod命令
调用lsmod程序将显示当前系统中正在使用的模块信息。实际上这个程序的功能就是读取/proc文件系统中的文件/proc/modules中的信息,其命令格式为:#lsmod
4.ksyms命令
ksyms这个程序用来显示内核符号和模块符号表的信息。与lsmod相似,它的功能是读取/proc文件系统中的另一个文件/proc/kallsyms。
问题解决
make[2]: *** 没有规则可以创建“/home/hello.o”需要的目标“/home/hello.c”
hello.c所在文件夹的名字出现了问题。
我出现问题是因为我的文件夹名字中间出现了空格,把空格去掉之后就成功了。
Makefile:6: *** 遗漏分隔符 。 停止。
这个是在写Makefile的时候每行前面的空白不是Tab而是空格
内核源码下载问题
本机内核版本
apt-cache search linux-source
我的版本是3.13.0
下载源码
sudo apt-get install linux-source-3.13.0
其他工具问题
安装build-essential,kernel-package,libncurses5-dev三个软件包,直接使用sudoapt-get install命令即可。
参考网站:http://blog.chinaunix.net/uid-24219701-id-3268294.html
http://www.cnblogs.com/fanzhidongyzby/p/3730131.html
http://blog.youkuaiyun.com/heyutao007/article/details/5737861