凌陽教育linux培訓之linux驅(qū)動基礎開發(fā)免費教程_第1頁
凌陽教育linux培訓之linux驅(qū)動基礎開發(fā)免費教程_第2頁
凌陽教育linux培訓之linux驅(qū)動基礎開發(fā)免費教程_第3頁
凌陽教育linux培訓之linux驅(qū)動基礎開發(fā)免費教程_第4頁
凌陽教育linux培訓之linux驅(qū)動基礎開發(fā)免費教程_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、以下是凌陽教育的嵌入式linux培訓資深講師-徐老師提供的免費的linux驅(qū)動基礎開發(fā)教程(linux驅(qū)動基礎開發(fā)0- linux驅(qū)動基礎開發(fā)3)理論加實例詳解,重點紅字標注。linux初學者必看!一:linux驅(qū)動基礎開發(fā)0-linux 設備驅(qū)動概述目前,Linux軟件工程師大致可分為兩個層次:(1)Linux應用軟件工程師(Application Software Engineer):主要利用C庫函數(shù)和Linux API進行應用軟件的編寫;從事這方面的開發(fā)工作,主要需要學習:符合linux posix標準的API函數(shù)及系統(tǒng)調(diào)用,linux的多任務編程技巧:多進程、多線程、進程間通信、多任務

2、之間的同步互斥等,嵌入式數(shù)據(jù)庫的學習,UI編程:QT、miniGUI等。(2)Linux固件工程師(Firmware Engineer):主要進行Bootloader、Linux的移植及Linux設備驅(qū)動程序的設計工作。一般而言,固件工程師的要求要高于應用軟件工程師的層次,而其中的Linux設備驅(qū)動編程又是Linux程序設計中比較復雜的部分,究其原因,主要包括如下幾個方面:1)設備驅(qū)動屬于Linux內(nèi)核的部分,編寫Linux設備驅(qū)動需要有一定的Linux操作系統(tǒng)內(nèi)核基礎;需要了解部分linux內(nèi)核的工作機制與系統(tǒng)組成。2)編寫Linux設備驅(qū)動需要對硬件的原理有相當?shù)牧私?,大多?shù)情況下我們是針

3、對一個特定的嵌入式硬件平臺編寫驅(qū)動的,例如:針對特定的主機平臺:可能是三星的2410、2440,也可能是atmel的,或者飛思卡爾的等等。3)Linux設備驅(qū)動中廣泛涉及到多進程并發(fā)的同步、互斥等控制,容易出現(xiàn)bug;因為linux本身是一個多任務的工作環(huán)境,不可避免的會出現(xiàn)在同一時刻對同一設備發(fā)生并發(fā)操作。4)由于屬于內(nèi)核的一部分,Linux設備驅(qū)動的調(diào)試也相當復雜。linux設備驅(qū)動沒有一個很好的IDE環(huán)境進行單步、變量查看等調(diào)試輔助工具;linux驅(qū)動跟linux內(nèi)核工作在同一層次,一旦發(fā)生問題,很容易造成內(nèi)核的整體崩潰。本系列文章我們將一步步、深入淺出的介紹linux設備驅(qū)動編程中設計

4、的一些問題及學習方法,希望對大家學習linux設備驅(qū)動有所幫助。在任何一個計算機系統(tǒng)中,大至服務器、PC機、小至手機、mp3/mp4播放器,無論是復雜的大型服務器系統(tǒng)還是一個簡單的流水燈單片機系統(tǒng),都離不開驅(qū)動程序的身影,沒有硬件的軟件是空中樓閣,沒有軟件的硬件只是一堆廢鐵,硬件是底層的基礎,是所有軟件得以運行的平臺,代碼最終會落實到硬件上的邏輯組合。但是硬件與軟件之間存在一個駁論:為了快速、優(yōu)質(zhì)的完成軟件功能設計,應用程序工程師不想也不愿關(guān)心硬件,而硬件工程師也很難有功夫去處理軟件開發(fā)中的一些應用。例如軟件工程師在調(diào)用printf的時候,不許也不用關(guān)心信息到底是通過什么樣的處理,走過哪些通路

