zhao
驱动牛犊
驱动牛犊
  • 注册日期2002-04-25
  • 最后登录2003-05-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1490回复:4

请大家看看这段代码?

楼主#
更多 发布于:2002-06-10 08:13
#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等字样的错误,请大侠们指点。
fulminate
驱动小牛
驱动小牛
  • 注册日期2002-05-16
  • 最后登录2006-11-27
  • 粉丝0
  • 关注0
  • 积分19分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-06-10 17:37
你的put_user函数在哪儿?
==========腾蛟起凤,孟学士之词宗;紫电青霜,王将军之武库==========
nh26223
驱动牛犊
驱动牛犊
  • 注册日期2002-04-06
  • 最后登录2002-06-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于: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);
试试

zhao
驱动牛犊
驱动牛犊
  • 注册日期2002-04-25
  • 最后登录2003-05-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-06-11 12:09
谢谢指点:
 出现新的问题,我在open_test中加了一句printk,却发现
不能够print任何东东,难道没有走到open_test中?

还请指点,我想您一定做过这方面的东东,冒昧请您写一个这样的小sample,只要能实现
数据的传送。thanks!!
nh26223
驱动牛犊
驱动牛犊
  • 注册日期2002-04-06
  • 最后登录2002-06-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于: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
游客

返回顶部