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####\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 檔案操作來完成。