• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      基于Linux的字符設(shè)備驅(qū)動程序的開發(fā)

      2012-10-17 03:07:06李蘭蘭
      關(guān)鍵詞:網(wǎng)絡(luò)設(shè)備驅(qū)動程序內(nèi)核

      李蘭蘭

      南京航空航天大學金城學院 江蘇省 211156

      0 引言

      任何一個計算機系統(tǒng)都是由計算機硬件子系統(tǒng)和計算機軟件子系統(tǒng)組成的,缺一不可,他們共同協(xié)作完成各種任務,但同時他們又具有一定的獨立性。硬件工程師往往不必關(guān)心軟件,而應用軟件工程師也不會過多關(guān)注硬件。應用軟件工程師需要看到一個沒有硬件的純粹的軟件世界,硬件對他們來說是透明的。而設(shè)備驅(qū)動程序就能達到這個目的,實現(xiàn)硬件對應用軟件工程師的隱形。

      1 設(shè)備分類

      Linux系統(tǒng)下,設(shè)備可以分成三種基本類型:字符設(shè)備、塊設(shè)備和網(wǎng)絡(luò)設(shè)備。對于字符設(shè)備而言,往往是以字節(jié)流的形式進行訪問的設(shè)備,如鼠標、觸摸屏等,其對應的驅(qū)動類型是字符設(shè)備驅(qū)動程序。塊設(shè)備可以以任意順序進行訪問,以塊為單位進行操作,如硬盤,其驅(qū)動通過塊設(shè)備驅(qū)動程序來實現(xiàn)。Linux系統(tǒng)中,應用程序可以像操作字符設(shè)備一樣的讀寫塊設(shè)備,但內(nèi)核為字符設(shè)備驅(qū)動和塊設(shè)備驅(qū)動提供了完全不同的接口。在Linux系統(tǒng)中,網(wǎng)絡(luò)設(shè)備處理的事務一般面向數(shù)據(jù)的接收和發(fā)送,不像字符設(shè)備和塊設(shè)備一樣對應于文件系統(tǒng)的節(jié)點,其對應的驅(qū)動為網(wǎng)絡(luò)設(shè)備驅(qū)動程序。內(nèi)核和網(wǎng)絡(luò)設(shè)備驅(qū)動程序間的通信,完全不同于和字符及塊設(shè)備驅(qū)動程序之間的通信,內(nèi)核為網(wǎng)絡(luò)設(shè)備驅(qū)動程序提供了一套和數(shù)據(jù)包傳輸相關(guān)的函數(shù)。

      這種分類方法并不是非常嚴格的,對于某些復雜的設(shè)備,Linux系統(tǒng)還定義了其他的驅(qū)動體系結(jié)構(gòu)。

      2 字符設(shè)備驅(qū)動程序的開發(fā)

      2.1 模塊的裝載和卸載

      Linux內(nèi)核非常龐大,包含的組件也非常多。這些組件成為內(nèi)核的一部分通??梢酝ㄟ^兩種途徑,一種是編譯時直接成為Linux內(nèi)核的組件,另一種是編譯時不進入內(nèi)核,但可以在需要時通過加載的方式成為內(nèi)核的一部分,當不再需要該模塊時,通過卸載的方式從內(nèi)核中移除。Linux中編寫的設(shè)備驅(qū)動程序就可以通過后面這種模塊化的方式進入到內(nèi)核中。這種模塊化驅(qū)動程序編程方式是Linux系統(tǒng)的一個很好的特色,有助于縮短模塊的開發(fā)周期,不需要每次都經(jīng)過冗長的關(guān)機/重啟過程。

      加載模塊時可以使用insmod或modprobe命令將模塊加載到正在運行的內(nèi)核中,通過rmmod程序把模塊從內(nèi)核中移除。當通過insmod或modprobe命令加載驅(qū)動模塊時,模塊的加載函數(shù)會自動被內(nèi)核執(zhí)行,完成模塊的初始化工作,對字符設(shè)備驅(qū)動程序來說,一般會在加載函數(shù)完成字符設(shè)備的注冊。當通過rmmod命令卸載驅(qū)動模塊時,內(nèi)核會自動運行模塊的卸載函數(shù),對字符設(shè)備驅(qū)動程序來說,一般在卸載函數(shù)對字符設(shè)備進行注銷。

      模塊的加載函數(shù)以“module_init(函數(shù)名)”的形式被指定,若初始化成功,應返回 0,而在初始化失敗時,應返回一個負值。模塊的卸載函數(shù)則以“module_exit(函數(shù)名)”形式指定,但卸載函數(shù)不返回任何值。

      2.2 分配和釋放設(shè)備號

      Linux內(nèi)核中使用cdev結(jié)構(gòu)體描述字符設(shè)備,其中cdev結(jié)構(gòu)體的dev_t成員定義了32位的設(shè)備號,其中高12位用來表示主設(shè)備號,低 20位為次設(shè)備號??梢酝ㄟ^使用宏MAJOR(dev_t dev)和 MINOR(dev_t dev)來分別獲取主設(shè)備號和次設(shè)備號,而宏MKDEV(int major, int minor)則通過主設(shè)備號和次設(shè)備號來生成dev_t。通常,用主設(shè)備號來標識設(shè)備對應的驅(qū)動程序。

      驅(qū)動程序在建立一個字符設(shè)備之前,首先要做的事情就是獲得一個或者多個設(shè)備號。該過程可以通過以下函數(shù)實現(xiàn)。

      register_chrdev_region()函數(shù)用于已知設(shè)備的設(shè)備號的情況;而alloc_chrdev_region()用于設(shè)備號未知,內(nèi)核為設(shè)備動態(tài)分配所需要的設(shè)備號,函數(shù)調(diào)用成功時,得到的設(shè)備號會放入第一個參數(shù)dev中。動態(tài)分配設(shè)備號的函數(shù)有個很大的優(yōu)點,即能避免設(shè)備號沖突的發(fā)生。

      在模塊卸載函數(shù)中,在對字符設(shè)備注銷后,調(diào)用unregister_chrdev_region()函數(shù)釋放開始分配的設(shè)備號。該函數(shù)原型為:

      2.3 設(shè)備的注冊和注銷

      在申請完設(shè)備號之后,需要對字符設(shè)備進行注冊,而字符設(shè)備是用結(jié)構(gòu)體cdev來表示的,cdev結(jié)構(gòu)體的定義如下:

      在對字符設(shè)備進行注冊時,先為字符設(shè)備分配 cdev結(jié)構(gòu),一般調(diào)用如下函數(shù):

      cdev_alloc函數(shù)會向系統(tǒng)動態(tài)申請一個cdev結(jié)構(gòu),接下來把該cdev結(jié)構(gòu)嵌入到自己的設(shè)備特定結(jié)構(gòu)中去,初始化已分配到的結(jié)構(gòu):

      接下來對cdev結(jié)構(gòu)體中的某些字段進行初始化:

      在設(shè)置好cdev結(jié)構(gòu)體后,通過下面的函數(shù)調(diào)用把該結(jié)構(gòu)告訴內(nèi)核:

      參數(shù)dev為已設(shè)置好的cdev結(jié)構(gòu)體,num為該設(shè)備對應的第一個設(shè)備號,count應該為和該設(shè)備關(guān)聯(lián)的設(shè)備號的數(shù)量,count的值常常會被設(shè)置成1。 cdev_add函數(shù)如果返回一個負的錯誤碼,則設(shè)備不會被添加到系統(tǒng)中去,只有當成功返回時,該字符設(shè)備才真正被添加到內(nèi)核中去,它的操作也才能被內(nèi)核調(diào)用。

      當需要從系統(tǒng)中刪除一個字符設(shè)備,則需調(diào)用cdev_del函數(shù),該函數(shù)原型如下:

      一旦調(diào)用了該函數(shù),會刪除cdev結(jié)構(gòu),注銷字符設(shè)備,此時就不能再訪問cdev結(jié)構(gòu)。

      2.4 file_operations結(jié)構(gòu)體

      file_operations結(jié)構(gòu)體中的成員函數(shù)是字符設(shè)備驅(qū)動程序設(shè)計的主體內(nèi)容,這些函數(shù)會在應用程序進行 open()、write()、read()、close()等系統(tǒng)調(diào)用時最終被調(diào)用。File_operations結(jié)構(gòu)體比較龐大,其中比較主要的成員如下:

      該成員指向擁有該結(jié)構(gòu)體的模塊的指針,該字段可以避免內(nèi)核正在操作該模塊時卸載該模塊。大多情形下,該成員都會被初始化為THIS_MODULE。

      用來從設(shè)備讀取數(shù)據(jù)。函數(shù)返回非負值表示成功讀取的字節(jié)數(shù),出錯時返回一個負值。

      用來向設(shè)備發(fā)送數(shù)據(jù)。函數(shù)返回的非負值表示成功寫入的字節(jié)數(shù),

      用來修改文件當前讀寫位置,并將新位置作為返回值返回,在出錯時,該函數(shù)返回一個負值。

      用來提供一種執(zhí)行設(shè)備特定命令的方法。當調(diào)用成功時,返回給調(diào)用程序一個非負值。內(nèi)核本身常常會提供一些操作設(shè)備的命令,而不需要調(diào)用設(shè)備驅(qū)動中的ioctl函數(shù)。如果設(shè)備不提供ioctl函數(shù),則對于任何內(nèi)核未預先定義的請求,ioctl系統(tǒng)調(diào)用將返回一個負的錯誤碼。

      字符設(shè)備驅(qū)動中需要對file_operations結(jié)構(gòu)進行初始化,如下:

      其中read和write函數(shù)分別進行拷貝數(shù)據(jù)到應用程序空間和從應用程序空間拷貝數(shù)據(jù)的操作,ssize_t (*read) (struct file *filp, char __user*buff, size_t count, loff_t *offp);

      對于這兩個函數(shù),參數(shù)filp是文件指針;參數(shù)count是請求傳輸?shù)臄?shù)據(jù)長度;參數(shù)buff指向用戶空間緩沖區(qū),這個緩沖區(qū)或者保存要寫入的數(shù)據(jù),或者是一個存放新讀入數(shù)據(jù)的空緩沖區(qū);參數(shù)offp指明用戶在文件中進行存取操作的位置。對于表示用戶空間的指針的buff參數(shù),內(nèi)核代碼不能直接引用其中的內(nèi)容,而驅(qū)動程序又必須訪問用戶空間的緩沖區(qū)以便完成自己的工作,這種訪問應始終通過內(nèi)核提供的專用函數(shù)完成。Read函數(shù)的任務是從設(shè)備拷貝數(shù)據(jù)到用戶空間,通過使用copy_to_user函數(shù)來實現(xiàn);write函數(shù)的任務則是從用戶空間拷貝數(shù)據(jù)到設(shè)備上,這可通過使用copy_from_user函數(shù)來實現(xiàn)。實現(xiàn)內(nèi)核空間和用戶空間之間拷貝數(shù)據(jù)的這兩個函數(shù)的原型是:

      2.5 用戶空間程序

      對編寫好的字符設(shè)備驅(qū)動程序進行編譯,將會得到mydev.ko文件,通過命令”insmod mydev.ko”加載驅(qū)動模塊,運行”lsmod”命令,發(fā)現(xiàn) mydev模塊已被加載。當執(zhí)行”cat/proc/devices”命令,發(fā)現(xiàn)多出了主設(shè)備號為***的“mydev“字符設(shè)備驅(qū)動。

      接下來通過命令“mknod /dev/mydev c *** 0“創(chuàng)建”/dev/mydev”設(shè)備節(jié)點,最后進行驗證。通過命令“echo “Is the driver OK” > /dev/mydev”和 命令“cat /dev/mydev”分別驗證設(shè)備的寫和讀,結(jié)果證明字符“Is the driver OK”被成功寫入到mydev字符設(shè)備中去。

      3 結(jié)束語

      本文介紹的字符設(shè)備驅(qū)動程序的設(shè)計是針對Linux內(nèi)核2.6而言的,相比較塊設(shè)備和網(wǎng)絡(luò)設(shè)備驅(qū)動程序而言,字符設(shè)備驅(qū)動程序還是相對較簡單的一類驅(qū)動程序。對于實際的物理設(shè)備,當把該設(shè)備注冊為字符設(shè)備時,除了實現(xiàn)字符設(shè)備驅(qū)動的部分,往往還需根據(jù)設(shè)備本身的特點,實現(xiàn)設(shè)備功能相關(guān)的代碼。

      [1]Cobet,Rubini,Kroah-Hartman. Linux設(shè)備驅(qū)動程序.第三版.魏永明等譯.北京:中國電力出版社.2005.

      [2]宋寶華編著.Linux設(shè)備驅(qū)動開發(fā)詳解.北京:人民郵電出版社.2008.

      [3] NeilMatthew RichardStones著.Linux程序設(shè)計[M].楊曉云,楊濤譯等譯.北京:機械工業(yè)出版社.2002.

      [4]Mait Weish,Matthias Kalle Dalheimer,Lar Kaufman著.Linux權(quán)威指南(第3版)[M].北京:中國電力出版社.2000.

      猜你喜歡
      網(wǎng)絡(luò)設(shè)備驅(qū)動程序內(nèi)核
      萬物皆可IP的時代,我們當夯實的IP內(nèi)核是什么?
      強化『高新』內(nèi)核 打造農(nóng)業(yè)『硅谷』
      一種基于C# 的網(wǎng)絡(luò)設(shè)備自動化登錄工具的研制
      基于嵌入式Linux內(nèi)核的自恢復設(shè)計
      Linux內(nèi)核mmap保護機制研究
      數(shù)據(jù)中心唯“快”不破
      基于列車監(jiān)測網(wǎng)絡(luò)設(shè)備的射頻功放模塊設(shè)計
      基于三層交換技術(shù)架構(gòu)數(shù)字化校園網(wǎng)絡(luò)設(shè)備的配置與管理
      驅(qū)動程序更新與推薦
      驅(qū)動程序更新與推薦
      汤阴县| 临湘市| 亚东县| 水城县| 南澳县| 剑河县| 新乡市| 韶关市| 龙里县| 泗洪县| 陵川县| 偃师市| 秦皇岛市| 新宁县| 南城县| 阜平县| 遂溪县| 阿巴嘎旗| 福州市| 西藏| 台江县| 康保县| 溧水县| 淅川县| 阳城县| 阜康市| 中方县| 利川市| 南充市| 鹤山市| 明光市| 松溪县| 忻州市| 清徐县| 石首市| 瑞金市| 钟祥市| 通州市| 乾安县| 柘荣县| 沂南县|