• 《信息安全系统设计基础》实验四实验报告


    《信息安全系统设计基础》实验四实验报告

    课程:信息安全系统设计基础

    姓名: 20145236 冯 佳 20145206 邹京儒

    班级:1452

    指导教师:娄嘉鹏

    实验日期:2016.11.10

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

    实验目的与要求:

    1. 在掌握基于 S3C2410 的 linux 开发环境的配置和使用的基础上进行交叉编译。  
      
    2. 理解驱动程序的一般设计方法。 
      
    3. (要求)正确使用连接线等实验仪器,并注意保护实验箱。实验结束之后将实验箱送回。
      

    实验内容、步骤与体会:

    一、实验内容

    (同实验一)本次实验建立在掌握嵌入式开发平台使用方法和配置方法的基础上,要求使用windows xp,linux(red hat),arm三个系统(即NFS方式);在linux系统中安装arm系统,然后对01_demo文件夹中的.c文件进行交叉编译。

    二、实验原理

    • 什么是驱动程序?

      • 目的:驱动程序是应用程序和硬件之间的一个软件层,为(许多个)应用程序提供硬件的所有功能。为了处理并发的情况,还需要考虑互斥量和锁等机制。
      • 特点:应用程序一般有一个 main 函数,从头到尾执行一个任务;驱动程序却不同,它没有main函数,通过使用宏module_init(初始化函数名)。
      • 用法:将初始化函数加入内核全局初始化函数列表中,在内核初始化时执行驱动的初始化函数,从而完成驱动的初始化和注册,之后驱动便停止等待被应用软件调用。驱动程序中有一个宏moudule_exit(退出处理函数名)注册退出处理函数。它在驱动退出时被调用。
    • 主要代码:

    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("
    *****************************************************
    ");
        }
    

    这段代码很简单,然而会出现一个疑问:write函数、read函数在哪里定义的?ioctl函数优势做什么的?于是我接下来查看了实验指导书的原理部分和demo.c代码。

    其实,上面这段代码中出现的函数都在demo.c代码中有了定义。比如,ioctl函数的定义(严格说来,驱动程序里定义的是方法):

    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;
    }

    ioctl方法主要用于对设备进行读写之外的其他控制,比如配置设备、进入或退出某种 操作模式,这些操作一般都无法通过read/write 文件操作来完成。

    三、实验过程

    1.配置实验箱

    • 同实验一中一样,配置实验环境
    • 连接arm开发板;
    • 建立超级终端;
    • 启动实验平台;
    • 修改windows xp系统的ip使得它与arm机的ip在同一网段;
    • 在red hat中安装arm编译器;
    • 配置环境变量。

    2.进入01_demo文件夹中,尝试直接make进行自动编译。出现如下图所示的错误。

    按照指导书的提示,进行如下操作建立linux连接:

    cd /usr/src/
    ln -sf linux-2.4.20-8 linux
    ls
    (结果)debug linux linux-2.4 linux-2.4.20-8 redhat
    然而,仍然出现上图的错误。

    3.这时,尝试按照如下内容修改01_demo文件夹中的Makefile.

    KERNELDIR = /usr/src/linux

    KERNELDIR = /arm2410cl/ kernel/linux-2.4.18-2410cl/

    INCLUDEDIR = $(KERNELDIR)/include

    CROSS_COMPILE=armv41-unknown-linux-

    AS =$(CROSS_COMPILE)as
    LD =$(CROSS_COMPILE)ld
    CC =$(CROSS_COMPILE)gcc
    CPP =$(CC) -E
    AR =$(CROSS_COMPILE)ar
    NM =$(CROSS_COMPILE)nm
    STRIP =$(CROSS_COMPILE)strip
    OBJCOPY =$(CROSS_COMPILE)objcopy
    OBJDUMP =$(CROSS_COMPILE)objdump
    CFLAGS += -I..
    CFLAGS += -Wall -O -D__KERNEL__ -DMODULE -I$(INCLUDEDIR)
    TARGET = demo
    OBJS = demo.o hello.o
    SRC = demo.c hello.c
    all: $(OBJS)
    demo.o: demo.c
    $(CC) -c $(CFLAGS) $^ -o $@
    hello.o:hello.c
    $(CC) -c $(CFLAGS) $^ -o $@
    install:
    install -d $(INSTALLDIR)
    install -c $(TARGET).o $(INSTALLDIR)
    clean:
    rm -f *.o *~ core .depend

    4.再次进行make之后,系统不再提示错误。然而少了最后对于testdemo.c的编译。于是,我们进行了手动编译。最后执行./testdemo,结果如下:

    四、实验中遇到的问题及总结

    1. 需要修改makefile:
      #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-

    2. 在本次实验中,当实验进行当编译那一步时总是出错,无法显现出指导书上那样正确的情况。
      解决方法:在实验中,编译我们使用了make的方法。修改虚拟机中的makefie,内容如指导书。但是应该用GCC编译,补上相关语句,修改MAKEFILE即可成功。

    3. 插入驱动模块失败如下:
      [root@zxt 01_demo]# ./test_demo
      ####DEMO device open fail####
      这个主要是因为,因为手动编译代码太为繁琐,我们选择了用make的方法,将Makefile稍微修改后就可以使用,但是我们错误的默认了make使用交叉编译,而实际上是用的gcc编译,所以缺少了设备节点的建立,补上这一步骤之后就成功了。

  • 相关阅读:
    开源项目
    [Accessibility] Missing contentDescription attribute on image [可取行]失踪contentDescription属性图像
    Android 布局 中实现适应屏幕大小及组件滚动
    EF 错误记录
    EasyUI 加载时需要显示和隐藏 panel(面板)内容破版问题
    IE 报表缩放后页面破版
    VS 2017 引入nuget 问题
    SSRS 报表显示页面 asp net session丢失或者找不到 asp net session has expired or could not be found()
    log4net 配置
    网站
  • 原文地址:https://www.cnblogs.com/feng886779/p/6096915.html
Copyright © 2020-2023  润新知