20135307 张嘉琪函数
Linux模块是一些能够做为独立程序来编译的函数和数据类型的集合。之因此提供模块机制,是由于Linux自己是一个单内核。单内核因为全部内容都集成在一块儿,效率很高,但可扩展性和可维护性相对较差,模块机制可弥补这一缺陷。测试
Linux模块能够经过静态或动态的方法加载到内核空间,静态加载是指在内核启动过程当中加载;动态加载是指在内核运行的过程当中随时加载。 一个模块被加载到内核中时,就成为内核代码的一部分。模块加载入系统时,系统修改内核中的符号表,将新加载的模块提供的资源和符号添加到内核符号表中,以便模块间的通讯。spa
模块构造函数:指针
执行insmod或modprobe指令加载内核模块时会调用的初始化函数。函数原型必须是module_init(),括号内是函数指针进程
模块析构函数:内存
执行rmmod指令卸载模块时调用的函数。函数原型是module_exit()资源
模块许可声明:原型
函数原型是MODULE_LICENSE(),告诉内核该程序使用的许可证,否则在加载时它会提示该模块污染内核。通常会写GPL。 模块参数(可选) 模块导出符号(可选) 模块做者信息声明(可选)源码
注意:it
头文件module.h,必须包含此文件;
头文件kernel.h,包含经常使用的内核函数;
头文件init.h包含宏init和exit,容许释放内核占用的内存。
写一个简单的代码,用来向内核输出一段文字。 代码很简单,里面包括了上文提到的构造、析构和许可证。
编译模块 接下来写Makefile。
3. 加载模块 sudo insmod printname.ko
4.测试模块 dmesg看内核信息
5.卸载模块 sudo rmmod printname
这时用dmesg看内核信息,就会看到写在module_exit()中的输出。
6.实现输出当前进程信息的功能
实现了代码的功能,验证成功。 7. 实现读取进程链表的功能 在上一个代码的基础上,修改代码。
其实就是个for循环,从第一个PCB(叫作init_task)开始,顺着next指针读了一圈。 修改Makefile,make,insmod,输出以下图:
编译模块与正常的C语言有一些区别,C语言的innclude文件存放在/usr/include中,而模块用到的include文件都在/usr/src/内核代码/include中。因为头文件的差别,会产生一些没法预料的错误。在第一次编译时就出现了make不成功的状况,修改PATH以后make成功,过程当中也没有出现其余问题,完成的比较顺利。