荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: cycker (快过年吧.我想回家), 信区: Linux
标  题: Linux 可卸载内核模块完全指南(四)(转寄)[转载]
发信站: 荔园晨风BBS站 (Thu Jan  2 18:22:34 2003), 站内信件

【 以下文字转载自 cycker 的信箱 】
【 原文由 xiaofong@bbs.pku.edu.cn 所发表 】
发信人: chenhao (努力学习), 信区: Linux
标  题: Linux 可卸载内核模块完全指南(四)
发信站: 北大未名站 (2000年11月20日01:11:28 星期一) , 转信

第一部分. 基础知识

1.7什么是内核守护进程

最后我们几乎已经要结束我们的基础部分了,现在我会解释一下内核守护进程(/sbin/ker
neld)的工作原理。正如名字所暗示的那样,这是一个在用户空间等待任务的进程。首先,
为了能够使用kerneld的功能,你必须在编译内核的时候加上kerneld选项.kerneld的工作方
式如下:如果内核想获取一个资源(当然是在内核空间中的),而这个资源当前并不能满足需
求,内核是不会引发一个错误的.他会向kerneld请求这种资源.如果kerneld能够提供这种资
源,他就会载入所需要的LKM,内核就能继续工作了.通过这种机制,使得LKMs可以在当他被需
要/不需要时被加载/卸载.必须清楚这项工作必须在内核空间和用户空间同时进行.

kerneld存在于用户空间.当内核需要一个新的模块时,这个守护进程会接收到内核传给他的
一个字符串来知道到底该加载那个内核.有可能内核送过来的是一个真实的设备名(而不是
文件名),像eth0.在这种情况下系统就要查找/etc/modules.conf里面的别名来确定到底加
载那个LKM到系统中.


下面的行表明了eth0用的是一个DEC Tulip driver LKM:


# /etc/modules.conf     # 或者 /etc/conf.modules - 这是不一样的

alias eth0 tulip


这是kerneld守护进程在用户空间这边的工作情况.在内核那边主要由4个函数来表示.这些
函数都是基于kerneld_send调用的.kerneld_send调用的确切形式可以看linux/kerneld.h
.下面的表列出了上面提到的4个函数.


函数描述


int sprintf (char *buf, const char *fmt, ...);

int vsprintf (char *buf, const char *fmt, va_list args);

用来将数据格式化为字符串的函数


int request_module (const char *name);

告诉kerneld内核需要某个模块(给出名字或者真实的ID/设备名)


int release_module (const char* name, int waitflag);

卸载一个模块


int delayed_release_module (const char *name);

推迟卸载


int cancel_release_module (const char *name);

取消一个推迟卸载调用


注意:Kernel 2.2使用另外一种机制来请求模块.可以看第5部分.


1.8 创建你自己的设备
附录A介绍了一个TTY攻击工具.他使用一个设备来纪录结果.因此我们必须来看一个非常简
单的关于设备驱动程序的例子.来看看下面的代码(这是一个非常基本的驱动,写他的目的仅
仅是为了论述,他几乎没有任何操作......)


#define MODULE

#define __KERNEL__


#include <linux/module.h>

#include <linux/kernel.h>

#include <asm/unistd.h>

#include <sys/syscall.h>

#include <sys/types.h>

#include <asm/fcntl.h>

#include <asm/errno.h>

#include <linux/types.h>

#include <linux/dirent.h>

#include <sys/mman.h>

#include <linux/string.h>

#include <linux/fs.h>

#include <linux/malloc.h>


static int driver_open(struct inode *i, struct file *f)

{

printk("<1>Open Function\n");

return 0;

}


/*注册我们提供给设备的每一个函数*/

static struct file_operations fops = {

NULL,         /*lseek*/

NULL,         /*read*/

NULL,         /*write*/

NULL,         /*readdir*/

NULL,         /*select*/

NULL,         /*ioctl*/

NULL,         /*mmap*/

driver_open,     /*open, take a look at my dummy open function*/

NULL,         /*release*/

NULL         /*fsync...*/

};



int init_module(void)

{

/*用ID 40和名字 driver给驱动注册*/

if(register_chrdev(40, "driver", &fops)) return -EIO;

return 0;

}


void cleanup_module(void)

{

/*取消注册*/

unregister_chrdev(40, "driver");

}


最为重要的函数是register_chrdev(....).这个函数用ID 40给我们的驱动注册.如果你想
使用这个驱动.照如下步骤做:


# mknode /dev/driver c 40 0


# insmod driver.o


这样你就能够存取这个设备了(但是由于缺乏时间,我并没有在其中实现任何功能....).fi
le_operations结构显示了我们这个驱动可以提供给系统的所有函数(操作).正如你所看到
的,我仅仅实现了一个十分(!)基本的笨蛋函数.这个函数仅仅打印一些东西.要清楚的是通
过上面提到的方法你可以很容易的实现你自己的设备.可以做一些试验.如果你想纪录一些
数据(比如说击键),你可以在你的驱动中间建立一个缓冲区.




--
※ 来源:.北大未名站 bbs.pku.edu.cn [FROM: 162.105.45.129]
--
※ 转寄:·北大未名站 bbs.pku.edu.cn·[FROM: 210.39.3.50]
--
※ 转载:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.36.220]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店