阅读:1490回复:4
请大家看看这段代码?
#define MODULE
#define __KERNEL__ #include <linux/kernel.h> #include <linux/module.h> #include <linux/version.h> #include <linux/types.h> #include <linux/string.h> #include <linux/malloc.h> #include <linux/stat.h> #include <linux/fcntl.h> #include <linux/file.h> #include <linux/sched.h> #include <linux/fs.h> #include <linux/mm.h> #include <linux/errno.h> #include <asm/segment.h> #include <asm/io.h> #include <asm/unistd.h> #include <asm/uaccess.h> unsigned int test_major = 0; static int read_test(struct inode *node,struct file *file, char *buf,int count) { int left=0,i; printk(\"\\n now is in read fun\\n\"); if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT ){ printk(\"\\n****************888888************************\\n\"); return -EFAULT; } for(left = count ; left > 0; left--) { put_user(1,buf); buf++; } return count; } static int write_test(struct inode *inode,struct file *file, const char *buf, int count) { return count; } static int open_test(struct inode *inode,struct file *file ) { MOD_INC_USE_COUNT; return 0; } static void release_test(struct inode *inode,struct file *file ) { MOD_DEC_USE_COUNT; } struct file_operations test_fops = { NULL, read_test, write_test, NULL, /* test_readdir */ NULL, NULL, /* test_ioctl */ NULL, /* test_mmap */ open_test, release_test, NULL, /* test_fsync */ NULL, /* test_fsync */ NULL, /* test_fasync */ NULL, /* test_fasync */ /* nothing more, fill with NULLs */ }; int init_module(void) { int result=-1; result = register_chrdev(0, \"9112drv\", &test_fops); if (result < 0) { printk(KERN_INFO \"test: can\'t get major number\\n\"); return result; } if (test_major == 0) test_major = result; /* dynamic */ printk(\"\\n successfully load and major=%d\\n\",result); return 0; } void cleanup_module(void) { unregister_chrdev(test_major, \"9112drv\"); } 以上是一个内核测试程序,从内核空间给用户空间的buffer赋值,将其编译,并insmod 和mknod后, 用下面的测试程序观察结果, #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> main() { int testdev; int i=-1; char buf[10]; testdev = open(\"/dev/9112drv\",O_RDWR); if ( testdev == -1 ) { printf(\"Cann\'t open file \\n\"); exit(0); } read(testdev,buf,10); for (i = 0; i < 10;i++) printf(\"%d\\n\",buf); close(testdev); } 可是在执行到 read(testdev,buf,10);时给出segment fault错误,并且这时如果执行 rmmod 9112drv命令 ,则会给出device busy等字样的错误,请大侠们指点。 |
|
沙发#
发布于:2002-06-10 17:37
你的put_user函数在哪儿?
|
|
|
板凳#
发布于:2002-06-11 08:02
将一下代码
for(left = count ; left > 0; left--) { put_user(1,buf); buf++; } 改为: for(left=count-1;left>0;left--) { put_user(1,buf); buf++; } put_user(1,buf); 试试 |
|
地板#
发布于:2002-06-11 12:09
谢谢指点:
出现新的问题,我在open_test中加了一句printk,却发现 不能够print任何东东,难道没有走到open_test中? 还请指点,我想您一定做过这方面的东东,冒昧请您写一个这样的小sample,只要能实现 数据的传送。thanks!! |
|
地下室#
发布于:2002-06-11 18:55
基本程序框架和你的差不多,不过我的系统是redhat7.2,有一些变动:
module如下: #include <linux/kernel.h> #include <linux/module.h> #include <linux/version.h> #include <linux/types.h> #include <linux/string.h> #include <linux/malloc.h> #include <linux/stat.h> #include <linux/fcntl.h> #include <linux/file.h> #include <linux/sched.h> #include <linux/fs.h> #include <linux/devfs_fs_kernel.h> #include <linux/mm.h> #include <linux/errno.h> #include <asm/segment.h> #include <asm/io.h> #include <asm/unistd.h> #include <asm/uaccess.h> unsigned int test_major = 0; static int read_test(struct file *file, char *buf, size_t count, loff_t *ppos) { int left=0; printk(\"\\n now is in read fun\\n\"); if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT ){ printk(\"\\n****************888888************************\\n\"); return -EFAULT; } for(left = count ; left > 0; left--){ put_user(1,buf); buf++; } return count; } static int write_test(struct file *file, const char *buf, size_t count, loff_t *ppos) { return count; } static int open_test(struct inode *inode,struct file *file ) { printk(\"Open operation\"); MOD_INC_USE_COUNT; return 0; } static int release_test(struct inode *inode,struct file *file ) { MOD_DEC_USE_COUNT; return 0; } struct file_operations test_fops = { read: read_test, write: write_test, open: open_test, release: release_test, }; int init_module(void) { int result=-1; result = register_chrdev(150, \"9112drv\", &test_fops); if (result < 0) { printk(KERN_INFO \"test: can\'t get major number\\n\"); return result; } if (test_major == 0) test_major = result; /* dynamic */ printk(\"\\n successfully load and major=%d\\n\",result); return 0; } void cleanup_module(void) { unregister_chrdev(test_major, \"9112drv\"); } 其中read,write函数采用2.4.0的新定义,register_chrdev的第一个参数使用150,没有使用0是因为这个数可能被系统保留(记不清楚了),read中使用你的写法可以正常运行。printk不能打印出来是因为新的内核为了调试方便(不被printk的输出扰乱控制台),将缺省的日志级别设为只输出到日志文件中,不会输出到控制台,你可以在/var/log/message中看到printk的输出, test如下: #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> main() { int testdev; int i=-1; char buf[10]; testdev = open(\"/dev/9112drv\",O_RDWR); if ( testdev == -1 ) { printf(\"Cann\'t open file \\n\"); exit(0); } read(testdev,buf,10); for (i = 0; i < 10;i++) printf(\"%d\\n\",buf); close(testdev); } 和你的一样,注意输出的值不是1,因为你的buf是char,而且从内核中输出的也是char。 makefiel如下: CC = gcc CMFLAGS = -Wall -O2 -D__KERNEL__ -DMODULE -DLINUX CFLAGS = -Wall -O2 all:testmodule test testmodule:testmodule.c $(CC) $(CMFLAGS) -c testmodule.c test:test.c $(CC) $(CFLAGS) -o test test.c |
|