5、顯示在該顯示的地方,硬件工程師在寫完了一個4*4鍵盤驅(qū)動后,無需也不必管應用程序在獲得鍵值后做哪些處理及操作。也就是說軟件工程師需要看到一個沒有硬件的純軟件世界,硬件必須透明的提供給他,誰來實現(xiàn)這一任務?答案是驅(qū)動程序,驅(qū)動程序從字面解釋就是:“驅(qū)使硬件設備行動”。驅(qū)動程序直接與硬件打交道,按照硬件設備的具體形式,驅(qū)動設備的寄存器,完成設備的輪詢、中斷處理、DMA通信,最終讓通信設備可以收發(fā)數(shù)據(jù),讓顯示設備能夠顯示文字和畫面,讓音頻設備可以完成聲音的存儲和播放。2.模塊卸載函數(shù)可見,設備驅(qū)動程序充當了硬件和軟件之間的樞紐,因此驅(qū)動程序的表現(xiàn)形式可能就是一些標準的、事先協(xié)定好的API函數(shù),驅(qū)動工

6、程師只需要去完成相應函數(shù)的填充,應用工程師只需要調(diào)用相應的接口完成相應的功能。無論有沒有操作系統(tǒng),驅(qū)動程序都有其存在價值,只是在裸機情況下,工作環(huán)境比較簡單、完成的工作較單一,驅(qū)動程序完成的功能也就比較簡單,同時接口只要在小范圍內(nèi)符合統(tǒng)一的標準即可。但是在有操作系統(tǒng)的情況下,此問題就會被放大:硬件來自不同的公司、千變?nèi)f化,全世界每天都會有大量的新芯片被生產(chǎn),大量的電路板被設計出來,如果沒有一個很好的統(tǒng)一標準去規(guī)范這一程序,操作系統(tǒng)就會被設計的非常冗余,效率會非常低。所以無論任何操作系統(tǒng)都會制定一套標準的架構(gòu)去管理這些驅(qū)動程序:linux作為嵌入式操作系統(tǒng)的典范,其驅(qū)動架構(gòu)具有很高的規(guī)范性與聚合

7、性,不但把不同的硬件設備分門別類、綜合管理,并且針對不同硬件的共性進行了統(tǒng)一抽象,將其硬件相關(guān)性降到最低,大大簡化了驅(qū)動程序的編寫,形成了具有其特色的驅(qū)動組織架構(gòu)。下圖反映了應用程序、linux內(nèi)核、驅(qū)動程序、硬件的關(guān)系。 linux內(nèi)核分為5大部分:多任務管理、內(nèi)存管理、文件系統(tǒng)管理、設備管理、網(wǎng)絡管理;每一部分都有承上下的作用,對上提供API接口,提供給應用開發(fā)工程師使用;對下通過驅(qū)動程序屏蔽不同的硬件構(gòu)成,完成硬件的具體操作。二:linux驅(qū)動基礎開發(fā)1linux 設備驅(qū)動基本概念學習linux設備驅(qū)動首先我們必須明確以下幾個概念,為我們接下來學習linux驅(qū)動打下堅實的基礎:應用程序、

8、庫、內(nèi)核、驅(qū)動程序的關(guān)系:設備類型設備文件、主設備號與從設備號驅(qū)動程序與應用程序的區(qū)別用戶態(tài)與內(nèi)核態(tài)Linux驅(qū)動程序功能一、應用程序、庫、內(nèi)核、驅(qū)動程序的關(guān)系1)應用程序調(diào)用一系列函數(shù)庫,通過對文件的操作完成一系列功能:應用程序以文件形式訪問各種硬件設備(linux特有的抽象方式,把所有的硬件訪問抽象為對文件的讀寫、設置)函數(shù)庫:部分函數(shù)無需內(nèi)核的支持,由庫函數(shù)內(nèi)部通過代碼實現(xiàn),直接完成功能部分函數(shù)涉及到硬件操作或內(nèi)核的支持,由內(nèi)核完成對應功能,我們稱其為系統(tǒng)調(diào)用2)內(nèi)核處理系統(tǒng)調(diào)用,根據(jù)設備文件類型、主設備號、從設備號(后面會講解),調(diào)用設備驅(qū)動程序;3)設備驅(qū)動直接與硬件通信; 二、設備

