課程:信息安全系統設計基礎
班級: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
#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);
Open 方法提供給驅動程序初始化設備的能力,從而爲之後的設備操做作好準備,此外open操做通常還會遞增使用計數,用以防止文件關閉前模塊被卸載出內核。測試
- 遞增使用計數 - 檢查特定設備錯誤。 - 若是設備是首次打開,則對其進行初始化。 - 識別次設備號,若有必要修改 f_op 指針。 - 分配並填寫 filp->private_data 中的數據。
與 open 方法相反,release 方法應完成以下功能:ui
- 釋放由 open 分配的 filp->private_data 中的全部內容 - 在最後一次關閉操做時關閉設備 - 使用計數減一
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)
因爲用戶空間和內核空間的內存映射方式徹底不一樣,因此不能使用象 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);
中斷處理程序與普通C代碼沒有太大不一樣,不一樣的是中斷處理程序在中斷期間運行,它有以下限制:debug
不能向用戶空間發送或接受數據 不能執行有睡眠操做的函數 不能調用調度函數
上面介紹了在 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:進行軟連接。(軟連接,又稱符號連接,這個文件包含了另外一個文件的路徑名,特色是能夠連接不一樣文件系統的文件,甚至能夠連接不存在的文件。)
若是使用 gcc 編譯的話,須要經過下面的命令來創建設備節點,若是使用交叉編譯器的話,不須要創建設備節點。
#mknod /dev/demo c 254 0
能夠用 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
- 成功後會出現下面的結果: 若是模塊沒有成功插入的話,會出現下面的狀況: [root@zxt 01_demo]# ./test_demo ####DEMO device open fail####
在驅動模塊成功插入後,會在/dev 下面創建一個叫作 demo 的設備文件,咱們也可使用 cat 命令來直接調用 read 函數,來測試讀過程。 [root@zxt demo]# cat /dev/demo/0 device open success!
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-
編譯經過:
此次實驗咱們嘗試了不少遍。一開始配置環境時一路順風讓咱們小小的得意了一下。可是後面當咱們好不容易能夠編譯驅動又怎麼也make不出來。在多方研究下,咱們發現makefile有問題,與實驗書中不一樣。因而咱們倆人配合,將makefile用按照實驗書中一個個修改了路徑。才使得編譯成功。以後,咱們用gcc測試,又發現沒有創建節點。創建好節點以後,insmod一下才終於能夠運行。這一次實驗,出現問題之後,咱們沒有互相埋怨,而是不斷努力尋找問題緣由,詢問同窗。在改makefile時也體現了團隊合做的默契度。最終成功完成了實驗四的內容。