資源描述:
《linux設(shè)備驅(qū)動(dòng)程式》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、Linux設(shè)備驅(qū)動(dòng)程式之讀書筆記第三章字符設(shè)備驅(qū)動(dòng)程式○、說明筆記適用于Linux的2.6.10以后的內(nèi)核。筆記以LinuxDeviceDriver3提供的scull程式(scull目錄中的main.c和scull.h)為記錄主線,并以該驅(qū)動(dòng)程式中的各種系統(tǒng)調(diào)用和函數(shù)調(diào)用流程為記錄順序。比如,module_init()和module_exit()為相對應(yīng)的一對系統(tǒng)調(diào)用,一般書籍中都會(huì)放在一起討論,不過本筆記卻不會(huì)這樣,而是在需要調(diào)用的時(shí)候才會(huì)涉及,因此module_init()會(huì)放在筆記開始時(shí),也就是剛
2、加載module時(shí)討論,而module_exit()則會(huì)放在筆記結(jié)束前,也就是要卸載module時(shí)再加以討論。該筆記的的目的是為了對LinuxDeviceDrvier3中提到的各個(gè)知識點(diǎn)作一下整理,理清一下頭緒,從而能讓我對Linux驅(qū)動(dòng)程式加深整體或全局上的理解。注:個(gè)人理解,有誤難免!*******************************************驅(qū)動(dòng)程式module的工作流程主要分為四個(gè)部分:1、用Linux提供的命令加載驅(qū)動(dòng)module2、驅(qū)動(dòng)module的初始化(初始化結(jié)
3、束后即進(jìn)入“潛伏”狀態(tài),直到有系統(tǒng)調(diào)用)3、當(dāng)操作設(shè)備時(shí),即有系統(tǒng)調(diào)用時(shí),調(diào)用驅(qū)動(dòng)module提供的各個(gè)服務(wù)函數(shù)4、卸載驅(qū)動(dòng)module一、驅(qū)動(dòng)程式的加載Linux驅(qū)動(dòng)程式分為兩種形式:一種是直接編譯進(jìn)內(nèi)核,另一種是編譯成module形式,然后在需要該驅(qū)動(dòng)module時(shí)手動(dòng)加載。對于前者,更有待學(xué)習(xí)。Module形式的驅(qū)動(dòng),Linux提供了兩個(gè)命令用來加載:modprobe和insmod。其中modprobe能解決驅(qū)動(dòng)module的依賴性,即如果正加載的驅(qū)動(dòng)module若引用了其他module提供的內(nèi)核
4、符號或其他資源,則modprobe就會(huì)自動(dòng)加載那些module,不過,使用modprobe時(shí),必須把要加載的驅(qū)動(dòng)module放在當(dāng)前模塊搜索路徑中。而insmod命令不會(huì)考慮驅(qū)動(dòng)module的依賴性,不過他卻能加載任意目錄下的驅(qū)動(dòng)module。一般來說,在驅(qū)動(dòng)研發(fā)階段,使用/sbin/insmod比較方便,因?yàn)椴挥脤odule放入當(dāng)前module搜索路徑中。一旦使用insmod加載模塊,則Linux內(nèi)核就會(huì)調(diào)用module_init(scull_init_module)特別宏,其中scull_init
5、_module是驅(qū)動(dòng)初始化函數(shù),可自定義名稱。在用insmod加載module時(shí),還能給module提供模塊參數(shù),不過這需要在驅(qū)動(dòng)原始碼中加入幾條語句,讓模塊參數(shù)對insmod和驅(qū)動(dòng)程式可見,如:staticchar*whom=”world”;staticinthowmany=10;module_param(howmany,int,S_IRUGO);module_param(whom,charp,S_IRUGO);這樣,當(dāng)使用/sbin/insmodscull.kowhom=”string”howman
6、y=20這樣的命令加載驅(qū)動(dòng)時(shí),whom和howmay的值就會(huì)傳入scull驅(qū)動(dòng)模塊了。驅(qū)動(dòng)程式module被加載后,若對設(shè)備進(jìn)行操作(如open,read,write等),驅(qū)動(dòng)module就會(huì)調(diào)用相應(yīng)的函數(shù)響應(yīng)該操作。那么,當(dāng)對設(shè)備進(jìn)行操作時(shí),驅(qū)動(dòng)module又怎么知道是自己應(yīng)該有所響應(yīng),而不是其他的驅(qū)動(dòng)module呢,也就是說,Linux內(nèi)核怎么知道應(yīng)該調(diào)用哪一個(gè)驅(qū)動(dòng)module呢?目前我只知道有兩種方式將設(shè)備和驅(qū)動(dòng)module聯(lián)系在一起(也許應(yīng)該說提供訪問設(shè)備的一種途徑比較恰當(dāng)):其一是通過某些設(shè)備
7、的ID(比如PCI設(shè)備和USB設(shè)備的DeviceID和ProductID),Linux內(nèi)核根據(jù)這些ID調(diào)用驅(qū)動(dòng)module;其二是在/dev目錄下根據(jù)設(shè)備的主次設(shè)備號創(chuàng)建對應(yīng)的設(shè)備節(jié)點(diǎn)(即設(shè)備文件),這樣當(dāng)操作/dev目錄下的設(shè)備文件時(shí),就會(huì)調(diào)用相應(yīng)的驅(qū)動(dòng)module。一、驅(qū)動(dòng)module的初始化使用insmod加載驅(qū)動(dòng)module時(shí),需要讓驅(qū)動(dòng)module為設(shè)備做一些初始化動(dòng)作,主要目的是讓Linux內(nèi)核知道這個(gè)設(shè)備(或說module?),及在以后對該設(shè)備進(jìn)行操作(如open,read,write等等
8、)時(shí),讓Linux內(nèi)核知道,本module擁有哪些函數(shù)能服務(wù)于系統(tǒng)調(diào)用。因此,scull_init_module函數(shù)中主要做了以下幾件事情:a)分配并注冊主設(shè)備號和次設(shè)備號b)初始化代表設(shè)備的struct結(jié)構(gòu)體:scull_devc)初始化互斥體init_MUTEX(本筆記不整理)d)初始化在內(nèi)核中代表設(shè)備的cdev結(jié)構(gòu)體,最主要是將該設(shè)備和file_operations結(jié)構(gòu)體聯(lián)系起來。1、分配并注冊主次設(shè)備號設(shè)備號是在驅(qū)動(dòng)module中分