预备知识:
freeBSD模块事件类型:
typedef enum modeventtype {
MOD_LOAD, //模块加载使用此值
MOD_UNLOAD,//模块卸载使用此值
MOD_SHUTDOWN,//系统关闭使用此值
MOD_QUIESCE //模块即将卸载使用此值
} modeventtype_t;
在系统中注册一个加载模块和模块事件处理程序
DECLARE_MODULE(name, data, sub, order)
name:模块的名字
data:是一个moduledata_t类型的结构 并且各个字段都进行了初始化
typedef struct moduledata
{
const char *name; /* 模块名 */
modeventhand_t evhand; /* 模块事件处理程序 typedef int (*modeventhand_t)(module_t mod, int event, void *arg); */
void *priv; /* 私有数据 */
} moduledata_t;
sub:模块所属于的内核子系统
enum sysinit_sub_id{
SI_SUB_DRIVERS 设备驱动程序子系统
.....
}
order: 模块在子系统中初始化次序
enum sysinit_elem_order {
SI_ORDER_FIRST = 0x0000000, /* first*/
SI_ORDER_SECOND = 0x0000001, /* second*/
SI_ORDER_THIRD = 0x0000002, /* third*/
SI_ORDER_FOURTH = 0x0000003, /* fourth*/
SI_ORDER_MIDDLE = 0x1000000, /* 中间的某个位置 */
SI_ORDER_ANY = 0xfffffff /* last*/
};
过程:
(1)编写Makefile如下
KMOD = netlink #模块名
SRCS=netlink.c #编译的c文件
.include <bsd.kmod.mk>
(2)写c代码netlink.c
#include <sys/param.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/systm.h>
static int test_handler(struct module *module, int event, void *arg)
{
int e = 0;
switch (event)
{
case MOD_LOAD://模块加载执行
printf("hello first module \n");//在dmesg 中查看消息打印
break;
case MOD_UNLOAD://模块卸载执行
uprintf("bye first module\n"); //可在终端查看消息打印
break;
default:
e = EOPNOTSUPP;
break;
}
return(e);
}
static moduledata_t test_conf = {
"netlink", /* 模块名 */
test_handler, /* 处理事件 */
NULL /* extra data */
};
//定义模块
DECLARE_MODULE(netlink, test_conf, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
(3)加载模块
make load 或者 kldload ./netlink.ko
(4)卸载模块
make unload或者 kldunload netlink.ko