20145201 20145227 《信息安全系统设计基础》实验四 内核驱动设计入门-模块方式驱动实验

20145201 20145227 《信息安全系统设计基础》实验四 内核驱动设计入门-模块方式驱动实验

北京电子科技学院(BESTI)
实 验 报 告
课程:信息安全系统设计基础 班级:1452
姓名: 鄢曼君 李子璇
学号: 20145227 20145201
成绩: 指导教师:娄嘉鹏 实验日期:2016.11.3
实验密级: 预习程度: 实验时间:10:00-12:30
仪器组次:1 必修/选修:必修 实验序号:04
实验名称:内核驱动设计入门-模块方式驱动实验
实验目的与要求:1.学习在LINUX下进行驱动设计的原理;2.掌握使用模块方式进行驱动开发调试的过程。
实验仪器:

名称 型号 数量
arm UP-TECH 1
pc Windows XP 1
虚拟机 redhat 1

一、实验过程

1.首先,如同实验一(具体步骤如:实验一),建立实验箱、虚拟机Redhat、WinXP之间的连接,在linux系统中安装arm系统,并对01_demo文件夹中的.c文件进行交叉编译

2.编译驱动模块及测试程序
在 Makefile 中有两种编译方法,可以在本机上使用gcc 也可以使用交叉编译器进行编译,这次实验我们组采用交叉编译器进行编译。如下图:

3.测试驱动程序
我们组使用交叉编译器的话,不需要建立设备节点。

使用用测试程序来进行测试,结果如下图:

二、实验过程中遇到的问题以及解决方案。

1、问题:采用交叉编译器进行编译时出现erro1错误

解决:在/usr/src 下建立一个 linux 连接,使用下面的命令:

2、解决上面问题后,make还是仍然有问题

解决:进入01_demo文件夹中,对Makefilemakefile文件进行修改,使之与指导书上一样(修改的内容较碎,检查了两次才修改完整)

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

再make之后,不会出现erro。最后执行./testdemo,结果如下:

代码分析:

  • 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代码中进行定义

  • 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 文件操作来完成。

原文地址:https://www.cnblogs.com/20145201lzx/p/6079245.html