9、類型硬件是千變?nèi)f化的,沒有八千也有一萬了,就像世界上有三種人:男人、女人、女博士一樣,linux做了一個很偉大也很艱難的分類:把所有的硬件設備分為三大類:字符設備、塊設備、網(wǎng)絡設備。1) 字符設備:字符(char)設備是個能夠像字節(jié)流(類似文件)一樣被訪問的設備。對字符設備發(fā)出讀/寫請求時,實際的硬件I/O操作一般緊接著發(fā)生;字符設備驅(qū)動程序通常至少要實現(xiàn)open、close、read和write系統(tǒng)調(diào)用。比如我們常見的lcd、觸摸屏、鍵盤、led、串口等等,就像男人是用來干活的一樣,他們一般對應具體的硬件都是進行出具的采集、處理、傳輸。2) 塊設備:一個塊設備驅(qū)動程序主要通過傳輸固定大小的數(shù)

10、據(jù)(一般為512或1k)來訪問設備。塊設備通過buffer cache(內(nèi)存緩沖區(qū))訪問,可以隨機存取,即:任何塊都可以讀寫,不必考慮它在設備的什么地方。塊設備可以通過它們的設備特殊文件訪問,但是更常見的是通過文件系統(tǒng)進行訪問。只有一個塊設備可以支持一個安裝的文件系統(tǒng)。比如我們常見的電腦硬盤、SD卡、U盤、光盤等,就像女人一樣是用來存儲信息的。3) 網(wǎng)絡接口:任何網(wǎng)絡事務都經(jīng)過一個網(wǎng)絡接口形成,即一個能夠和其他主機交換數(shù)據(jù)的設備。訪問網(wǎng)絡接口的方法仍然是給它們分配一個唯一的名字(比如eth0),但這個名字在文件系統(tǒng)中不存在對應的節(jié)點。內(nèi)核和網(wǎng)絡設備驅(qū)動程序間的通信,完全不同于內(nèi)核和字符以及塊驅(qū)

11、動程序之間的通信,內(nèi)核調(diào)用一套和數(shù)據(jù)包傳輸相關(guān)的函數(shù)(socket函數(shù))而不是read、write等。比如我們常見的網(wǎng)卡設備、藍牙設備,就像女博士一樣,數(shù)量稀少但又不可或缺。linux中所有的驅(qū)動程序最終都能歸到這三種設備中,當然他們之間也沒有非常嚴格的界限,這些都是程序中對他們的劃分而已,比如一個sd卡,我們也可以把它封裝成字符設備去操作也是沒有問題的。就像三、設備文件、主設備號、從設備號有了設備類型的劃分,那么應用程序應該怎樣訪問具體的硬件設備呢?或者說已經(jīng)確定他是一個男人了,那么怎么從萬千世界中區(qū)分他與他的不同呢?答案是:姓名,在linux驅(qū)動中也就是設備文件名。那么重名怎么辦?答案是:

12、身份證號,在linux驅(qū)動中也就是設備號(主、從)。設備文件:在linux 系統(tǒng) 中有一個約定俗成的說法:“一切皆文件”, 應用程序使用設備文件節(jié)點訪問對應設備, Linux下的各種硬件設備以文件的形式存放于/dev目錄下,可以使用ls /dev 查看 Linux把對硬件的操作全部抽象成對文件的操作 (open,read,write,close,)每個設備文件都有其文件屬性(c或者b),使用ls /dev -l 的命令查看, 表明其是字符設備或者塊設備,網(wǎng)絡設備沒有在這個文件夾下,用來明其性別(男人、女人)主設備號、從設備號在設備管理中,除了設備類型外,內(nèi)核還需要一對被稱為主從設備號的參數(shù),才

