|
OpenBSD可加载内核模块编程完全指南(7) char msg[MAXMSGLEN]; };
当模块第一次被加载的时候,我们设置value为13并且为我们的字符串赋值"hello world!".我们定义了两个简单的ioctl调用来设置或获取内
部结构的当前的value的值.这些 都利用ourdev_io结构作为一个参数,然后利用ioctl执行一个相应的动作. 在模块的入口指针中,我这里再次用了IDSPATH宏.
以下是我们自定义的设备程序的完整代码(chardev.c):
#include <sys/param.h> #include <sys/fcntl.h> #include <sys/systm.h> #include <sys/ioctl.h> #include <sys/exec.h> #include <sys/conf.h> #include <sys/lkm.h>
#include "common.h"
/* * 导入我们支持的操作:open,read,close,ioctl等 */
int ourdevopen __P((dev_t dev, int oflags, int devtype, struct proc *p)); int ourdevclose __P((dev_t dev, int fflag, int devtype, struct proc *p)); int ourdevread __P((dev_t dev, struct uio *uio, int ioflag)); int ourdevioctl __P((dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)); int ourdev_handler __P((struct lkm_table *lkmtp, int cmd));
/* * outdev_io结构定义在头文件common.h中,我们的设备会通过ioctl调用来获取和设置它的值. */
static struct ourdev_io dio;
/* * 这里我们初始化我们的设备的操作向量 */
cdev_decl(ourdev); static struct cdevsw cdev_ourdev = cdev_ourdev_init(1, ourdev);
/* * 初始化lkm接口的内部结构.第一个参数是模块名,第二个参数是设备的类型,在我的例子里标记为 * LM_DT_CHAR表示是一个字符设备.第三个参数是我们存储在cdevsw[]表中的操作结构.就象系统 * 调用的例子中一样,值为-1的话系统自动找寻空闲的位置存储.最后我们初始化cdevsw结构 */
MOD_DEV("ourdev", LM_DT_CHAR, -1, &cdev_ourdev)
/* * 以下的动作在设备被打开的时候执行,这里打印"hello",哈,仅做测试之用:) */
int ourdevopen(dev, oflags, devtype, p) dev_t dev; int oflags, devtype;
|