zoukankan      html  css  js  c++  java
  • 20145211《信息安全系统设计基础》实验四 驱动程序设计

    课程:信息安全系统设计基础
    班级:1452 1453
    姓名:黄志远  王亦徐
    学号:20145211 20145311
    实验日期:2016.11.24

    实验时间:10:10-12:25

    实验名称:外设驱动程序设计

    实验目的与要求:

    1.掌握实时系统应用和驱动程序的编写
    2.选择某个接口电路

    实验仪器:






    实验仪器 型号 数量
    计算机 Lenovo 1
    虚拟Linux环境 Redhat 9.0 1
    Arm开发板 UP-NETARM2410-CL 1

    一、实验内容

    1.阅读和理解源代码

    (1)功能

    • demo_read,demo_write 函数完成驱动的读写接口功能,do_write 函数实现将用户写入的数据逆序排列,通过读取函数读取转换后的数据。这里只是演示接口的实现过程和内核驱动对用户的数据的处理。

    (2)源代码框架

    #define DEVICE_NAME  "demo"
    static ssize_t demo_write(struct file *filp,const char * buffer, size_t count)
    { 
        char drv_buf[];
        copy_from_user(drv_buf , buffer, count);
        …
    }
    static ssize_t demo_read(struct file *filp,char *buffer,size_t count,loff_t *ppos)
    {
    char drv_buf[];
    copy_to_user(buffer, drv_buf,count);
    ….
    }
    static int demo_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg)
    {
    }
    static int demo_open(struct inode *inode, struct file *file)
    {
    }
    static int demo_release(struct inode *inode, struct file *filp)
    {
        MOD_DEC_USE_COUNT;
        DPRINTK("device release
    ");
        return 0;
    }
    static struct file_operations demo_fops = {
        owner:  THIS_MODULE,
        write:demo_write, 
        read: demo_read, 
        ioctl: demo_ioctl,
        open: demo_open,
        release:demo_release,
    };
    #ifdef CONFIG_DEVFS_FS
    static devfs_handle_t devfs_demo_dir, devfs_demoraw;
    #endif
    static int __init demo_init(void)
    {
        int result;
        #ifdef CONFIG_DEVFS_FS
        devfs_demo_dir = devfs_mk_dir(NULL, "demo", NULL);
        devfs_demoraw = devfs_register(devfs_demo_dir, "0", DEVFS_FL_DEFAULT,
        demo_Major, demo_MINOR, S_IFCHR | S_IRUSR | S_IWUSR,&demo_fops, NULL);
        #else
        SET_MODULE_OWNER(&demo_fops);
        result = register_chrdev(demo_Major, "scullc", &demo_fops);
        if (result < 0) return result;
        if (demo_Major == 0) demo_Major = result; /* dynamic */
        #endif
        printk(DEVICE_NAME " initialized
    ");
        return 0;
    }
    static void __exit demo_exit(void)
    {
        unregister_chrdev(demo_major, "demo");
        kfree(demo_devices);
        printk(DEVICE_NAME " unloaded
    ");
    }
    module_init(demo_init);
    module_exit(demo_exit);

    (3)注释

    将驱动映射为标准接口
    • static struct file_operations demo_fops = {…}完成了将驱动函数映射为
      标准接口。
    驱动向内核注册
    • devfs_registe()和 register_chrdev()函数完成将驱动向内核注册。
    Open方法
    • Open 方法提供给驱动程序初始化设备的能力,从而为以后的设备操作做好准备,此外open操作一般还会递增使用计数,用以防止文件关闭前模块被卸载出内核。

      - 递增使用计数
      - 检查特定设备错误。
      - 如果设备是首次打开,则对其进行初始化。
      - 识别次设备号,如有必要修改 f_op 指针。
      - 分配并填写 filp->private_data 中的数据。
    Release 方法
    • 与 open 方法相反,release 方法应完成如下功能:

      - 释放由 open 分配的 filp->private_data 中的所有内容
      - 在最后一次关闭操作时关闭设备
      - 使用计数减一
    Read 和 和 Write 方法
    ssize_t demo_write(struct file *filp,const char * buffer, size_t count,loff_t *ppos)
    ssize_t demo_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
    • read 方法完成将数据从内核拷贝到应用程序空间,write 方法相反,将数据从应用程
      序空间拷贝到内核。对于者两个方法,参数 filp 是文件指针,count 是请求传输数据的长
      度,buffer 是用户空间的数据缓冲区,ppos 是文件中进行操作的偏移量,类型为 64 位数。
    • 由于用户空间和内核空间的内存映射方式完全不同,所以不能使用象 memcpy 之类的函数,
      必须使用如下函数:

      unsigned long copy_to_user (void *to,const void *from,unsigned long count);
      unsigned long copy_from_user(void *to,const void *from,unsigned long count);
    ioctl方法
    • ioctl 方法主要用于对设备进行读写之外的其他控制,比如配置设备、进入或退出某种
      操作模式,这些操作一般都无法通过 read/write 文件操作来完成。
    编写中断处理函数的注意事项:
    • 中断处理程序与普通C代码没有太大不同,不同的是中断处理程序在中断期间运行,它有如下限制:

      不能向用户空间发送或接受数据
      不能执行有睡眠操作的函数
      不能调用调度函数
    使用/proc文件系统
    • /proc 文件系统是由程序创建的文件系统,内核利用它向外输出信息。/proc 目录下的
      每一个文件都被绑定到一个内核函数,这个函数在此文件被读取时,动态地生成文件的内
      容。
    • 大多数情况下 proc 目录下的文件是只读的。使用/proc 的模块必须包 含
      头文件

    2.编译驱动模块及测试程序

    • 上面介绍了在 Makefile 中有两种编译方法,可以在本机上使用 gcc 也可以使用交叉编译器进行编译,这里我们只介绍用交叉编译器进行编译的结果。

    • 注意:如果编译的时候出现问题,可能是在/usr/src 下没有建立一个 linux 连接,可以使用下面的命令:

      [root@zxt 01_demo]# cd /usr/src/
      [root@zxt src]# ln –sf   linux-2.4.20-8  linux
      [root@zxt src]# ls
      debug  linux  linux-2.4  linux-2.4.20-8  redha
    • 附:
      - ln指令的用法是连接,使用格式是ln [options] source dist,这里我们用到的sf参数的含义是:

      -f:链接时先将与dist同档名的档案删除
      
      -s:进行软链接。(软链接,又称符号链接,这个文件包含了另一个文件的路径名,特点是可以链接不同文件系统的文件,甚至可以链接不存在的文件。)

    3.测试驱动程序

    (1)建立设备节点

    如果使用 gcc 编译的话,需要通过下面的命令来建立设备节点,如果使用交叉编译器的话,不需要建立设备节点。
    
    #mknod /dev/demo c 254 0

    (2)插入驱动模块demo.o

    可以用 lsmod 命令来查看模块是否已经被插入,在不使用该模块的时候还可以用 rmmod 命令来将模块卸载。
    
        [root@zxt 01_demo]# insmod demo.o
        Warning: loading demo.o will taint the kernel: no license
        See http://www.tux.org/lkml/#export-tainted for information about tainted modules
        Module demo loaded, with warnings

    (3)使用测试程序进行测试

    - 成功后会出现下面的结果:
    
    如果模块没有成功插入的话,会出现下面的情况:
    [root@zxt 01_demo]# ./test_demo
    ####DEMO  device open fail####  

    (4)测试读过程

    在驱动模块成功插入后,会在/dev 下面建立一个叫做 demo 的设备文件,我们也可以使用 cat 命令来直接调用 read 函数,来测试读过程。
        [root@zxt demo]# cat /dev/demo/0
        device open success!

    二、遇到的问题

    1.需要修改makefile

    makefile中两行宏变量定义用于使用armv4l-unknown-linux-gcc编译器编译驱动:

    #KERNELDIR = /arm2410cl/ kernel/linux-2.4.18-2410cl/
    #CROSS_COMPILE= armv4l-unknown-linux-

    由于makefile文件中KERNEL_PATH设置和真实环境有点不同,修改makefile文件中的路径就好了。

    修改后:

    KERNELDIR = /usr/src/linux
    #KERNELDIR = /arm2410cl/ kernel/linux-2.4.18-2410cl/
    INCLUDEDIR = $(KERNELDIR)/include
    #CROSS_COMPILE=armv41-unknown-linux-

    编译通过:



    三、实验体会

      这次实验我们尝试了很多遍。一开始配置环境时一帆风顺让我们小小的得意了一下。但是后面当我们好不容易可以编译驱动又怎么也make不出来。在多方研究下,我们发现makefile有问题,与实验书中不同。于是我们俩人配合,将makefile用按照实验书中一个个修改了路径。才使得编译成功。之后,我们用gcc测试,又发现没有建立节点。建立好节点之后,insmod一下才终于可以运行。这一次实验,出现问题以后,我们没有互相埋怨,而是不断努力寻找问题原因,询问同学。在改makefile时也体现了团队合作的默契度。最终成功完成了实验四的内容。 

     
  • 相关阅读:
    Leetcode Unique Binary Search Trees
    Leetcode Decode Ways
    Leetcode Range Sum Query 2D
    Leetcode Range Sum Query
    Leetcode Swap Nodes in Pairs
    Leetcode Rotate Image
    Leetcode Game of Life
    Leetcode Set Matrix Zeroes
    Leetcode Linked List Cycle II
    CF1321A
  • 原文地址:https://www.cnblogs.com/nostalgia-/p/6104155.html
Copyright © 2011-2022 走看看