13、能唯一標識一個設備,類似人的身份證號主設備號:用于標識驅(qū)動程序,相同的主設備號使用相同的驅(qū)動程序,例如:S3C2440 有串口、LCD、觸摸屏三種設備,他們的主設備號各不相同;從設備號:用于標識同一驅(qū)動程序的不同硬件例:PC的IDE設備,主設備號用于標識該硬盤,從設備號用于標識每個分區(qū),2440有三個串口,每個串口的主設備號相同,從設備號用于區(qū)分具體屬于那一個串口。四、驅(qū)動程序與應用程序的區(qū)別應用程序以main開始驅(qū)動程序沒有main,它以一個模塊初始化函數(shù)作為入口應用程序從頭到尾執(zhí)行一個任務驅(qū)動程序完成初始化之后不再運行,等待系統(tǒng)調(diào)用應用程序可以使用glibc等標準C函數(shù)庫驅(qū)動程序不能使用標

14、準C庫五、用戶態(tài)與內(nèi)核態(tài)的區(qū)分驅(qū)動程序是內(nèi)核的一部分,工作在內(nèi)核態(tài)應用程序工作在用戶態(tài)數(shù)據(jù)空間訪問問題無法通過指針直接將二者的數(shù)據(jù)地址進行傳遞系統(tǒng)提供一系列函數(shù)幫助完成數(shù)據(jù)空間轉(zhuǎn)換get_userput_usercopy_from_usercopy_to_user六、Linux驅(qū)動程序功能對設備初始化和釋放資源把數(shù)據(jù)從內(nèi)核傳送到硬件和從硬件讀取數(shù)據(jù)讀取應用程序傳送給設備文件的數(shù)據(jù)和回送應用程序請求的數(shù)據(jù)檢測和處理設備出現(xiàn)的錯誤(底層協(xié)議)用于區(qū)分具體設備的實例三:linux驅(qū)動基礎開發(fā)2linux 驅(qū)動開發(fā)前奏(模塊編程)一、linux內(nèi)核模塊簡介linux內(nèi)核整體結(jié)構(gòu)非常龐大,其包含的組件也

15、非常多。我們怎么把需要的部分都包含在內(nèi)核中呢?一種辦法是把所有的需要的功能都編譯到內(nèi)核中。這會導致兩個問題,一是生成的內(nèi)核會很大,二是如果我們要在現(xiàn)有的內(nèi)核中新增或刪除功能,不得不重新編譯內(nèi)核,工作效率會非常的低,同時如果編譯的模塊不是很完善,很有可能會造成內(nèi)核崩潰。linux提供了另一種機制來解決這個問題,這種集中被稱為模塊,可以實現(xiàn)編譯出的內(nèi)核本身并不含有所有功能,而在這些功能需要被使用的時候,其對應的代碼可以被動態(tài)的加載到內(nèi)核中。二、模塊特點:1)模塊本身并不被編譯入內(nèi)核,從而控制了內(nèi)核的大小。2)模塊一旦被加載,他就和內(nèi)核中的其他部分完全一樣。注意:模塊并不是驅(qū)動的必要形式:即:驅(qū)動不

16、一定必須是模塊,有些驅(qū)動是直接編譯進內(nèi)核的;同時模塊也不全是驅(qū)動,例如我們寫的一些很小的算法可以作為模塊編譯進內(nèi)核,但它并不是驅(qū)動。就像燒餅不一定是圓的,圓的也不都是燒餅一樣。三、最簡單的模塊分析1)以下是一個最簡單的模塊例子1. #include <linux/init.h>         /* printk() */  2. #include <linux/module.h>   

