• 
    

    
    

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

      ?

      Linux內(nèi)核與用戶空間通信機(jī)制研究

      2012-04-29 13:17:14劉斌朱程榮
      電腦知識(shí)與技術(shù) 2012年16期
      關(guān)鍵詞:驅(qū)動(dòng)程序

      劉斌 朱程榮

      摘要:Linux內(nèi)核采用單內(nèi)核架構(gòu),具有簡(jiǎn)單、高效、安全的優(yōu)點(diǎn)。Linux各子系統(tǒng)包含在內(nèi)核中,而系統(tǒng)配置及管理工具運(yùn)行于用戶空間。開發(fā)人員需要采用一種合適的在內(nèi)核與用戶空間之間通信的方法。該文總結(jié)了幾種常用的通信方法:設(shè)備節(jié)點(diǎn)適合于驅(qū)動(dòng)程序開發(fā),但創(chuàng)建過程比較復(fù)雜;/proc文件易于創(chuàng)建,但是不支持大量數(shù)據(jù)的傳輸;netlink具有高可擴(kuò)展性,越來(lái)越多的系統(tǒng)工具采用這種方式,而其傳輸速度較慢;內(nèi)存映射是傳輸速度最快的方式,使用不當(dāng)時(shí)會(huì)對(duì)系統(tǒng)造成破壞。

      關(guān)鍵詞:Linux;驅(qū)動(dòng)程序;proc文件;netlink;內(nèi)存映射

      中圖分類號(hào):TP316.8文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2012)16-3816-02

      The Research of Communication Mechanism between Linux Kernel and User-space

      LIU Bin, ZHU Cheng-rong

      (Computer Science and Technology Department of Tongji University, Shanghai 201804, China)

      Abstract: The architecture of Linux is designed as monolithic kernel, this makes Linux simple, efficient, secure. Since all Linux subsystems are contained in its kernel, while most system configuration and management tools are running in user-space, developers have to find a proper way to communicate between kernel and user-space. The author introduces several usual mechanisms: device node is used for driv er development, to create a device driver interface is complicated than other methods; /proc file is easy to create and use, but it can not transfer large message; netlink sockets is a highly extensible message mechanism, more and more system tools use this mechanism, even though its transfer speed is low; memory-mapped I/O is fastest, but its misuse will cause system failure.

      Key words: Linux; device driver; proc file; netlink; memory-mapped I/O

      Linux是一個(gè)開源操作系統(tǒng),具有良好的平臺(tái)間可移植性,在嵌入式及服務(wù)器操作系統(tǒng)領(lǐng)域所占的份額越來(lái)越大。Linux內(nèi)核,跟許多其他類Unix系統(tǒng)一樣,采用單內(nèi)核架構(gòu),即內(nèi)核運(yùn)行在一個(gè)獨(dú)立的地址空間中[1]。單內(nèi)核架構(gòu)有以下優(yōu)點(diǎn):

      1)簡(jiǎn)單。單內(nèi)核使得內(nèi)核設(shè)計(jì)較為簡(jiǎn)單,內(nèi)核映像文件更容易存儲(chǔ)。

      2)高效。所有內(nèi)核服務(wù)運(yùn)行于同一個(gè)內(nèi)核空間,其間的通信不需涉及狀態(tài)轉(zhuǎn)換過程,使內(nèi)核保持較高的工作效率。

      3)安全。運(yùn)行于內(nèi)核空間的指令具有特權(quán),內(nèi)核空間獨(dú)立于用戶空間,這使得用戶不能隨意占用系統(tǒng)資源、對(duì)系統(tǒng)修改甚至危害系統(tǒng)的安全,這樣內(nèi)核就具有較高的安全性。

      Linux內(nèi)核子系統(tǒng)運(yùn)行于內(nèi)核空間,而對(duì)其的配置管理卻是通過用戶空間的管理工具來(lái)完成的。Linux內(nèi)核需要提供一定的接口,允許用戶空間進(jìn)程獲取內(nèi)核的資源、信息和服務(wù),甚至配置、監(jiān)控內(nèi)核的運(yùn)行。為了完成與用戶空間的交互,需要內(nèi)核提供一組接口。

      系統(tǒng)調(diào)用是Linux中除異常和陷入外,用戶空間訪問內(nèi)核的唯一合法入口。添加新的系統(tǒng)調(diào)用的過程比較簡(jiǎn)單,但是涉及申請(qǐng)系統(tǒng)調(diào)用號(hào)和重新編譯內(nèi)核等問題,直接在程序中使用新系統(tǒng)調(diào)用會(huì)對(duì)程序的可移植性造成很大的影響。替代方法包括使用設(shè)備節(jié)點(diǎn)、使用/proc文件系統(tǒng)等方式。這些方式都是通過系統(tǒng)已有的系統(tǒng)調(diào)用實(shí)現(xiàn)的。

      該文介紹了幾種用戶空間與內(nèi)核通信機(jī)制的使用方法,并對(duì)其性能及安全性進(jìn)行比較。

      1設(shè)備驅(qū)動(dòng)接口

      設(shè)備節(jié)點(diǎn)位于/dev目錄下。字符設(shè)備驅(qū)動(dòng)和塊設(shè)備驅(qū)動(dòng)接口允許用戶從特定的設(shè)備節(jié)點(diǎn)中讀取以及向其中寫入數(shù)據(jù)。這些接口允許在內(nèi)核與用戶空間之間傳遞數(shù)據(jù),就像訪問文件一樣,并且具有較好的可擴(kuò)展性。但是此類接口通常為內(nèi)核設(shè)備驅(qū)動(dòng)程序保留[2]。因此,Linux內(nèi)核開發(fā)者認(rèn)為新的內(nèi)核子系統(tǒng)使用設(shè)備節(jié)點(diǎn)并不是好的選擇。設(shè)備節(jié)點(diǎn)的復(fù)用也是經(jīng)常遇到的問題。該文以字符設(shè)備驅(qū)動(dòng)為例說(shuō)明數(shù)據(jù)傳遞過程。

      字符設(shè)備驅(qū)動(dòng)函數(shù)地址保存在file_operations結(jié)構(gòu)體中。該結(jié)構(gòu)體包含眾多成員,此處重點(diǎn)關(guān)注字符設(shè)備讀寫處理函數(shù)。讀處理函數(shù)使用copy_from_user從用戶空間復(fù)制數(shù)據(jù),寫處理函數(shù)使用copy_to_user向用戶空間寫入數(shù)據(jù)。在模塊初始化過程中,首先生成設(shè)備號(hào),將設(shè)備號(hào)注冊(cè)到系統(tǒng)中;初始化字符設(shè)備,將驅(qū)動(dòng)程序函數(shù)與字符設(shè)備關(guān)聯(lián);在/dev目錄下建立設(shè)備節(jié)點(diǎn)。在模塊退出函數(shù)中,首先刪除/dev目錄下的設(shè)備節(jié)點(diǎn),然后刪除字符設(shè)備,從系統(tǒng)中注銷其設(shè)備號(hào)。

      內(nèi)核函數(shù)copy_from_uer用于從用戶空間向內(nèi)核空間復(fù)制數(shù)據(jù),執(zhí)行成功返回0,失敗時(shí)返回未被復(fù)制的字節(jié)數(shù)。該函數(shù)可能睡眠,無(wú)法使用在中斷上下文中。在開始復(fù)制數(shù)據(jù)前,該函數(shù)驗(yàn)證用戶空間地址的有效性,檢查所復(fù)制的內(nèi)存區(qū)域是否超出了用戶空間進(jìn)程大小。通過驗(yàn)證之后才進(jìn)行數(shù)據(jù)復(fù)制。如果復(fù)制過程中遇到非法指針,系統(tǒng)調(diào)用頁(yè)異常處理程序進(jìn)行后續(xù)處理。內(nèi)核函數(shù)copy_to_user用于內(nèi)核空間向用戶空間復(fù)制數(shù)據(jù),其實(shí)現(xiàn)過程與copy_from_user相似,不再?gòu)?fù)述。

      用戶空間應(yīng)用程序需要打開創(chuàng)建的設(shè)備節(jié)點(diǎn),獲取其文件描述符,使用標(biāo)準(zhǔn)庫(kù)中的read函數(shù)讀取數(shù)據(jù),使用write函數(shù)寫入數(shù)據(jù)。程序結(jié)束時(shí)關(guān)閉文件。

      2 /proc文件系統(tǒng)

      /proc文件系統(tǒng)最初被用來(lái)顯示進(jìn)程信息。Linux發(fā)行版中的許多工具都通過/proc文件獲取所需信息。為了使用它,用戶空間應(yīng)用程序需要打開/proc文件,然后從內(nèi)核空間讀取信息,或者向其中寫入數(shù)據(jù)。所讀取的消息可以直接顯示在終端上,因此用戶主要通過/proc文件來(lái)獲取或改變系統(tǒng)配置。而從/proc文件中讀取的信息難以被用戶空間應(yīng)用程序使用,因?yàn)檫@需要開發(fā)人員解析消息的格式,并且將其轉(zhuǎn)換成程序內(nèi)部的表示形式[3]。但是/proc文件系統(tǒng)不支持基于事件的信號(hào)機(jī)制,且可擴(kuò)展性較差,數(shù)據(jù)傳輸被限制在一個(gè)內(nèi)存頁(yè)中。

      /proc文件的創(chuàng)建較設(shè)備節(jié)點(diǎn)簡(jiǎn)單許多。在模塊的入口函數(shù)中,創(chuàng)建/proc文件,將/proc文件讀寫處理函數(shù)與其關(guān)聯(lián)。在模塊的退出函數(shù)中,刪除/proc文件。寫處理函數(shù)使用copy_to_user向用戶空間寫入數(shù)據(jù)。用戶空間應(yīng)用程序讀/proc文件時(shí),內(nèi)核將分配一頁(yè)內(nèi)存,內(nèi)核模塊可以通過該內(nèi)存頁(yè)將數(shù)據(jù)傳遞至內(nèi)存空間。系統(tǒng)將該內(nèi)存頁(yè)首地址以參數(shù)形式傳遞至讀處理函數(shù)。讀處理函數(shù)可以直接對(duì)此內(nèi)存進(jìn)行操作,以完成數(shù)據(jù)傳遞,而傳遞的數(shù)據(jù)不能超過一頁(yè)內(nèi)存的大小[2]。

      用戶空間應(yīng)用程序?qū)?proc文件的使用過程與設(shè)備節(jié)點(diǎn)相似。

      3 netlink套接字

      Netlink是一種面向數(shù)據(jù)報(bào)的消息系統(tǒng),允許在內(nèi)核與用戶空間之間雙向傳遞消息。它也可以用來(lái)在多個(gè)用戶態(tài)進(jìn)程之間傳遞消息,完成IPC任務(wù)。Netlink消息具有較強(qiáng)的擴(kuò)展能力,用戶可以自定義消息的格式。并且netlink提供了基于事件的信號(hào)機(jī)制,允許大數(shù)據(jù)的傳輸,克服了上述Linux內(nèi)核接口的缺點(diǎn)[3]。Netlink支持單播和多播兩種通信方式。單播適合內(nèi)核子系統(tǒng)與一個(gè)用戶空間進(jìn)程之間通信,主要用于用戶空間進(jìn)程向內(nèi)核空間發(fā)送指令,接收指令執(zhí)行的結(jié)果,從內(nèi)核中獲取信息。多播適合內(nèi)核子系統(tǒng)與多個(gè)用戶空間進(jìn)程通信,可以借此實(shí)現(xiàn)基于事件的信號(hào)機(jī)制。該文主要討論單播通信。

      Netlink接口在不同版本Linux內(nèi)核中有較大變化。在2.6.38內(nèi)核中,創(chuàng)建內(nèi)核netlink套接字需要指定網(wǎng)絡(luò)名字空間、netlink協(xié)議類型、netlink消息處理函數(shù)、模塊互斥量和模塊屬主等六個(gè)參數(shù)。在模塊的退出函數(shù)中,釋放netlink套接字。發(fā)送netlink消息的過程如下:先向系統(tǒng)申請(qǐng)一個(gè)skb,其大小可由消息內(nèi)容的大小確定;初始化skb中的netlink協(xié)議頭部,將消息內(nèi)容復(fù)制到skb中;調(diào)用netlink_unicast將上述skb通過netlink套接字發(fā)送到指定的用戶空間進(jìn)程。創(chuàng)建netlink套接字時(shí)指定的消息處理函數(shù),用于接收用戶空間發(fā)來(lái)的netlink消息,內(nèi)核可以直接操作保存消息的skb。

      用戶空間應(yīng)用程序先創(chuàng)建指定類型的netlink socket,將其與特定地址綁定;然后分配netlink消息,組裝消息內(nèi)容,將其通過套接字函數(shù)sendto發(fā)送至內(nèi)核;接收消息通過套接字函數(shù)recvfrom完成。程序結(jié)束時(shí)釋放netlink消息,關(guān)閉套接字。

      4內(nèi)存映射

      內(nèi)存映射I/O將一個(gè)文件映射到一段內(nèi)存空間。對(duì)這段內(nèi)存空間的讀寫相當(dāng)于對(duì)文件的讀寫,而不需要通過調(diào)用read和write[4]。/dev/mem是一個(gè)特殊的字符設(shè)備文件,其內(nèi)容是系統(tǒng)內(nèi)存的映像,即文件中的字節(jié)地址可以被解釋為物理內(nèi)存地址。mem可以被用來(lái)檢查和修改系統(tǒng)。開發(fā)人員通過/dev/mem,可以將內(nèi)核內(nèi)存空間映射到用戶地址空間,然后對(duì)映射后的內(nèi)存區(qū)域進(jìn)行相關(guān)操作。但是引用不存在于內(nèi)存中的內(nèi)核地址將導(dǎo)致錯(cuò)誤,檢查或修改系統(tǒng)中的只讀或只寫位可能導(dǎo)致未知錯(cuò)誤。

      為了不使內(nèi)核遭受災(zāi)難性的破壞,最好對(duì)內(nèi)核中的空閑內(nèi)存頁(yè)進(jìn)行映射操作。在內(nèi)核模塊入口函數(shù)中,申請(qǐng)空閑的內(nèi)核內(nèi)存頁(yè),將頁(yè)首虛擬地址轉(zhuǎn)換成物理地址;然后將物理地址及內(nèi)存頁(yè)大小通過/proc文件(也可通過其他方式)傳遞至用戶空間。在模塊退出函數(shù)中,釋放申請(qǐng)的內(nèi)存頁(yè)。在X86平臺(tái)上使用/dev/mem和mmap,編譯內(nèi)核時(shí)需要關(guān)閉兩個(gè)選項(xiàng):CONFIG_X86_PAT和CON? FIG_STRICT_DEVMEM。

      用戶空間應(yīng)用程序先獲得內(nèi)核內(nèi)存頁(yè)的物理地址及大小,然后打開/dev/mem,通過mmap建立映射關(guān)系,獲取映射到用戶空間后的內(nèi)存地址。程序?qū)@塊內(nèi)存進(jìn)行讀寫,等同于對(duì)內(nèi)核對(duì)應(yīng)內(nèi)存進(jìn)行讀寫。程序結(jié)束需要解除映射,關(guān)閉打開的/dev/mem。

      5性能測(cè)試

      使用前述方法,分別建立內(nèi)核模塊及應(yīng)用程序,在實(shí)際平臺(tái)上對(duì)這些通信機(jī)制進(jìn)行性能測(cè)試。測(cè)試平臺(tái)的配置如表1所示。測(cè)試方法為:每次傳輸1K字節(jié),測(cè)試不同方法傳輸1G字節(jié)消息所耗費(fèi)的時(shí)間。測(cè)試結(jié)果如表2所示。

      6結(jié)論

      設(shè)備節(jié)點(diǎn)的傳輸速度較快,傳遞消息的大小由內(nèi)核緩沖區(qū)大小決定。該接口主要供設(shè)備驅(qū)動(dòng)程序使用,且創(chuàng)建的過程比較復(fù)雜。

      /proc文件創(chuàng)建和使用都比較簡(jiǎn)單。在讀/proc文件的過程中沒有使用copy_from_user,系統(tǒng)需要分配單獨(dú)的緩存頁(yè),因此其消耗的時(shí)間大于寫/proc文件。/proc機(jī)制每次向用戶空間傳遞的消息不能大于一個(gè)內(nèi)存頁(yè)。

      Netlink具有較高的擴(kuò)展性,支持用戶自定義消息格式,消息大小受內(nèi)核可用skb大小限制。由于netlink是基于BSD socket實(shí)現(xiàn)的,其通信過程是上述方法中最耗時(shí)的。內(nèi)核發(fā)送消息時(shí)需要分配skb,因此內(nèi)核至用戶空間的傳輸時(shí)間大于相反方向的傳輸。

      內(nèi)存映射的傳輸速度最高。但是需要其他通信方式的支持,并且這種方式的危險(xiǎn)性較高,使用不當(dāng)時(shí)容易對(duì)系統(tǒng)造成破壞。

      參考文獻(xiàn):

      [1] Robert L. Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)[M].2版.陳莉君,康華,等,譯.北京:機(jī)械工業(yè)出版社,2006.

      [2] Corbet J, Rubini A, Kroah-Hartma G.Linux設(shè)備驅(qū)動(dòng)程序[M].3版.魏永明,耿岳,鐘書毅,譯.北京:中國(guó)電力出版社,2006.

      [3] Campbell J,Comer D.Software:Practice and Experience[M].John Wiley & Sons,1991.

      [4] Stevens W R,Rago S A. UNIX環(huán)境高級(jí)編程[M].2版.尤晉元,等,譯.北京:人民郵電出版社,2009.

      猜你喜歡
      驅(qū)動(dòng)程序
      計(jì)算機(jī)硬件設(shè)備驅(qū)動(dòng)程序分析
      電子制作(2018年17期)2018-09-28 01:56:58
      驅(qū)動(dòng)程序更新與推薦
      驅(qū)動(dòng)程序更新與推薦
      如何為老顯卡安裝Windows7驅(qū)動(dòng)程序? 等
      驅(qū)動(dòng)程序更新與推薦
      驅(qū)動(dòng)程序的真心話和大冒險(xiǎn)
      时尚| 安吉县| 大冶市| 临澧县| 临清市| 广昌县| 吴忠市| 当雄县| 巴东县| 诸暨市| 芒康县| 长沙县| 庄河市| 孝昌县| 奉贤区| 万源市| 永年县| 东宁县| 涞源县| 湖北省| 陆川县| 滦平县| 星座| 台前县| 耿马| 蕲春县| 临高县| 历史| 阿拉善盟| 嘉禾县| 运城市| 富平县| 慈溪市| 湘西| 仪征市| 洪泽县| 拉孜县| 长岛县| 二连浩特市| 合山市| 平顶山市|