zoukankan      html  css  js  c++  java
  • 国嵌内核驱动进阶班-7-1(Ioctl设备控制)--- 测试代码

    驱动内容:

      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 <linux/slab.h>
     11 #include <asm/uaccess.h>
     12 
     13 #include "memdev.h"
     14 
     15 static int mem_major = MEMDEV_MAJOR;
     16 
     17 module_param(mem_major, int, S_IRUGO);
     18 
     19 struct mem_dev *mem_devp; /*设备结构体指针*/
     20 
     21 struct cdev cdev; 
     22 
     23 /*文件打开函数*/
     24 int mem_open(struct inode *inode, struct file *filp)
     25 {
     26     struct mem_dev *dev;
     27     
     28     /*获取次设备号*/
     29     int num = MINOR(inode->i_rdev);
     30 
     31     if (num >= MEMDEV_NR_DEVS) 
     32             return -ENODEV;
     33     dev = &mem_devp[num];
     34     
     35     /*将设备描述结构指针赋值给文件私有数据指针*/
     36     filp->private_data = dev;
     37     
     38     return 0; 
     39 }
     40 
     41 /*文件释放函数*/
     42 int mem_release(struct inode *inode, struct file *filp)
     43 {
     44   return 0;
     45 }
     46 
     47 /*IO操作*/
     48 long memdev_ioctl(struct file *filp,
     49                  unsigned int cmd, unsigned long arg)
     50  //long (*compat_ioctl) (struct file *filp, unsigned int cmd, 
     51  //                         unsigned long arg)
     52 {
     53     printk("<--- memdev_ioctl is call @@@ --->
    
    ");
     54     
     55     int err = 0;
     56     int ret = 0;
     57     int ioarg = 0;
     58     
     59     /* 检测命令的有效性 */
     60     if (_IOC_TYPE(cmd) != MEMDEV_IOC_MAGIC) 
     61         return -EINVAL;
     62     if (_IOC_NR(cmd) > MEMDEV_IOC_MAXNR) 
     63         return -EINVAL;
     64 
     65     /* 根据命令类型,检测参数空间是否可以访问 */
     66     if (_IOC_DIR(cmd) & _IOC_READ)
     67         err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
     68     else if (_IOC_DIR(cmd) & _IOC_WRITE)
     69         err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
     70     if (err) 
     71         return -EFAULT;
     72 
     73     /* 根据命令,执行相应的操作 */
     74     switch(cmd) {
     75 
     76       /* 打印当前设备信息 */
     77       case MEMDEV_IOCPRINT:
     78           printk("<--- CMD MEMDEV_IOCPRINT Done--->
    
    ");
     79         break;
     80       
     81       /* 获取参数 */
     82       case MEMDEV_IOCGETDATA: 
     83         ioarg = 1101;
     84         ret = __put_user(ioarg, (int *)arg);
     85         break;
     86       
     87       /* 设置参数 */
     88       case MEMDEV_IOCSETDATA: 
     89         ret = __get_user(ioarg, (int *)arg);
     90         printk("<--- In Kernel MEMDEV_IOCSETDATA ioarg = %d --->
    
    ",ioarg);
     91         break;
     92 
     93       default:  
     94         return -EINVAL;
     95     }
     96     return ret;
     97 
     98 }
     99 
    100 /*文件操作结构体*/
    101 static const struct file_operations mem_fops =
    102 {
    103   .owner = THIS_MODULE,
    104   .open = mem_open,
    105   .release = mem_release,
    106   .unlocked_ioctl = memdev_ioctl,
    107 };
    108 
    109 /*设备驱动模块加载函数*/
    110 static int memdev_init(void)
    111 {
    112   int result;
    113   int i;
    114 
    115   dev_t devno = MKDEV(mem_major, 0);
    116 
    117   /* 静态申请设备号*/
    118   if (mem_major)
    119     result = register_chrdev_region(devno, 2, "memdev");
    120   else  /* 动态分配设备号 */
    121   {
    122     result = alloc_chrdev_region(&devno, 0, 2, "memdev");
    123     mem_major = MAJOR(devno);
    124   }  
    125   
    126   if (result < 0)
    127     return result;
    128 
    129   /*初始化cdev结构*/
    130   cdev_init(&cdev, &mem_fops);
    131   cdev.owner = THIS_MODULE;
    132   cdev.ops = &mem_fops;
    133   
    134   /* 注册字符设备 */
    135   cdev_add(&cdev, MKDEV(mem_major, 0), MEMDEV_NR_DEVS);
    136    
    137   /* 为设备描述结构分配内存*/
    138   mem_devp = kmalloc(MEMDEV_NR_DEVS * sizeof(struct mem_dev), GFP_KERNEL);
    139   if (!mem_devp)    /*申请失败*/
    140   {
    141     result =  - ENOMEM;
    142     goto fail_malloc;
    143   }
    144   memset(mem_devp, 0, sizeof(struct mem_dev));
    145   
    146   /*为设备分配内存*/
    147   for (i=0; i < MEMDEV_NR_DEVS; i++) 
    148   {
    149         mem_devp[i].size = MEMDEV_SIZE;
    150         mem_devp[i].data = kmalloc(MEMDEV_SIZE, GFP_KERNEL);
    151         memset(mem_devp[i].data, 0, MEMDEV_SIZE);
    152   }
    153     
    154   return 0;
    155 
    156   fail_malloc: 
    157   unregister_chrdev_region(devno, 1);
    158   
    159   return result;
    160 }
    161 
    162 /*模块卸载函数*/
    163 static void memdev_exit(void)
    164 {
    165   cdev_del(&cdev);   /*注销设备*/
    166   kfree(mem_devp);     /*释放设备结构体内存*/
    167   unregister_chrdev_region(MKDEV(mem_major, 0), 2); /*释放设备号*/
    168 }
    169 
    170 MODULE_AUTHOR("David Xie");
    171 MODULE_LICENSE("GPL");
    172 
    173 module_init(memdev_init);
    174 module_exit(memdev_exit);
     1 #ifndef _MEMDEV_H_
     2 #define _MEMDEV_H_
     3 
     4 #include <linux/ioctl.h>
     5 
     6 #ifndef MEMDEV_MAJOR
     7 #define MEMDEV_MAJOR 0   /*预设的mem的主设备号*/
     8 #endif
     9 
    10 #ifndef MEMDEV_NR_DEVS
    11 #define MEMDEV_NR_DEVS 2    /*设备数*/
    12 #endif
    13 
    14 #ifndef MEMDEV_SIZE
    15 #define MEMDEV_SIZE 4096
    16 #endif
    17 
    18 /*mem设备描述结构体*/
    19 struct mem_dev                                     
    20 {                                                        
    21   char *data;                      
    22   unsigned long size;       
    23 };
    24 
    25 /* 定义幻数 */
    26 #define MEMDEV_IOC_MAGIC  'k'
    27 
    28 /* 定义命令 */
    29 #define MEMDEV_IOCPRINT   _IO(MEMDEV_IOC_MAGIC, 1)
    30 #define MEMDEV_IOCGETDATA _IOR(MEMDEV_IOC_MAGIC, 2, int)
    31 #define MEMDEV_IOCSETDATA _IOW(MEMDEV_IOC_MAGIC, 3, int)
    32 
    33 #define MEMDEV_IOC_MAXNR 3
    34 
    35 #endif /* _MEMDEV_H_ */
    ifneq ($(KERNELRELEASE),)
    
    obj-m := memdev.o
    
    else
        
    KDIR := /home/rpi/RpiLinux
    all:
        make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=/home/rpi/RpiTools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-
    
    clean:
        rm -f *.ko *.o *.mod.o *.mod.c *.symvers  modul*
    
    endif

    测试代码:

     1 #include <stdio.h>
     2 #include<sys/types.h>
     3 #include<sys/stat.h>
     4 #include<fcntl.h>
     5 
     6 #include "memdev.h"  /* 包含命令定义 */
     7 
     8 int main()
     9 {
    10     int fd = 0;
    11     int cmd;
    12     int arg = 0;
    13     char Buf[4096];
    14     
    15     
    16     /*打开设备文件*/
    17     fd = open("/dev/memdev0",O_RDWR);
    18     if (fd < 0)
    19     {
    20         printf("Open Dev Mem0 Error!
    ");
    21         return -1;
    22     }
    23     
    24     /* 调用命令MEMDEV_IOCPRINT */
    25     printf("<--- Call MEMDEV_IOCPRINT --->
    ");
    26     cmd = MEMDEV_IOCPRINT;
    27     if (ioctl(fd, cmd, &arg) < 0)
    28         {
    29             printf("Call cmd MEMDEV_IOCPRINT fail
    ");
    30             return -1;
    31     }
    32     
    33     
    34     /* 调用命令MEMDEV_IOCSETDATA */
    35     printf("<--- Call MEMDEV_IOCSETDATA --->
    ");
    36     cmd = MEMDEV_IOCSETDATA;
    37     arg = 2007;
    38     if (ioctl(fd, cmd, &arg) < 0)
    39         {
    40             printf("Call cmd MEMDEV_IOCSETDATA fail
    ");
    41             return -1;
    42     }
    43 
    44     
    45     /* 调用命令MEMDEV_IOCGETDATA */
    46     printf("<--- Call MEMDEV_IOCGETDATA --->
    ");
    47     cmd = MEMDEV_IOCGETDATA;
    48     if (ioctl(fd, cmd, &arg) < 0)
    49         {
    50             printf("Call cmd MEMDEV_IOCGETDATA fail
    ");
    51             return -1;
    52     }
    53     printf("<--- In User Space MEMDEV_IOCGETDATA Get Data is %d --->
    
    ",arg);    
    54     
    55     close(fd);
    56     return 0;    
    57 }

    运行结果:

     1 pi@raspberrypi ~/test_driver $ sudo ./a.out 
     2 <--- Call MEMDEV_IOCPRINT --->
     3 <--- Call MEMDEV_IOCSETDATA --->
     4 <--- Call MEMDEV_IOCGETDATA --->
     5 <--- In User Space MEMDEV_IOCGETDATA Get Data is 1101 --->
     6 
     7 pi@raspberrypi ~/test_driver $ sudo dmesg
     8 [ 1382.384123] <--- memdev_ioctl is call @@@ --->
     9 [ 1382.384123] 
    10 [ 1382.384158] <--- CMD MEMDEV_IOCPRINT Done--->
    11 [ 1382.384158] 
    12 [ 1382.384541] <--- memdev_ioctl is call @@@ --->
    13 [ 1382.384541] 
    14 [ 1382.384565] <--- In Kernel MEMDEV_IOCSETDATA ioarg = 2007 --->
    15 [ 1382.384565] 
    16 [ 1382.384816] <--- memdev_ioctl is call @@@ --->
    17 [ 1382.384816] 
  • 相关阅读:
    《网络攻防》 第七周学习总结
    《网络攻防》 第六周学习总结
    《网络攻防》第五周学习总结
    网络协议分析工具wireshark
    《网络攻防》第四周学习总结
    《网络攻防》第三周总结
    黑客信息介绍
    网络攻防第二周总结
    联陪1693git项目地址汇总
    网络攻防第一周作业
  • 原文地址:https://www.cnblogs.com/renhl/p/4548126.html
Copyright © 2011-2022 走看看