17、60;   /* _init _exit */  3.   4. static int  _init  hello_init(void)      /*模塊加載函數(shù),通過insmod命令加載模塊時,被自動執(zhí)行*/  5.   6.   printk(KERN_INFO " Hello Wo

18、rld entern");  7.   return 0;  8.   9. static void  _exit  hello_exit(void)    /*模塊卸載函數(shù),當通過rmmod命令卸載時,會被自動執(zhí)行*/  10.   11.   printk(KERN_INFO " Hello W

19、orld exitn ");  12.   13.   14. module_init(hello_init);  15. module_exit(hello_exit);  16.   17. MODULE_AUTHOR("dengwei");           /*模塊作者,可選*/  18.

20、 MODULE_LICENSE("Dual BSD/GPL");     /*模塊許可證明,描述內(nèi)核模塊的許可權(quán)限,必須*/  19.   20. MODULE_DESCRIPTION("A simple Hello World Module"); /*模塊說明,可選*/  21. MODULE_ALIAS("a simplest module")

21、;                  /*模塊說明,可選*/<span style="font-family:SimSun;font-size:18px;color:#FF0000;"><strong>  22. </strong></span>  2) 以下是編譯上述模塊所需的編寫的makefile

22、1. obj-m :=hello.o                     /目標文件  2. #module-objs := file1.o file.o      /當模塊有多個文件組成時,添加本句  3. KDIR :=/usr/s

23、rc/linux               /內(nèi)核路徑,根據(jù)實際情況換成自己的內(nèi)核路徑,嵌入式的換成嵌入式,PC機的指定PC機路徑  4. PWD := $(shell pwd)                 /模塊源文件路徑

24、  5. all:      6.     $(MAKE)  -C  $(KDIR)  SUBDIRS=$(PWD)  modules  7.     rm -rf *.mod.*  8.     rm -rf .*.cmd &#

25、160;9.     rm -rf *.o  10.     rm -rf Module.*  11. clean:  12.     rm -rf *.ko  最終會編譯得到:hello.ko文件使用insmodhello.ko將模塊插入內(nèi)核,然后使用dmesg即可看到輸出提示信息。常用的幾種模塊操作:insmod XXX.ko 加載指

26、定模塊lsmod 列舉當前系統(tǒng)中的所有模塊rmmod XXX 卸載指定模塊(注意沒有。ko后綴)dmesg 當打印等級低于默認輸出等級時,采用此命令查看系統(tǒng)日志3)linux內(nèi)核模塊的程序結(jié)構(gòu)1.模塊加載函數(shù):Linux內(nèi)核模塊一般以_init標示聲明,典型的模塊加載函數(shù)的形式如下:1. static int _init myModule_init(void)  2.   3.     /* Module init code */ &#

27、160;4.     PRINTK("myModule_initn");  5.     return 0;  6.   7. module_init(myModule_init);  模塊加載函數(shù)的名字可以隨便取,但必須以“module_init(函數(shù)名)”的形式被指定;執(zhí)行insmod命令時被執(zhí)行,用于初始化模塊所必需資源,比如內(nèi)存空間、硬件設備等;它返回整形值,若初始化成功,應返回0,初始化失敗返回負

28、數(shù)。2.模塊卸載函數(shù)典型的模塊卸載函數(shù)形式如下:1. static void _exit myModule_exit(void)  2.   3.     /* Module exit code */  4.     PRINTK("myModule_exitn");  5.     return; 

29、; 6.   7. module_exit(myModule_exit);  模塊卸載函數(shù)在模塊卸載的時候執(zhí)行,不返回任何值,需用“module_exit(函數(shù)名)”的形式被指定。卸載模塊完成與加載函數(shù)相反的功能:若加載函數(shù)注冊了XXX,則卸載函數(shù)應當注銷XXX若加載函數(shù)申請了內(nèi)存空間,則卸載函數(shù)應當釋放相應的內(nèi)存空間若加載函數(shù)申請了某些硬件資源(中斷、DMA、I/0端口、I/O內(nèi)存等),則卸載函數(shù)應當釋放相應的硬件資源若加載函數(shù)開啟了硬件,則卸載函數(shù)應當關(guān)閉硬件。其中_init 、_exit 為系統(tǒng)提供的兩種宏,表示其所修飾的函數(shù)在調(diào)用完成后

