热门关键字:  ubuntu  分区  函数  linux系统进程  Fedora

当前位置 :| 主页>Linux教程>内核研究>

Introduction to NetBSD loadable kernel modules 翻译

来源: 作者: 时间:2007-12-03 Tag: 点击:
NetBSD可加载内核模块入门
 
原文出自NetBSD官方网站http://www.home.unix-ag.org/bmeurer/NetBSD/howto-lkm.html
翻译并没有通过作者的许可,只是出于学习目的,请勿用于商业用途。
我翻译的有很多出入,本文由abutter重新翻译。
 
绪论
在诸如GNU/LinuxFreeBSD以及Microsfot Windows等大多数现代操作系统中,可加载内核模块(loadable kernel moduleLKM)非常的流行。有了它,你可以在内核运行时扩展其的功能,而不必重新编译(内核),更不用重启系统。可加载内核模块可以在内核运行时加载,以支持特定的设备以及伪设备。举例来说,几乎每个Linux设备驱动程序是以或者能以可加载内核模块的形式使用的。
而在NetBSD中,可加载内核模块目前还不那样常见。本文编写时,仅有很少驱动程序(大部分的文件系统、兼容层和以及其他少数linuxrtc模拟之类的驱动程序)是以可加载内核模块的形式使用的。这种情况在不久的将来会有所改变。
可加载内核模块接口的最初设计目的是为了与SunOS可加载内核模块功能上保持一致。对/dev/lkm文件执行ioctl(2)调用可以控制lkm(4)功能,不过,你应该从不需要直接与/dev/lkm打交道,因为所有的(这些)操作都由modload(8)modunload(8)modstat(8)程序处理了。值得注意的是,为了使用可加载内核模块,你运行的内核必须是编译时是打开了LKM选项的。
 
编写可加载内核模块
我很乐意向你展示如何编写一个只进行FIBONACCI数计算的简单字符设备驱动,因此,我将此模块命名为fibo.o,并且让所有函数的名称以fibo_开头。这个驱动程序提供了从/dev/fibo0/dev/fibo78个子设备,而每个子设备支持下面几个函数:
static int fibo_open(dev_t, int, int, struct proc *);
static int fibo_close(dev_t, int, int, struct proc *);
static int fibo_read(dev_t dev, struct uio *, int);
你可以打开和关闭这个驱动程序提供的设备,同时你也可以从中读取内容(后面讨论这些实际的函数的时候,我们再进一步的了解这些参数)。
现在,我们需要告诉内核我们有一个具有上述三个函数的字符设备驱动,因此,我们要对结构体cdevsw进行填充(cdevsw表示字符设备转换器,结构体cdevswsys/conf.h中定义)。
static struct cdevsw fibo_dev = {
 fibo_open,
 fibo_close,
 fibo_read,
 (dev_type_write((*))) enodev,
 (dev_type_ioctl((*))) enodev,
 (dev_type_stop((*))) enodev,
 0,
 (dev_type_poll((*))) enodev,
 (dev_type_mmap((*))) enodev,
 0
};
enodev是一个普通的函数,只是简单的返回errno(2) ENODEV(此操作设备不支持)——这意味着,除了opencloseread之外我们不提供任何其他的功能。因此,举个例子,当你尝试向此设备写入内容的时候,write(2)就会失败并且返回ENODEV
紧接着,我们需要告诉内核这个模块是怎么命名的以及在哪个地方寻找此模块提供的操作信息。依照LKM接口,这是一件非常简单的事情:我们使用预处理宏MOD_DEV——在sys/lkm.h中定义以便于传递这些信息。在NetBSD-current中,MOD_DEV发生了变化,因此,我们用下面的结构让代码能工作在NetBSD 1.6以及之前、NetBSD 1.6H以及之后的版本中(感谢Anil Gopinath的提醒)。
#if (__NetBSD_Version__ >= 106080000)
MOD_DEV("fibo", "fibo", NULL, -1, &fibo_dev, -1);
#else
MOD_DEV("fibo", LM_DT_CHAR, -1, &fibo_dev);
#endif
这段代码的意思是:我们的模块以fibo命名,我们提供了一个字符设备(子设备由模块本身处理,所以,当前他们无关紧要);我们想从内核获得主设备号(如果你想使用特定的主设备号,你必须用此设备号替换-1,但是谨防跟其他设备驱动冲突);而且,我们也在fibo_dev中包含支持的操作相关的信息。为了保证能模块卸载正常,我们需要一个全局引用的已打开设备计数器。
上一篇:没有了
下一篇:没有了
最新评论共有 4 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册