20145201 20145227 《資訊保安系統設計基礎》實驗四 核心驅動設計入門-模組方式驅動實驗

20145201李子璇發表於2016-11-27

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 也可以使用交叉編譯器進行編譯,這次實驗我們組採用交叉編譯器進行編譯。如下圖:
20145201 20145227 《資訊保安系統設計基礎》實驗四 核心驅動設計入門-模組方式驅動實驗

3.測試驅動程式
我們組使用交叉編譯器的話,不需要建立裝置節點。

使用用測試程式來進行測試,結果如下圖:
20145201 20145227 《資訊保安系統設計基礎》實驗四 核心驅動設計入門-模組方式驅動實驗

二、實驗過程中遇到的問題以及解決方案。

1、問題:採用交叉編譯器進行編譯時出現erro1錯誤

解決:在/usr/src 下建立一個 linux 連線,使用下面的命令:
20145201 20145227 《資訊保安系統設計基礎》實驗四 核心驅動設計入門-模組方式驅動實驗

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

20145201 20145227 《資訊保安系統設計基礎》實驗四 核心驅動設計入門-模組方式驅動實驗

再make之後,不會出現erro。最後執行./testdemo,結果如下:

20145201 20145227 《資訊保安系統設計基礎》實驗四 核心驅動設計入門-模組方式驅動實驗

程式碼分析:

  • 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####\n");
            return (-1);
        }
        printf("write %d bytes data to /dev/demo \n",MAX_LEN);
        showbuf(buf);//先顯示一下要寫入什麼,然後寫入
        write(fd,buf,MAX_LEN);

        printf("Read %d bytes data from /dev/demo \n",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("\n%4d: ",j++);
            printf("%4d ",buf[i]);
        }
        printf("\n*****************************************************\n");
    }

程式碼中出現的函式都在demo.c程式碼中進行定義

  • ioctl函式的定義:
static int demo_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
    printk("ioctl runing\n");
    switch(cmd){
        case 1:printk("runing command 1 \n");break;
        case 2:printk("runing command 2 \n");break;
        default:
            printk("error cmd number\n");break;
    }
return 0;
}

ioctl 方法主要用於對裝置進行讀寫之外的其他控制,比如配置裝置、進入或退出某種 操作模式,這些操作一般都無法通過read/write 檔案操作來完成。

相關文章