20145211《信息安全系統設計基礎》實驗四 驅動程序設計

課程:信息安全系統設計基礎
班級:1452 1453
姓名:黃志遠  王亦徐
學號:20145211 20145311
實驗日期:2016.11.24node

實驗時間:10:10-12:25linux

實驗名稱:外設驅動程序設計安全

實驗目的與要求:markdown

1.掌握實時系統應用和驅動程序的編寫
2.選擇某個接口電路框架

實驗儀器:函數






實驗儀器 型號 數量
計算機 Lenovo 1
虛擬Linux環境 Redhat 9.0 1
Arm開發板 UP-NETARM2410-CL 1

 

1、實驗內容

1.閱讀和理解源代碼

(1)功能

  • demo_read,demo_write 函數完成驅動的讀寫接口功能,do_write 函數實現將用戶寫入的數據逆序排列,經過讀取函數讀取轉換後的數據。這裏只是演示接口的實現過程和內核驅動對用戶的數據的處理。

(2)源代碼框架

#define DEVICE_NAME "demo" static ssize_t demo_write(struct file *filp,const char * buffer, size_t count) { char drv_buf[]; copy_from_user(drv_buf , buffer, count); … } static ssize_t demo_read(struct file *filp,char *buffer,size_t count,loff_t *ppos) { char drv_buf[]; copy_to_user(buffer, drv_buf,count); …. } static int demo_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg) { } static int demo_open(struct inode *inode, struct file *file) { } static int demo_release(struct inode *inode, struct file *filp) { MOD_DEC_USE_COUNT; DPRINTK("device release\n"); 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) { int result; #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 SET_MODULE_OWNER(&demo_fops); result = register_chrdev(demo_Major, "scullc", &demo_fops); if (result < 0) return result; if (demo_Major == 0) demo_Major = result; /* dynamic */ #endif printk(DEVICE_NAME " initialized\n"); return 0; } static void __exit demo_exit(void) { unregister_chrdev(demo_major, "demo"); kfree(demo_devices); printk(DEVICE_NAME " unloaded\n"); } module_init(demo_init); module_exit(demo_exit);

(3)註釋

將驅動映射爲標準接口
  • static struct file_operations demo_fops = {…}完成了將驅動函數映射爲
    標準接口。
驅動向內核註冊
  • devfs_registe()和 register_chrdev()函數完成將驅動向內核註冊。
Open方法
  • Open 方法提供給驅動程序初始化設備的能力,從而爲之後的設備操做作好準備,此外open操做通常還會遞增使用計數,用以防止文件關閉前模塊被卸載出內核。測試

    - 遞增使用計數 - 檢查特定設備錯誤。 - 若是設備是首次打開,則對其進行初始化。 - 識別次設備號,若有必要修改 f_op 指針。 - 分配並填寫 filp->private_data 中的數據。
Release 方法
  • 與 open 方法相反,release 方法應完成以下功能:ui

    - 釋放由 open 分配的 filp->private_data 中的全部內容 - 在最後一次關閉操做時關閉設備 - 使用計數減一
Read 和 和 Write 方法
ssize_t demo_write(struct file *filp,const char * buffer, size_t count,loff_t *ppos) ssize_t demo_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
  • read 方法完成將數據從內核拷貝到應用程序空間,write 方法相反,將數據從應用程
    序空間拷貝到內核。對於者兩個方法,參數 filp 是文件指針,count 是請求傳輸數據的長
    度,buffer 是用戶空間的數據緩衝區,ppos 是文件中進行操做的偏移量,類型爲 64 位數。
  • 因爲用戶空間和內核空間的內存映射方式徹底不一樣,因此不能使用象 memcpy 之類的函數,
    必須使用以下函數:spa

    unsigned long copy_to_user (void *to,const void *from,unsigned long count); unsigned long copy_from_user(void *to,const void *from,unsigned long count);
ioctl方法
  • ioctl 方法主要用於對設備進行讀寫以外的其餘控制,好比配置設備、進入或退出某種
    操做模式,這些操做通常都沒法經過 read/write 文件操做來完成。
編寫中斷處理函數的注意事項:
  • 中斷處理程序與普通C代碼沒有太大不一樣,不一樣的是中斷處理程序在中斷期間運行,它有以下限制:debug

    不能向用戶空間發送或接受數據
    不能執行有睡眠操做的函數
    不能調用調度函數
使用/proc文件系統
  • /proc 文件系統是由程序建立的文件系統,內核利用它向外輸出信息。/proc 目錄下的
    每個文件都被綁定到一個內核函數,這個函數在此文件被讀取時,動態地生成文件的內
    容。
  • 大多數狀況下 proc 目錄下的文件是隻讀的。使用/proc 的模塊必須包 含
    頭文件

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 redha
  • 附:
    - ln指令的用法是鏈接,使用格式是ln [options] source dist,這裏咱們用到的sf參數的含義是:

    -f:連接時先將與dist同檔名的檔案刪除 -s:進行軟連接。(軟連接,又稱符號連接,這個文件包含了另外一個文件的路徑名,特色是能夠連接不一樣文件系統的文件,甚至能夠連接不存在的文件。)

3.測試驅動程序

(1)創建設備節點

若是使用 gcc 編譯的話,須要經過下面的命令來創建設備節點,若是使用交叉編譯器的話,不須要創建設備節點。

#mknod /dev/demo c 254 0

(2)插入驅動模塊demo.o

能夠用 lsmod 命令來查看模塊是否已經被插入,在不使用該模塊的時候還能夠用 rmmod 命令來將模塊卸載。

    [root@zxt 01_demo]# insmod demo.o Warning: loading demo.o will taint the kernel: no license See http://www.tux.org/lkml/#export-tainted for information about tainted modules Module demo loaded, with warnings

(3)使用測試程序進行測試

- 成功後會出現下面的結果:  若是模塊沒有成功插入的話,會出現下面的狀況: [root@zxt 01_demo]# ./test_demo ####DEMO device open fail#### 

(4)測試讀過程

在驅動模塊成功插入後,會在/dev 下面創建一個叫作 demo 的設備文件,咱們也可使用 cat 命令來直接調用 read 函數,來測試讀過程。 [root@zxt demo]# cat /dev/demo/0 device open success!

2、遇到的問題

1.須要修改makefile

makefile中兩行宏變量定義用於使用armv4l-unknown-linux-gcc編譯器編譯驅動:

#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-

編譯經過:



3、實驗體會

  此次實驗咱們嘗試了不少遍。一開始配置環境時一路順風讓咱們小小的得意了一下。可是後面當咱們好不容易能夠編譯驅動又怎麼也make不出來。在多方研究下,咱們發現makefile有問題,與實驗書中不一樣。因而咱們倆人配合,將makefile用按照實驗書中一個個修改了路徑。才使得編譯成功。以後,咱們用gcc測試,又發現沒有創建節點。創建好節點以後,insmod一下才終於能夠運行。這一次實驗,出現問題之後,咱們沒有互相埋怨,而是不斷努力尋找問題緣由,詢問同窗。在改makefile時也體現了團隊合做的默契度。最終成功完成了實驗四的內容。 

相關文章
相關標籤/搜索