• 信息安全系统设计基础exp_4


    北京电子科技学院(BESTI)
                  
    课程:信息安全系统设计基础 班级:1353 姓名:郑伟、吴子怡
    学号:20135322、20135313 指导教师: 娄嘉鹏 实验日期:2015年11月17日
    必修/选修:必修 实验序号:exp4 实验时间:15:30-18:00
    实验名称:  exp4_外设驱动程序设计
    实验内容:在PC机上编写简单的虚拟硬件驱动程序并进行调试,实验驱动的各个接口函数的实现,分析并理解驱动与应用程序的交互过程。
    实验目的与要求 1.学习在LINUX下进行驱动设计的原理;   
    2.掌握使用模块方式进行驱动开发调试的过程 。 
    实验器材 1、Lenovo计算机一台
    2、ARM实验箱一个

     

    配置实验环境:同实验一。若不能熟练掌握,可点击如下链接查看详细步骤:

    http://www.cnblogs.com/zhengwei0712/p/4960130.html <<exp1实验报告

    一、实验步骤

    1.阅读和理解源代码

    进入/01_demo,使用vi编辑器阅读理解源代码。

    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 redhat

     

    3.测试驱动程序

    如果使用 gcc 编译的话,需要通过下面的命令来建立设备节点,如果使用交叉编译器的话,不需要建立设备节点。

    #mknod /dev/demo c 254 0

    首先要插入驱动模块demo.o,然后可以用lsmod 命令来查看模块是否已经被插入,在不使用该模块的时候还可以用rmmod 命令来将模块卸载。

    我们使用交叉编译器,不需要建立设备节点。下图为步骤成功的结果。

     

    驱动模块成功插入后,在/dev下面建立一个demo的审文件,使用cat来直接调用read函数,测试读过程。

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

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

    [root@zxt demo]# cat /dev/demo/0
    device open success!
    

    二、遇到的问题与解决方法

    在编译驱动模块的时候,makefile 有两种编译方法,可以用gcc,也可以用交叉编译器编译。当我们使用编译器进行编译的时候,出现了问题Error 1,如下图:

    第一次,可能是/usr/src下没有建立 linux连接,所以使用命令,如下图:

    第二次,经过研究,发现是makefile里的编写文件,与实验指导书里的不一样,通过进入makefile文件,修改了路径,才编译通过,如下图:

    附:代码分析

    参考驱动代码 demo.c 如下,其中的 demo_read,demo_write 函数完成驱动的读写接口功能,do_write 函数实现将用户写入的数据逆序排列,通过读取函数读取转换后的数据。
    
    这里只是演示接口的实现过程和内核驱动对用户的数据的处理。 Demo_ioctl函数演示ioctl调用接口的实现过程。
    
    test_demo.c
    
        #include <stdio.h>
    
        #include <stdlib.h>
    
        #include <fcntl.h>//其中定义了很多宏和诸如open,close函数
    
        #include <unistd.h>
    
        #include <sys/ioctl.h>//ioctl函数的头文件
    
     
    
        void showbuf(char *buf);
    
        int MAX_LEN=32;
    
     
    
        int main()
    
        {
    
            int fd;
    
            int i;
    
            char buf[255];
    
     
    
            for(i=0; i<MAX_LEN; i++){//给数组元素依次赋值
    
                buf[i]=i;
    
            }
    
     
    
            fd=open("/dev/demo",O_RDWR);//以既可以读又可以写的方式打开文件
    
            if(fd < 0){
    
                printf("####DEMO  device open fail####
    ");
    
                return (-1);
    
            }
    
            printf("write %d bytes data to /dev/demo 
    ",MAX_LEN);
    
            showbuf(buf);//先显示一下要写入什么,然后写入
    
            write(fd,buf,MAX_LEN);
    
     
    
            printf("Read %d bytes data from /dev/demo 
    ",MAX_LEN);
    
            read(fd,buf,MAX_LEN);
    
            showbuf(buf);//先读出来字符串到buf中,再显示
    
     
    
            ioctl(fd,1,NULL);
    
            ioctl(fd,4,NULL);
    
            close(fd);
    
            return 0;
    
     
    
        }
    
     
    
        void showbuf(char *buf)
    
        {
    
            int i,j=0;
    
            for(i=0;i<MAX_LEN;i++){
    
                if(i%4 ==0)
    
                    printf("
    %4d: ",j++);
    
                printf("%4d ",buf[i]);
    
            }
    
            printf("
    *****************************************************
    ");
    
        }
    
    /**************************************************************
    demo.c
    linux driver example for UP-netarm3000 & UP-netarm2410 
    It can be compiled for x86 PC
    author: zou jian-guo <ah_zou@163.com>
    date: 2004-8-20
    
    ***************************************************************/
    
    
    //#define CONFIG_DEVFS_FS
    
    
    #ifndef __KERNEL__
    # define __KERNEL__
    #endif
    #ifndef MODULE
    # define MODULE
    #endif
    
    
    #include <linux/config.h>
    #include <linux/module.h>
    #include <linux/devfs_fs_kernel.h>
    
    #include <linux/init.h>
    #include <linux/kernel.h> /* printk() */
    #include <linux/slab.h> /* kmalloc() */
    #include <linux/fs.h> /* everything... */
    #include <linux/errno.h> /* error codes */
    #include <linux/types.h> /* size_t */
    #include <linux/proc_fs.h>
    #include <linux/fcntl.h> /* O_ACCMODE */
    #include <linux/poll.h> /* COPY_TO_USER */
    #include <asm/system.h> /* cli(), *_flags */
    
    #define DEVICE_NAME	"demo"
    #define demo_MAJOR 254
    #define demo_MINOR 0
    static int MAX_BUF_LEN=1024;
    static char drv_buf[1024];
    static int WRI_LENGTH=0;
    
    /*************************************************************************************/
    /*逆序排列缓冲区数据*/
    static void do_write()
    {
    
    int i;
    int len = WRI_LENGTH;
    char tmp;
    for(i = 0; i < (len>>1); i++,len--){
    tmp = drv_buf[len-1];
    drv_buf[len-1] = drv_buf[i];
    drv_buf[i] = tmp;
    }
    }
    /*************************************************************************************/
    static ssize_t demo_write(struct file *filp,const char *buffer, size_t count)
    { 
    if(count > MAX_BUF_LEN)count = MAX_BUF_LEN;
    copy_from_user(drv_buf , buffer, count);
    WRI_LENGTH = count;
    printk("user write data to driver
    ");
    do_write();	
    return count;
    }
    /*************************************************************************************/
    static ssize_t demo_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
    {
    if(count > MAX_BUF_LEN)
    count=MAX_BUF_LEN;
    copy_to_user(buffer, drv_buf,count);
    printk("user read data from driver
    ");
    return count;
    }
    /*************************************************************************************/
    static int demo_ioctl(struct inode *inode, struct file *file, 
    unsigned int cmd, unsigned long arg)
    {
    printk("ioctl runing
    ");
    switch(cmd){
    case 1:printk("runing command 1 
    ");break;
    case 2:printk("runing command 2 
    ");break;
    default:
    printk("error cmd number
    ");break;
    }
    return 0;
    }
    /*************************************************************************************/
    static int demo_open(struct inode *inode, struct file *file)
    {
    sprintf(drv_buf,"device open sucess!
    ");
    printk("device open sucess!
    ");
    return 0;
    }
    /*************************************************************************************/
    static int demo_release(struct inode *inode, struct file *filp)
    {
    MOD_DEC_USE_COUNT;
    printk("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)
    {
    #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
    int result;
    SET_MODULE_OWNER(&demo_fops);
    result = register_chrdev(demo_MAJOR, "demo", &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);
    

      

    三、exp4学习摘要

    1.在 Makefile 中有两种编译方法,可以在本机上使用gcc。也可以使用交叉编译器进行编译,但是gcc的编译方法还有后续操作。如下:

    如果使用 gcc 编译的话,在测试驱动程序时需要通过下面的命令来建立设备节点,如果使用交叉编译器的话,不需要建立设备节点。

    #mknod /dev/demo c 254 0

    2.当make出现问题时,可尝试打开makefile文件查看编译程序的所在路径是否正确,是否能够成功链接,若不能,则应该加以修改,这一点在实验五中也会涉及。修改是一个难度较大的操作,也没有学习过。可以多加留意学习。

    四、实验体会

    通过这次实验,虽然操作不难,但我们觉得注重在于对代码的理解,以及实验遇到问题时的解决。Makefile的路径修改成功,让我们很开心,但是也深深感到了自己对理论知识的掌握还不够,makefile学得还不够精,遇到问题的时候要学会一个个地寻找问题,如果不是这个问题,就排除它,寻找下一个问题原因的可能性。由于多番尝试,最终的成功解决,不仅能使我们尝到成功的喜悦,还能使我们对问题理解和记忆地更加深刻,今后再次遇到此类问题也就不用再担心。同时还帮助同学们解决了这个问题,加深了团队合作的意识。

    实验依然是使用上次实验的环境,多次操作使得我们对ARM和REDHAT的搭建更加熟练。

    在本次实验中,我负责查找实验指导书中对问题的剖析和预测。重点关注问题的解决方法,还有上网搜查问题的结症所在和解决方案。郑伟则是负责操作和调试。在遇到问题时,我们各司其职,她对自己的操作进行检查,我积极提出问题的可能根源。合作得很高效。

    五、搭档博客传送门

    http://www.cnblogs.com/zhengwei0712/20135322郑伟

     

  • 相关阅读:
    为图片指定区域添加链接
    数值取值范围问题
    【leetcode】柱状图中最大的矩形(第二遍)
    【leetcode 33】搜索旋转排序数组(第二遍)
    【Educational Codeforces Round 81 (Rated for Div. 2) C】Obtain The String
    【Educational Codeforces Round 81 (Rated for Div. 2) B】Infinite Prefixes
    【Educational Codeforces Round 81 (Rated for Div. 2) A】Display The Number
    【Codeforces 716B】Complete the Word
    一个简陋的留言板
    HTML,CSS,JavaScript,AJAX,JSP,Servlet,JDBC,Structs,Spring,Hibernate,Xml等概念
  • 原文地址:https://www.cnblogs.com/paperfish/p/4984284.html
Copyright © 2020-2023  润新知