基于內核模塊的測試代碼編寫

發表于:2014-08-03來源:uml.org.cn作者:fvceww點擊數: 標簽:測試代碼
壓縮卡驅動提供給文件系統KAPI,供文件系統對文件數據進行壓縮和解壓。在測試中,最初采用的方法是通過文件系統提供的系統調用,利用文件系統在處理系統調用時,會調用到驅動的

  1、背景

  壓縮卡驅動提供給文件系統KAPI,供文件系統對文件數據進行壓縮和解壓。在測試中,最初采用的方法是通過文件系統提供的系統調用,利用文件系統在處理系統調用時,會調用到驅動的KAPI,來完成對壓縮卡KAPI及其更下層(包含硬件)正確性的測試??紤]到這種方法,可能會由于文件系統對KAPI的具體使用方式而屏蔽一些問題的發現,因此展開了對KAPI的直接測試。由于KAPI是內核態的接口,無法在用戶態直接調用,因此要最終完成對KAPI的更直接測試,需要借助編寫內核模塊(Kernel Module),來實現用戶進程對KAPI的訪問;此外,還要解決用戶態和內核態兩者的交互。下圖中表示了引入基于內核模塊的測試方法,可以使我們的測試程序在調用關系上更加接近被測模塊,從而在測試效率和覆蓋性上得到改進。

  在本文中,將主要介紹實現基于內核模塊的測試的相關知識與代碼編寫方式。

  2、用戶態和內核態

  操作系統中,虛擬內存被分為內核空間和用戶空間。內核空間被用于內核,內核擴展功能和一些設備驅動的運行;用戶空間是用戶進程在用戶態下運行時所使用。在 linux系統中,內核擁有地址為3G到4G的內存空間,并且它是被共享的,而用戶進程擁有0到3G的用戶空間,每個用戶進程擁有獨立的空間。

  CPU根據PSW寄存器中的模式bit,可以工作在用戶態 (Ring 3)或內核態(Ring 0),用戶態能執行有限的非特權的CPU指令。在內核態可以執行所有指令。工作在用戶態的進程無法直接訪問硬件和內核的內存空間,這是出于運行安全的考慮。當然,操作系統也會也提供系統調用或中斷等方法,讓用戶進程可以切換到內核態,以訪問內核空間或硬件。系統調用或中斷,可以看作是有限度的開放給用戶進程對內核和硬件的訪問,從而保證了系統安全。

  在驅動項目中,驅動程序工作在內核空間中,它直接提供KAPI給內核,這樣我們就無法通過用戶進程完成對該KAPI的測試。當然,通過執行內核提供的系統調用,當發生磁盤讀寫時可以間接的調用到該KAPI,但是內核對其有限或具體的調用方式往往屏蔽了底層驅動的部分缺陷,這種測試方法也帶來發現問題后追查定位的困難。要改變這些不足,最直接的思路就是跨越對內核特殊邏輯間接調用的依賴,通過直接對KAPI進行調用的方法完成測試。

  為了實現對工作在內核態的KAPI的訪問,必須向內核置入內核態的代碼以發起調用,這將通過kernel module來完成,會在第三部分具體介紹。而為了實現對測試數據輸入,執行發起,結果輸出采集等的靈活控制,還必須實現用戶態和內核態的交互,具體方法將在第四部分介紹。

  3. Kernel Module

  要達成對KAPI的直接調用和測試,需要添加工作在內核態的代碼實現對該函數的訪問,這里我們借助kernel module來完成。kernel module提供了不需要重新編譯kernel image,就向內核引入新代碼和邏輯的支持。Kernel Module通常是以ko為擴展名的文件,通過lsmod命令可以查看已經加載的Kernel Module,通過insmod/rmmod命令完成指定的的模塊的加載和卸載。Kernel Module最基本的編程模式是編程者通過宏定義module_init和module_exit,指定在模塊加載和卸載時進行的初始化或清理等工作。一個基本的hello world程序如下。向init中就可以加入對KAPI進行調用的函數,當模塊被insmod時就會在內核態被執行。但是這與靈活的完成各種測試任務還有差距,為了能在用戶態完成測試數據的準備和輸入,測試結果的獲取和對執行的控制,還需要引入用戶態和內核態的交互。關于Kernel Module更詳細的編譯方式和編程模式介紹,可以參考 http://www.tldp.org/LDP/lkmpg/2.6/html/

#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */

static int __init hello_init(void){
printk(KERN_INFO "Hello, world 2\n");
return 0;
}
static void __exit hello_exit(void){
printk(KERN_INFO "Goodbye, world 2\n");}

module_init(hello_init);
module_exit(hello_exit);

  4. 用戶空間和內核空間的交互

原文轉自:http://www.uml.org.cn/Test/201210242.asp

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97