• 信息安全系统设计基础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郑伟

     

  • 相关阅读:
    GDI+ 支持的图片文件格式
    Linux学习-灾难复原的考虑
    Linux学习-备份策略
    Linux学习-备份的种类、频率与工具的选择
    Linux学习-备份要点
    Linux学习-服务器硬件数据的收集
    Linux学习-系统基本设定
    Linux学习-开机过程的问题解决
    Linux学习-Boot Loader: Grub2
    Linux学习-核心与核心模块
  • 原文地址:https://www.cnblogs.com/paperfish/p/4984284.html
Copyright © 2020-2023  润新知