如何在FreeBSD上编写LKM?
<div style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-size: 14px; padding: 0px;" class="PostContent">版权信息:可以任意转载, 转载时请务必以超链接形式标明文章原文出处,谢谢原文出处: http://libiao.appspot.com/2009/07/first_lkm_intro.html
LKM: Loadable Kernel Module,也叫KLD (Dynamic Kernel Linker)就是编写可动态加载和卸载的内核模块。使用kldload(8)加载内核模块,使用kldunload(8)卸载内核模块,使用kldstat(8)来显示查看已经加载的内核模块。调用kldload(8),必须要在内核上链接并且注册上,在FreeBSD的内核编程上,可以使用宏DECLARE_MODULE来进行链接和注册,
宏DECLARE_MODULE一共有4个参数
第一个参数是模块的名称,传入的是一个字符串,但是很奇怪的是,好像这个字符串不需要加引号
第二个参数是最重要的一个参数,其为数据结构struct moduledata(即moduledata_t类型结构),在该结构中保存该模块的官方名称,事件处理函数以及一些额外的数据
如:
static moduledata_t hello_mod = {
"hello",
load,
NULL
};
其中load是一个事件处理函数,其处理了如下的事件
typedef enum modeventtype {
MOD_LOAD,/* 当模块以及被加载后触发*/
MOD_UNLOAD,/*当模块被卸载的时候触发*/
MOD_SHUTDOWN,/*当在SHUTDOWN的时候触发*/
MOD_QUIESCE/*当模块quiesce时候触发*/
}
第三个参数是该模块的类型,可选值可以参考enum sysinit_sub_id(在sys/kernel.h),一般情况下是使用SI_SUB_DRIVERS
第四个参数是KLD初始化的顺序,可以参考enum sysinit_elem_order(在sys/kernel.h)中的值,一般情况下是使用SI_ORDER_MIDDLE
实例:
DECLARE_MODULE(hello,hello_mod,SI_SUB_DRIVERS,SI_ORDER_MIDDLE);
下面是整个代码
<div style="" class="default">static int load(struct module* module,int cmd,void* arg)<a name="code0-7">{error = 0;<a name="code0-9">switch(cmd)<a name="code0-11">{case MOD_LOAD:<a name="code0-13">uprintf("Hello world\n");break;<a name="code0-15">case MOD_UNLOAD:<a name="code0-17">uprintf("Good-Bye, cruel world!\n");break;<a name="code0-19">default:<a name="code0-21">error = EOPNOTSUPP;break;<a name="code0-23">}return error;<a name="code0-26">}static moduledata_t hello_mod = {<a name="code0-29">"hello",load,<a name="code0-31">NULL};<a name="code0-33">DECLARE_MODULE(hello,hello_mod,SI_SUB_DRIVERS,SI_ORDER_MIDDLE);
页:
[1]