头文件中,其原型如下:
typedef int (*modeventhand_t) (module_t, int /*modeventtype_t*/,void *) ;其中,module_t 是一个指向模块结构的指针,modeventtype_t被定义在头文件中,其原型如下:
typedef enum modeventtype {
MOD_LOAD, /*/当模块登陆的时候要进行设置*/
MOD_UNLOAD, /*当模块退出时进行设置*/
MOD_SHUTDOWN,/*当shutdown进行设置*/
MOD_QUIESCE /*当quiesce是进行设置*/
} mod_eventtype_t;
二、使用KLD登录模块时必须使用宏DECLARE_MODULE,她被定义在中,其模型如下:
#define DECLARE_MODULE(name,data,sub,order)
MODULE_METADATA(_md_##name,MDT_MODULE,&data,#name);
SYSINIT(name##module,sub,order,module_regilster_init,&data)
struct __hack
其中,参数name指模块的名字,data通过moduledata指定正式的模块名字和事件句柄,moduledata被定义在中,其原型如下:
typedef struct moduledata {
const char *name; /*module name*/
modeventhand_t evhant; /*event handler*/
void *priv; /*extra data*/
} moduledata_t;
参数sub指定识别的模块类型启动接口,有效的 入口参数能被发现在,用sysinit_sub_id 来枚举列表。
现在我用SI_SUB_DRIVERS这个参数来注册设备驱动。参数order指定KLD命令的初始化,定义在头文件中,用sysinit_elem_order来枚举列表。我们用SI_ORDER_MIDDLE来初始化KLD在中部。
三、 现在可以开始写第一个KLD了,一个完整的"hello,world"模块。其源代码如下:
#include
#include
#include
#include
/*下面的函数被叫在load/unload时*/
static int load(struct module *module,int cmd,void *arg)
{
int error=0;
switch(cmd) {
case MOD_LOAD:
uprintf("hello,world! ");
break;
case MOD_UNLOAD:
uprintf("good-bye,cruel world! ");
break;
default:
error = EOPNOTSUPP;
break;
}
return(error);
}
/*下面声明DECLARE_MODULE*/
static moduledata_t hello_mod = {
"hello", /*模块的名字*/
load, /*事件句柄*/
NULL /*extra data*/
};
DECLARE_MODULE(hello,hello_mod,SI_SUB_DRIVERS,SI_ORDER_MIDDLE);
四、为了编译这个模块,你可以使用Makefile bsd.kmod.mk,其Makefile for hello.c如下:
KMOD= hello #KLD要建立的名字
SRCS= hello.c #源文件列表
.include
假设Makefile和hello.c 在同一个目录下,你可以键入make来生成可执行文件hello.ko。
如果你不是在root权限中,你要使用如下命令来运行程序:
$sudo kldload ./hello.ko
$sudo kldunload hello.ko
评论