30、會自動回收內(nèi)存,即內(nèi)核認為這種函數(shù)只會被執(zhí)行1次,然后他所占用的資源就會被釋放。3.模塊聲明與描述在linux內(nèi)核模塊中,我們可以用MODULE_AUTHOR、MODULE_DESCRIPTION、MODULE_VERSION、MODULE_TABLE、MODULE_ALIA,分別描述模塊的作者、描述、版本、設備表號、別名等。1. MODULE_AUTHOR("dengwei");  2. MODULE_LICENSE("Dual BSD/GPL");  3. MODULE_DESCRIPTION(&qu

31、ot;A simple Hello World Module");  4. MODULE_ALIAS("a simplest module"); 四、有關(guān)模塊的其它特性1)模塊參數(shù):我們可以利用module_param(參數(shù)名、參數(shù)類型、參數(shù)讀寫屬性) 為模塊定義一個參數(shù),例如:1. static char *string_test = “this is a test”;  2. sta

32、tic num_test = 1000;    3. module_param (num_test,int,S_IRUGO);  4. module_param (steing_test,charp,S_ITUGO);  在裝載模塊時,用戶可以給模塊傳遞參數(shù),形式為:“insmod 模塊名 參數(shù)名=參數(shù)值”,如果不傳遞,則參數(shù)使用默認的參數(shù)值參數(shù)的類型可以是:byte,short,ushort,int,uint,long,ulong,charp,bool;權(quán)限:定義

33、在linux/stat.h中,控制存取權(quán)限,S_IRUGO表示所有用戶只讀;模塊被加載后,在sys/module/下會出現(xiàn)以此模塊命名的目錄,當讀寫權(quán)限為零時:表示此參數(shù)不存在sysfs文件系統(tǒng)下的文件節(jié)點,當讀寫權(quán)限不為零時:此模塊的目錄下會存在parameters目錄,包含一系列以參數(shù)名命名的文件節(jié)點,這些文件節(jié)點的權(quán)限值就是傳入module_param()的“參數(shù)讀/寫權(quán)限”,而該文件的內(nèi)容為參數(shù)的值。除此之外,模塊也可以擁有參數(shù)數(shù)組,形式為:“module_param_array(數(shù)組名、數(shù)組類型、數(shù)組長、參數(shù)讀寫權(quán)限等)”,當不需要保存實際的輸入的數(shù)組元素的個數(shù)時,可以設置“數(shù)組長”

34、為0。運行insmod時,使用逗號分隔輸入的數(shù)組元素。下面是一個實際的例子,來說明模塊傳參的過程。1. #include <linux/module.h>    /*module_init()*/  2. #include <linux/kernel.h> /* printk() */  3. #include <linux/init.h>       

35、;/* _init _exit */  4.   5. #define DEBUG   /open debug message  6.   7. #ifdef DEBUG  8. #define PRINTK(fmt, arg.)     printk(KERN_WARNING fmt, #arg) 

36、; 9. #else  10. #define PRINTK(fmt, arg.)     printk(KERN_DEBUG fmt, #arg)  11. #endif  12.   13. static char *string_test="default paramater"  14. static int num_te

37、st=1000;  15.   16. static int _init hello_init(void)  17.   18.   PRINTK("nthe  string_test is : %sn",string_test);  19.   PRINTK("the  num_test is : 

38、;%dn",num_test);  20.   return 0;  21.   22.   23. static void _exit hello_exit(void)  24.   25.   PRINTK(" input paramater module exitn ");  26. 

39、0; 27.   28. module_init(hello_init);  29. module_exit(hello_exit);  30.   31. module_param(num_test,int,S_IRUGO);  32. module_param(string_test,charp,S_IRUGO);  33.   34. MODULE_AUTHOR("dengwei");  35. MO

40、DULE_LICENSE("GPL");  當執(zhí)行 insmod hello_param.ko時,執(zhí)行dmesg 查看內(nèi)核輸出信息:1. Hello World enter  2. the test string is: this is a test  3. the test num is :1000  當執(zhí)行insmod hello_param.ko num_tes

41、t=2000 string_test=“edit by dengwei”,執(zhí)行dmesg查看內(nèi)核輸出信息:1. Hello World enter  2. the test string is: edit by dengwei  3. the test num is :2000  2)導出模塊及符號的相互引用Linux2.6內(nèi)核的“/proc/kallsyms”文件對應內(nèi)核符號表,它記錄了符號以及符號所在的內(nèi)存地址,

42、模塊可以使用下列宏導到內(nèi)核符號表中。EXPORT_SYMBOL(符號名); 任意模塊均可EXPORT_SYMBOL_GPL(符號名); 只使用于包含GPL許可權(quán)的模塊導出的符號可以被其它模塊使用,使用前聲明一下即可。下面給出一個簡單的例子:將add sub符號導出到內(nèi)核符號表中,這樣其它的模塊就可以利用其中的函數(shù)1. #include <linux/module.h>    /*module_init()*/  2. #include <linux/kernel.h> /*

43、0;printk() */  3. #include <linux/init.h>       /* _init _exit */  4.                  5. int add_test(int a ,int&

44、#160;b)                                  6.               &#

45、160;                   7.     return a + b;                     &

46、#160;         8.    9.                                  10. int sub_te

47、st(int a,int b)                                  11.            &

48、#160;                      12.     return a - b;                  

49、;             13.                               14.   15. EXPORT_SYMBOL(add

50、_test);  16. EXPORT_SYMBOL(sub_test);  17.   18. MODULE_AUTHOR("dengwei");  19. MODULE_LICENSE("GPL");  執(zhí)行 cat/proc/kallsyms | grep test 即可找到以下信息,表示模塊確實被加載到內(nèi)核表中。1. f88c9008 r _ksymtab_sub_integar    &

51、#160;   export_symb  2. f88c9020 r _kstrtab_sub_integar         export_symb  3. f88c9018 r _kcrctab_sub_integar         export_symb  4. f88c9010&

52、#160;r _ksymtab_add_integar        export_symb  5. f88c902c r _kstrtab_add_integar          export_symb  6. f88c901c r _kcrctab_add_integar    &#

53、160;    export_symb  7. f88c9000 T add_tes                export_symb  8. f88c9004 T sub_tes           &#

54、160;    export_symb  9. 13db98c9 a _crc_sub_integar           export_symb  10. e1626dee a _crc_add_integar           export_symb&#

55、160; 在其它模塊中可以引用此符號1. #include <linux/module.h>    /*module_init()*/  2. #include <linux/kernel.h> /* printk() */  3. #include <linux/init.h>       /* _init _exit&

56、#160;*/  4.   5. #define DEBUG   /open debug message  6.   7. #ifdef DEBUG  8. #define PRINTK(fmt, arg.)     printk(KERN_WARNING fmt, #arg)  9. #else  

57、;10. #define PRINTK(fmt, arg.)     printk(KERN_DEBUG fmt, #arg)  11. #endif  12.   13. extern int add_test(int a ,int b);   14. extern int sub_test(int a,int b);

58、0;  15.   16. static int _init hello_init(void)  17.   18.     int a,b;  19.     20.   a = add_test(10,20);  21.   b = sub_test(30,20); 

59、; 22.   PRINTK("the add test result is %d",a);  23.   PRINTK("the sub test result is %dn",b);  24.   return 0;  25.   26.   27. static 

60、void _exit hello_exit(void)  28.   29.   PRINTK(" Hello World exitn ");  30.   31.   32. module_init(hello_init);  33. module_exit(hello_exit);  34.   35. MODULE_AUTHOR(&

61、quot;dengwei");  36. MODULE_LICENSE("GPL");  四:linux驅(qū)動基礎開發(fā)3linux 內(nèi)核配置機制(make menuconfig、Kconfig、makefile)講解前面我們介紹模塊編程的時候介紹了驅(qū)動進入內(nèi)核有兩種方式:模塊和直接編譯進內(nèi)核,并介紹了模塊的一種編譯方式在一個獨立的文件夾通過makefile配合內(nèi)核源碼路徑完成。那么如何將驅(qū)動直接編譯進內(nèi)核呢?在我們實際內(nèi)核的移植配置過程中經(jīng)常聽說的內(nèi)核裁剪又是怎么麼回事呢?我們在進行l(wèi)inux內(nèi)核配置的時候經(jīng)常會執(zhí)行make

62、menuconfig這個命令,然后屏幕上會出現(xiàn)以下界面:這個界面是怎么生成的呢?跟我們經(jīng)常說的內(nèi)核配置與與編譯又有什么關(guān)系呢?下面我們借此來講解一下linux內(nèi)核的配置機制及其編譯過程。一、配置系統(tǒng)的基本結(jié)構(gòu)Linux內(nèi)核的配置系統(tǒng)由三個部分組成,分別是:1、Makefile:分布在 Linux 內(nèi)核源代碼根目錄及各層目錄中,定義 Linux 內(nèi)核的編譯規(guī)則;2、配置文件(config.in(2.4內(nèi)核,2.6內(nèi)核):給用戶提供配置選擇的功能;3、配置工具:包括配置命令解釋器(對配置腳本中使用的配置命令進行解釋)和配置用戶界面(提供基于字符界面、基于 Ncurses 圖形界面以及基于 Xwin

63、dows 圖形界面的用戶配置界面,各自對應于 Make config、Make menuconfig 和 make xconfig)。這些配置工具都是使用腳本語言,如 Tcl/TK、Perl 編寫的(也包含一些用 C 編寫的代碼)。本文并不是對配置系統(tǒng)本身進行分析,而是介紹如何使用配置系統(tǒng)。所以,除非是配置系統(tǒng)的維護者,一般的內(nèi)核開發(fā)者無須了解它們的原理,只需要知道如何編寫 Makefile 和配置文件就可以。二、makefile menuconfig過程講解當我們在執(zhí)行make menuconfig這個命令時,系統(tǒng)到底幫我們做了哪些工作呢?這里面一共涉及到了一下幾個文件我們來一一講解Linu

64、x內(nèi)核根目錄下的scripts文件夾arch/$ARCH/Kconfig文件、各層目錄下的Kconfig文件Linux內(nèi)核根目錄下的makefile文件、各層目錄下的makefile文件Linux內(nèi)核根目錄下的的。config文件、arm/$ARCH/下的config文件Linux內(nèi)核根目錄下的 include/generated/autoconf.h文件1)scripts文件夾存放的是跟make menuconfig配置界面的圖形繪制相關(guān)的文件,我們作為使用者無需關(guān)心這個文件夾的內(nèi)容2)當我們執(zhí)行make menuconfig命令出現(xiàn)上述藍色配置界面以前,系統(tǒng)幫我們做了以下工作:首先系統(tǒng)會讀

65、取arch/$ARCH/目錄下的Kconfig文件生成整個配置界面選項(Kconfig是整個linux配置機制的核心),那么ARCH環(huán)境變量的值等于多少呢?它是由linux內(nèi)核根目錄下的makefile文件決定的,在makefile下有此環(huán)境變量的定義:或者通過 make ARCH=arm menuconfig命令來生成配置界面,默認生成的界面是所有參數(shù)都是沒有值的比如教務處進行考試,考試科數(shù)可能有外語、語文、數(shù)學等科,這里相當于我們選擇了arm科可進行考試,系統(tǒng)就會讀取arm/arm/kconfig文件生成配置選項(選擇了arm科的卷子),系統(tǒng)還提供了x86科、milps科等10幾門功課的考試題4) 假設教務處比較“仁慈”,為了怕某些同學做不錯試題,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論