Chinaunix首页 | 论坛 | 博客
  • 博客访问: 210113
  • 博文数量: 80
  • 博客积分: 213
  • 博客等级: 入伍新兵
  • 技术积分: 435
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-27 11:13
文章分类

全部博文(80)

文章存档

2012年(46)

2011年(34)

分类:

2012-03-24 02:02:05

  1. #ifndef _MEMDEV_H_
  2. #define _MEMDEV_H_

  3. #include <linux/ioctl.h>

  4. #ifndef MEMDEV_MAJOR
  5. #define MEMDEV_MAJOR 0 /*预设的mem的主设备号*/
  6. #endif

  7. #ifndef MEMDEV_NR_DEVS
  8. #define MEMDEV_NR_DEVS 2 /*设备数*/
  9. #endif

  10. #ifndef MEMDEV_SIZE
  11. #define MEMDEV_SIZE 4096
  12. #endif

  13. /*mem设备描述结构体*/
  14. struct mem_dev
  15. {
  16.   char *data;
  17.   unsigned long size;
  18. };

  19. /* 定义幻数 */
  20. #define MEMDEV_IOC_MAGIC 'k'

  21. /* 定义命令 */
  22. #define MEMDEV_IOCPRINT _IO(MEMDEV_IOC_MAGIC, 1)
  23. #define MEMDEV_IOCGETDATA _IOR(MEMDEV_IOC_MAGIC, 2, int)
  24. #define MEMDEV_IOCSETDATA _IOW(MEMDEV_IOC_MAGIC, 3, int)

  25. #define MEMDEV_IOC_MAXNR 3

  26. #endif /* _MEMDEV_H_ */
  1. #include <linux/module.h>
  2. #include <linux/types.h>
  3. #include <linux/fs.h>
  4. #include <linux/errno.h>
  5. #include <linux/mm.h>
  6. #include <linux/sched.h>
  7. #include <linux/init.h>
  8. #include <linux/cdev.h>
  9. #include <asm/io.h>
  10. #include <asm/system.h>
  11. #include <asm/uaccess.h>

  12. #include "memdev.h"

  13. static int mem_major = MEMDEV_MAJOR;

  14. module_param(mem_major, int, S_IRUGO);

  15. struct mem_dev *mem_devp; /*设备结构体指针*/

  16. struct cdev cdev;

  17. /*文件打开函数*/
  18. int mem_open(struct inode *inode, struct file *filp)
  19. {
  20.     struct mem_dev *dev;
  21.     
  22.     /*获取次设备号*/
  23.     int num = MINOR(inode->i_rdev);

  24.     if (num >= MEMDEV_NR_DEVS)
  25.             return -ENODEV;
  26.     dev = &mem_devp[num];
  27.     
  28.     /*将设备描述结构指针赋值给文件私有数据指针*/
  29.     filp->private_data = dev;
  30.     
  31.     return 0;
  32. }

  33. /*文件释放函数*/
  34. int mem_release(struct inode *inode, struct file *filp)
  35. {
  36.   return 0;
  37. }

  38. /*IO操作*/
  39. int memdev_ioctl(struct inode *inode, struct file *filp,
  40.                  unsigned int cmd, unsigned long arg)
  41. {

  42.     int err = 0;
  43.     int ret = 0;
  44.     int ioarg = 0;
  45.     
  46.     /* 检测命令的有效性 */
  47.     if (_IOC_TYPE(cmd) != MEMDEV_IOC_MAGIC)
  48.         return -EINVAL;
  49.     if (_IOC_NR(cmd) > MEMDEV_IOC_MAXNR)
  50.         return -EINVAL;

  51.     /* 根据命令类型,检测参数空间是否可以访问 */
  52.     if (_IOC_DIR(cmd) & _IOC_READ)
  53.         err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
  54.     else if (_IOC_DIR(cmd) & _IOC_WRITE)
  55.         err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
  56.     if (err)
  57.         return -EFAULT;

  58.     /* 根据命令,执行相应的操作 */
  59.     switch(cmd) {

  60.       /* 打印当前设备信息 */
  61.       case MEMDEV_IOCPRINT:
  62.           printk("<--- CMD MEMDEV_IOCPRINT Done--->\n\n");
  63.         break;
  64.       
  65.       /* 获取参数 */
  66.       case MEMDEV_IOCGETDATA:
  67.         ioarg = 1101;
  68.         ret = __put_user(ioarg, (int *)arg);
  69.         break;
  70.       
  71.       /* 设置参数 */
  72.       case MEMDEV_IOCSETDATA:
  73.         ret = __get_user(ioarg, (int *)arg);
  74.         printk("<--- In Kernel MEMDEV_IOCSETDATA ioarg = %d --->\n\n",ioarg);
  75.         break;

  76.       default:
  77.         return -EINVAL;
  78.     }
  79.     return ret;

  80. }

  81. /*文件操作结构体*/
  82. static const struct file_operations mem_fops =
  83. {
  84.   .owner = THIS_MODULE,
  85.   .open = mem_open,
  86.   .release = mem_release,
  87.   .ioctl = memdev_ioctl,
  88. };

  89. /*设备驱动模块加载函数*/
  90. static int memdev_init(void)
  91. {
  92.   int result;
  93.   int i;

  94.   dev_t devno = MKDEV(mem_major, 0);

  95.   /* 静态申请设备号*/
  96.   if (mem_major)
  97.     result = register_chrdev_region(devno, 2, "memdev");
  98.   else /* 动态分配设备号 */
  99.   {
  100.     result = alloc_chrdev_region(&devno, 0, 2, "memdev");
  101.     mem_major = MAJOR(devno);
  102.   }
  103.   
  104.   if (result < 0)
  105.     return result;

  106.   /*初始化cdev结构*/
  107.   cdev_init(&cdev, &mem_fops);
  108.   cdev.owner = THIS_MODULE;
  109.   cdev.ops = &mem_fops;
  110.   
  111.   /* 注册字符设备 */
  112.   cdev_add(&cdev, MKDEV(mem_major, 0), MEMDEV_NR_DEVS);
  113.    
  114.   /* 为设备描述结构分配内存*/
  115.   mem_devp = kmalloc(MEMDEV_NR_DEVS * sizeof(struct mem_dev), GFP_KERNEL);
  116.   if (!mem_devp) /*申请失败*/
  117.   {
  118.     result = - ENOMEM;
  119.     goto fail_malloc;
  120.   }
  121.   memset(mem_devp, 0, sizeof(struct mem_dev));
  122.   
  123.   /*为设备分配内存*/
  124.   for (i=0; i < MEMDEV_NR_DEVS; i++)
  125.   {
  126.         mem_devp[i].size = MEMDEV_SIZE;
  127.         mem_devp[i].data = kmalloc(MEMDEV_SIZE, GFP_KERNEL);
  128.         memset(mem_devp[i].data, 0, MEMDEV_SIZE);
  129.   }
  130.     
  131.   return 0;

  132.   fail_malloc:
  133.   unregister_chrdev_region(devno, 1);
  134.   
  135.   return result;
  136. }

  137. /*模块卸载函数*/
  138. static void memdev_exit(void)
  139. {
  140.   cdev_del(&cdev); /*注销设备*/
  141.   kfree(mem_devp); /*释放设备结构体内存*/
  142.   unregister_chrdev_region(MKDEV(mem_major, 0), 2); /*释放设备号*/
  143. }

  144. MODULE_AUTHOR("David Xie");
  145. MODULE_LICENSE("GPL");

  146. module_init(memdev_init);
  147. module_exit(memdev_exit);
  1. #include <stdio.h>
  2. #include<sys/types.h>
  3. #include<sys/stat.h>
  4. #include<fcntl.h>

  5. #include "memdev.h" /* 包含命令定义 */

  6. int main()
  7. {
  8.     int fd = 0;
  9.     int cmd;
  10.     int arg = 0;
  11.     char Buf[4096];
  12.     
  13.     
  14.     /*打开设备文件*/
  15.     fd = open("/dev/memdev0",O_RDWR);
  16.     if (fd < 0)
  17.     {
  18.         printf("Open Dev Mem0 Error!\n");
  19.         return -1;
  20.     }
  21.     
  22.     /* 调用命令MEMDEV_IOCPRINT */
  23.     printf("<--- Call MEMDEV_IOCPRINT --->\n");
  24.     cmd = MEMDEV_IOCPRINT;
  25.     if (ioctl(fd, cmd, &arg) < 0)
  26.         {
  27.             printf("Call cmd MEMDEV_IOCPRINT fail\n");
  28.             return -1;
  29.     }
  30.     
  31.     
  32.     /* 调用命令MEMDEV_IOCSETDATA */
  33.     printf("<--- Call MEMDEV_IOCSETDATA --->\n");
  34.     cmd = MEMDEV_IOCSETDATA;
  35.     arg = 2007;
  36.     if (ioctl(fd, cmd, &arg) < 0)
  37.         {
  38.             printf("Call cmd MEMDEV_IOCSETDATA fail\n");
  39.             return -1;
  40.     }

  41.     
  42.     /* 调用命令MEMDEV_IOCGETDATA */
  43.     printf("<--- Call MEMDEV_IOCGETDATA --->\n");
  44.     cmd = MEMDEV_IOCGETDATA;
  45.     if (ioctl(fd, cmd, &arg) < 0)
  46.         {
  47.             printf("Call cmd MEMDEV_IOCGETDATA fail\n");
  48.             return -1;
  49.     }
  50.     printf("<--- In User Space MEMDEV_IOCGETDATA Get Data is %d --->\n\n",arg);    
  51.     
  52.     close(fd);
  53.     return 0;    
  54. }
阅读(541) | 评论(0) | 转发(0) |
0

上一篇:Linux体系结构

下一篇:proc文件系统

给主人留下些什么吧!~~