Linux内核分析实验报告
实验题目: 动态模块设计实验
实验目的:学习模块,模块式linux特有的一种机制。模块可以动态地增加内核
的功能。编写模块,将它作为linux内核空间的扩展。
硬件环境:内存1G以上
软件环境:Linux(Ubuntu) 2-6 实验步骤:
一:实验原理简介:
模块一旦被转载进系统,就会在系统态下运行。如果模块知道系统的数
据结构地址,就可以读写相应的数据结构。模块作为一种抽象的数据类型,他有一个可以通过静态内核中断的接口。加入模块的每个新函数必须在该模块被装载到内核时进行注册。如果模块式静态装载的,加入模块的所有函数在内核启动时候进行注册。如果是动态装载的,必须在装载这个模块时候动态注册。注册工作在init_module() 中完成,注销工作是在cheanup_module()中完成。
对于模块的使用有两种方式。一种是设备驱动程序,一种是/proc文件。 本实验中要求从当前进程开始,首先追溯到init进程,显示出一路上经
历的所有进程的进程号,进程名。然后从init进程开始,遍历所有的进程,显示进程名与进程号。前者主要是用到一个while循环,判断当前进程进程号是否是1,后者主要是用到一个宏定义for_each_process,遍历所有的进程。
二:主要数据结构:
1./proc下的文件(目录)结构:
struct proc_dir_entry { unsigned int low_ino; /*目录入口的imod节点号 */ unsigned short namelen; /*节点名长度*/ const char *name; /*节点名*/
mode_t mode; /*节点的类型和权限*/ nlink_t nlink; /*节点的连接数*/
uid_t uid; /*拥有该节点的用户uid*/ gid_t gid; /*g拥有该节点的组gid*/ loff_t size;
/*节点的限制大小,除非限制长度,否则为 0*/
struct inode_operations * proc_iops;
/*对该节点的操作*/
const struct file_operations * proc_fops;
/*对该文件的操作*/
get_info_t *get_info; /*如果定义,当有读操作时候调用*/ struct module *owner; /*拥有该模块的用户*/
struct proc_dir_entry *next, *parent, *subdir;
/*节点间的关系,初始为NULL*/
void *data; /*节点对应文件的内容*/ read_proc_t *read_proc; /*读操作函数*/
write_proc_t *write_proc; /*写操作函数*/ atomic_t count; /* 节点引用计数 */ int deleted; /* 节点删除标志 */ void *set; };
其中几个属性的设置为: owner=THIS_MODULE;
data 指向文件数据区,自己定义 read_proc 指向读操作处理函数 write_proc 指向写操作处理函数
三:主要函数介绍 1:系统函数
(1)init_module()
函数说明:系统调用装载模块
(2)cleanup_module()
函数说明:清除模块。
(3)int sprintf(string format, mixed [args]...)
函数说明:将args各个函数的参数整合到format字符串中。
四:程序流程:
进程初始化过程当中,我们将进程的信息,整合到mydata
数据结构当中,然后输出:
具体内容包括:
从当前进程开始向上遍历,直至进程号为1结束(81行—85行):
用宏调用for_each_process从init开始逐个遍历进程,
同样的方式将将进程的信息追加到mydata数据结构。(90行—95行)
(见图3--1)
(图3--1)
五:结果检测:
编译模块:进入程序所在的目录,键入make命令 安装模块:sudo install shiyan.ko
测试结果:lsmod
显示结果是
正确,说明模块被正确加载
进入/proc/mydir下查看myfile文件内容:
结果见图3--2