一種嵌入式Linux下用戶態(tài)驅(qū)動程序的實現(xiàn)方法
【專利摘要】本發(fā)明涉及一種嵌入式Linux下用戶態(tài)驅(qū)動程序的實現(xiàn)方法,屬于嵌入式操作系統(tǒng)【技術(shù)領(lǐng)域】。本發(fā)明具體步驟為將傳統(tǒng)的內(nèi)核態(tài)驅(qū)動程序依據(jù)性能相關(guān)與否以及優(yōu)先級,分離為運行于內(nèi)核態(tài)的k-driver和運行于用戶態(tài)的u-driver兩個組件;在內(nèi)核態(tài)建立動態(tài)可加載內(nèi)核模塊k-mod;在用戶態(tài)建立動態(tài)鏈接庫u-lib。本發(fā)明用戶態(tài)編程工具,允許程序員在編寫驅(qū)動程序時使用通用成熟的編程工具如代碼調(diào)試器,提高了編碼質(zhì)量;較好的性能,相比與傳統(tǒng)的內(nèi)核態(tài)設(shè)備驅(qū)動程序有著相似的性能,例如相似的吞吐量、延遲和CPU開銷;故障隔離,用戶層組件發(fā)生的故障不會影響到內(nèi)核,即不會影響到整個系統(tǒng)的安全運行;兼容性,與現(xiàn)有的嵌入式Linux系統(tǒng)兼容,提供一樣的接口。
【專利說明】—種嵌入式Linux下用戶態(tài)驅(qū)動程序的實現(xiàn)方法
【技術(shù)領(lǐng)域】
[0001]本發(fā)明涉及一種嵌入式Linux下用戶態(tài)驅(qū)動程序的實現(xiàn)方法,尤其是嵌入式Linux系統(tǒng)下的驅(qū)動程序的加固,具體地說是在保證性能以及與現(xiàn)有系統(tǒng)兼容的前提下在嵌入式Linux系統(tǒng)中實現(xiàn)用戶態(tài)驅(qū)動程序的方法,屬于嵌入式操作系統(tǒng)【技術(shù)領(lǐng)域】。
【背景技術(shù)】
[0002]隨著計算機技術(shù)與通信技術(shù)的迅猛發(fā)展,嵌入式系統(tǒng)已經(jīng)滲透到人們生活的各個方面,在工業(yè)控制、航天軍工、醫(yī)療衛(wèi)生、消費電子等領(lǐng)域,嵌入式系統(tǒng)都有著廣泛的應(yīng)用。而在各大嵌入式操作系統(tǒng)中,Linux以其開放源代碼、較好的網(wǎng)絡(luò)性能、精簡高效的內(nèi)核、較高的可定制性、支持多種體系結(jié)構(gòu)等特性,廣泛地應(yīng)用于嵌入式領(lǐng)域。
[0003]在嵌入式領(lǐng)域,可靠性被提高到了最重要的位置。而操作系統(tǒng)中,驅(qū)動程序是影響系統(tǒng)可靠性的最大隱患。來自微軟公司的報告顯示,89%導(dǎo)致windows XP系統(tǒng)崩潰的源頭來自驅(qū)動程序。一項針對Linux內(nèi)核的研究也顯示驅(qū)動程序出現(xiàn)BUG的幾率比內(nèi)核中其它部分的代碼高出2-7倍。
[0004]在嵌入式Linux系統(tǒng)中,為了兼顧性能和I/O指令的特權(quán)操作要求,傳統(tǒng)的驅(qū)動程序是運行在內(nèi)核態(tài),擁有內(nèi)核的所有權(quán)限,一旦驅(qū)動程序出現(xiàn)BUG,將會導(dǎo)致整個系統(tǒng)崩潰。在提高系統(tǒng)可靠性方面,目前已有的研究,都專注于通過把有錯誤的設(shè)備驅(qū)動程序與內(nèi)核隔離。然而,這些研究都忽略了驅(qū)動程序可靠性問題中最重要的一個方面:在內(nèi)核態(tài)編程要比在用戶態(tài)編程要困難得多,由于難以調(diào)試,因此也更容易出現(xiàn)未知的bug,導(dǎo)致系統(tǒng)可靠性下降。將驅(qū)動程序移出內(nèi)核被認(rèn)為是這一問題很好的解決方案之一。
[0005]目前已有的用戶態(tài)驅(qū)動解決方案,主要存在兩個問題。第一,由于現(xiàn)有的驅(qū)動/內(nèi)核接口的限制,用戶態(tài)驅(qū)動程序執(zhí)行時需要頻繁地在用戶態(tài)以及內(nèi)核態(tài)切換并移動大量數(shù)據(jù),這導(dǎo)致了明顯的性能低下,難以滿足實際系統(tǒng)的需求。第二,要實現(xiàn)用戶態(tài)驅(qū)動程序的高性能,就需要完全重寫現(xiàn)有的驅(qū)動程序,這就導(dǎo)致每一個這樣的系統(tǒng)中的驅(qū)動程序都是單獨實現(xiàn),無法實現(xiàn)通用,更無法與現(xiàn)有的系統(tǒng)相兼容。
【發(fā)明內(nèi)容】
[0006]本發(fā)明要解決的技術(shù)問題是提供一種在嵌入式Linux系統(tǒng)中實現(xiàn)用戶態(tài)驅(qū)動程序的方法,用以解決現(xiàn)有用戶態(tài)驅(qū)動解決方案中存在的性能低下以及與現(xiàn)有系統(tǒng)的兼容性問題。
[0007]本發(fā)明的技術(shù)方案是:
一種嵌入式Linux下用戶態(tài)驅(qū)動程序的實現(xiàn)方法:
首先,分離傳統(tǒng)的內(nèi)核態(tài)驅(qū)動程序。將傳統(tǒng)的內(nèi)核態(tài)驅(qū)動程序依據(jù)性能相關(guān)與否以及優(yōu)先級,分離為運行于內(nèi)核態(tài)的k-driver和運行于用戶態(tài)的u-driver兩個部分。
[0008]所述的k-driver,包括性能相關(guān)的熱點代碼和數(shù)據(jù)通道,例如輸入/輸出、中斷處理函數(shù)、一些高優(yōu)先級函數(shù)(軟中斷、tasklet和工作隊列)等。k-driver以Linux的可加載動態(tài)模塊(Loadable Kernel Module )的方式運行于內(nèi)核態(tài),以保證高性能。
[0009]所述的u-driver,包括驅(qū)動程序中一些與性能無關(guān)的非關(guān)鍵操作以及一些優(yōu)先級較低的代碼,例如設(shè)備初始化、設(shè)備配置、設(shè)備控制、錯誤處理等。u-driver以一個普通進(jìn)程的形式運行于用戶態(tài),以保證充分的故障隔離。
[0010]所述的U-driver,通過對/dev/mem的訪問,使用mmap ()系統(tǒng)調(diào)用將設(shè)備寄存器或端口映射到用戶空間。這樣,u-driver就可以在用戶態(tài)直接訪問硬件的寄存器或輸入輸出端口。
[0011]其次,當(dāng)一個傳統(tǒng)的內(nèi)核態(tài)驅(qū)動程序被轉(zhuǎn)換為一個k-driver和一個u-driver,這兩個組件需要通信和共享數(shù)據(jù)。提供這一服務(wù)的是運行于內(nèi)核態(tài)的k-mod以及運行于用戶態(tài)的u-lib。
[0012]所述的k-mod,注冊為一個設(shè)備驅(qū)動程序并實現(xiàn)了字符設(shè)備接口用來與u-lib通信。它實現(xiàn)的功能包括與u-driver進(jìn)行通信、追蹤k-driver與u-driver間共享的數(shù)據(jù)結(jié)構(gòu)等。
[0013]所述的u-lib,被實現(xiàn)為一個鏈接到u-driver的多線程庫,它面向u-driver的接口與k-mod面向內(nèi)核的接口類似。它實現(xiàn)的功能包括請求k-driver提供服務(wù)、執(zhí)行來自k-mod的函數(shù)調(diào)用請求等。
[0014]所述的k-mod和u-lib共同提供了 k-driver和u-driver之間的通信,使得k-driver可以調(diào)用u-driver中的函數(shù),u-driver同樣能夠調(diào)用k-driver中的函數(shù)。它們還跟蹤k-driver和u-driver兩個模塊的共享變量或全局?jǐn)?shù)據(jù),任何一方對數(shù)據(jù)的改變都要通知另一方,保證兩者數(shù)據(jù)的同步。
[0015]當(dāng)系統(tǒng)啟動時,系統(tǒng)加載k-driver和k_mod模塊,隨后啟動用戶態(tài)的u-driver和u-lib, u-lib中的一個主要線程通過ioctl ()系統(tǒng)調(diào)用將u-driver注冊到k_mod。u-lib調(diào)用k-mod模塊的ioctl,等待請求,當(dāng)k-driver向上調(diào)用時,ioctl返回并把請求傳送給用戶層。這樣,k-driver和u-driver通過k-mod以及u_lib的配合,即可實現(xiàn)傳統(tǒng)內(nèi)核態(tài)驅(qū)動程序的功能。
[0016]本發(fā)明的有益效果是:
(1)用戶態(tài)編程工具,允許程序員在編寫驅(qū)動程序時使用通用成熟的編程工具如代碼調(diào)試器,提高了編碼質(zhì)量;
(2)較好的性能,相比與傳統(tǒng)的內(nèi)核態(tài)設(shè)備驅(qū)動程序有著相似的性能,例如相似的吞吐量、延遲和CPU開銷;
(3)故障隔離,用戶層組件發(fā)生的故障不會影響到內(nèi)核,即不會影響到整個系統(tǒng)的安全運行;
(4)兼容性,與現(xiàn)有的嵌入式Linux系統(tǒng)兼容,提供一樣的接口。
【專利附圖】
【附圖說明】
[0017]圖1為本發(fā)明提供的一種用戶態(tài)驅(qū)動程序的實現(xiàn)方法的框架結(jié)構(gòu)圖;
圖2為本發(fā)明提供的一種用戶態(tài)驅(qū)動程序的實現(xiàn)方法的執(zhí)行流程圖;
圖3為本發(fā)明實施例中所述用戶態(tài)驅(qū)動程序的通信流程圖;
圖4為本發(fā)明實施例中所述用戶態(tài)驅(qū)動程序的數(shù)據(jù)拷貝流程圖?!揪唧w實施方式】
[0018]下面結(jié)合附圖和【具體實施方式】,對本發(fā)明作進(jìn)一步說明。這里以在DM9000網(wǎng)卡上實現(xiàn)本發(fā)明所述的用戶態(tài)驅(qū)動程序作為實施例,來具體說明本發(fā)明的實現(xiàn)方法。所描述的實施例僅僅是本發(fā)明的一部分實施例,而不是全部的實施例。
[0019]實施例1:首先,按照
【發(fā)明內(nèi)容】
中所描述的驅(qū)動架構(gòu),將DM9000網(wǎng)卡內(nèi)核態(tài)驅(qū)動程序分離為兩個部分:k-driver和u-driver。如圖1所示,圖1為本發(fā)明提供的一種用戶態(tài)驅(qū)動程序的實現(xiàn)方法的框架結(jié)構(gòu)圖,其中實線是性能攸關(guān)代碼路徑,虛線是性能無關(guān)代碼路徑。k-driver以Linux的可加載動態(tài)模塊(Loadable Kernel Module )的方式實現(xiàn),包括了 DM9000網(wǎng)卡驅(qū)動中的數(shù)據(jù)處理核心功能代碼,如接受數(shù)據(jù)包、數(shù)據(jù)包拷貝、中斷處理等。u-driver以普通用戶態(tài)程序的方式實現(xiàn),包括了 DM9000網(wǎng)卡驅(qū)動中的一些非熱點代碼,如設(shè)備初始化、設(shè)備配置、錯誤處理等,這部分代碼可以安全地從內(nèi)核態(tài)移出,并且對性能影響甚微。
[0020]其次,確定DM9000網(wǎng)卡用戶態(tài)驅(qū)動的I/O訪問方式。需要在用戶態(tài)的u-driver能夠直接訪問DM9000的寄存器或I/O端口。在傳統(tǒng)的X86架構(gòu)處理器平臺,存在著兩個相關(guān)的系統(tǒng)調(diào)用:iopl()和iopermO,通過這兩個系統(tǒng)調(diào)用即可允許調(diào)用進(jìn)程獲得訪問設(shè)備對應(yīng)的I/O端口或寄存器的權(quán)限。但在嵌入式系統(tǒng)常用的ARM平臺,不存在這兩個系統(tǒng)調(diào)用,但是,可以將設(shè)備的寄存器或端口映射到某段物理內(nèi)存空間上。/dev/mem是物理內(nèi)存的全映像,可以用來訪問物理內(nèi)存,那么只需將DM9000網(wǎng)卡的寄存器或內(nèi)存映射到物理地址空間,根據(jù)映射的地址,使用_ap()系統(tǒng)調(diào)用,u-driver可以直接訪問和操作DM9000網(wǎng)卡的寄存器。
[0021]第三,確定MD9000網(wǎng)卡用戶態(tài)驅(qū)動的通信方案。如圖3所示,圖3為本實施例所采用的通信方案流程圖,其中實線為數(shù)據(jù)路徑,虛線為控制路徑。k-driver和u-driver必須協(xié)同工作才能完成傳統(tǒng)的內(nèi)核態(tài)驅(qū)動的功能。內(nèi)核態(tài)和用戶態(tài)的運行庫提供了這一服務(wù)。運行于內(nèi)核態(tài)的k-mod注冊為一個設(shè)備驅(qū)動程序并實現(xiàn)了字符設(shè)備接口。運行于用戶態(tài)的u-lib實現(xiàn)為一個鏈接到k-driver的多線程庫。本實施例采用ioctl O系統(tǒng)調(diào)用機制,實現(xiàn)k-mod和u-lib之間的通信。
[0022]k-driver調(diào)用u-driver中的函數(shù)時,通過調(diào)用k_mod來傳送請求給u-driver,u-driver預(yù)分配一個緩沖區(qū)來接收數(shù)據(jù),緩沖區(qū)的大小設(shè)置為u-driver與k-driver能傳輸?shù)臄?shù)據(jù)的上限,接下來,k-mod激活在內(nèi)核中等待的主線程,復(fù)制數(shù)據(jù)到u-driver地址空間中的緩沖區(qū),并通知u-lib調(diào)用u-driver中正確的函數(shù)。收到來自k-driver的請求之后,u-lib發(fā)送請求給一個工作線程,并回復(fù)內(nèi)核等待接下來的請求。
[0023]u-driver也可以向下調(diào)用,不論是調(diào)用k-driver中的函數(shù)還是內(nèi)核中的其它函數(shù),都可以通過ioctl O系統(tǒng)調(diào)用來實現(xiàn),k-mod中的一個ioctl管理器收到請求并調(diào)用合適的內(nèi)核函數(shù)。u-driver向下調(diào)用的的請求主要有以下幾種:(I)VIRT2PHY,計算u-driver模塊中虛擬地址對應(yīng)的物理地址;(2)UP_INF0,向內(nèi)核空間提交當(dāng)前用戶態(tài)驅(qū)動進(jìn)程信息;(3)DMA_PHY,獲取k-driver中DMA緩沖區(qū)的物理地址;(4)0PEN、CL0SE等系統(tǒng)調(diào)用。
[0024]第四,確定MD9000網(wǎng)卡用戶態(tài)驅(qū)動的DMA緩沖區(qū)分配方案。如圖4所示,圖4為本發(fā)明實施例中所采用的DMA緩沖區(qū)分配方案的數(shù)據(jù)拷貝流程圖,其中實線是本實施例方案的數(shù)據(jù)拷貝路徑,虛線是傳統(tǒng)內(nèi)核態(tài)驅(qū)動程序的數(shù)據(jù)拷貝路徑。為減少數(shù)據(jù)拷貝次數(shù),u-driver要能夠直接訪問DMA緩沖區(qū)的內(nèi)容,即實現(xiàn)用戶態(tài)的DMA緩沖區(qū)。這可以通過Linux內(nèi)核的設(shè)備文件/dev/mem和mmapO系統(tǒng)調(diào)用來實現(xiàn)。通過open()系統(tǒng)調(diào)用打開/dev/mem文件,接著,把k-driver申請的內(nèi)存的物理地址傳送到用戶空間,最后通過mmap ()將這段物理內(nèi)存映射到當(dāng)前進(jìn)程的地址空間。其中,分配共享內(nèi)存的關(guān)鍵代碼如下:kaddr = kmalloc (size);phy_addr = addr - PAGE_OFFSET;fd = open ( “/dev/mem'',0_RDWR); uaddr = mmap(phy_addr, length, PR0T_READ | PROT_WRITE, MAP_SHARED, fd, 0);最后,確定MD9000網(wǎng)卡用戶態(tài)驅(qū)動的中斷通知機制。將硬件產(chǎn)生的中斷通知給用戶程序,這里通過將中斷映射到文件描述符來實現(xiàn)這一功能。在Linux系統(tǒng)的/proc文件系統(tǒng)下,每一個中斷都對應(yīng)一個目錄,目錄下包含一些屬性文件。通過在中斷號對應(yīng)的目錄下增加一個新的屬性文件,用來標(biāo)識是否產(chǎn)生了該中斷號對應(yīng)的中斷。當(dāng)u-driver對該文件執(zhí)行readO操作時,內(nèi)核在對應(yīng)的信號量上執(zhí)行down()操作,阻塞該read()操作直到中斷的產(chǎn)生。硬件產(chǎn)生中斷時,首先在內(nèi)核中斷處理函數(shù)中屏蔽該中斷,然后增加中斷映射的文件描述符中的計數(shù),最后在對應(yīng)的信號量上執(zhí)行up()操作,使之前阻塞的readO操作返回,返回值為文件描述符中的中斷計數(shù),如果返回值大于0,說明產(chǎn)生了硬件中斷,則轉(zhuǎn)而去執(zhí)行u-driver中定義的中斷處理函數(shù)。
[0025]綜上所述,即將傳統(tǒng)的DM9000內(nèi)核態(tài)驅(qū)動程序改寫成為新的用戶態(tài)驅(qū)動程序。由于數(shù)據(jù)處理的關(guān)鍵代碼都留在內(nèi)核態(tài),移到用戶態(tài)的代碼都是對性能影響甚微的非關(guān)鍵代碼,這樣就將用戶態(tài)驅(qū)動程序?qū)π阅艿挠绊懡档搅俗钚?,完全能夠滿足實際需求。由于運行于用戶態(tài)的部分即使出現(xiàn)故障也不會影響到整個系統(tǒng),只需簡單地殺掉進(jìn)程再重新啟動即可,在本實施例中,約70%的代碼都可以從內(nèi)核態(tài)移至用戶態(tài),大大減少了留在內(nèi)核態(tài)運行的代碼量,而用戶態(tài)的部分也可以使用成熟的軟件工程工具來進(jìn)行編程,提高了代碼質(zhì)量,因此大大提高了系統(tǒng)的穩(wěn)定性。同時,實現(xiàn)過程中使用到的接口和系統(tǒng)調(diào)用都是現(xiàn)有Linux系統(tǒng)中的標(biāo)準(zhǔn)接口,與現(xiàn)有系統(tǒng)完全兼容,應(yīng)用范圍廣泛。
[0026]上面結(jié)合附圖對本發(fā)明的【具體實施方式】作了詳細(xì)說明,但是本發(fā)明并不限于上述實施方式,在本領(lǐng)域普通技術(shù)人員所具備的知識范圍內(nèi),還可以在不脫離本發(fā)明宗旨的前提下作出各種變化。
【權(quán)利要求】
1.一種嵌入式Linux下用戶態(tài)驅(qū)動程序的實現(xiàn)方法,其特征在于包括以下步驟: 步驟一,將傳統(tǒng)的內(nèi)核態(tài)驅(qū)動程序依據(jù)性能相關(guān)與否以及優(yōu)先級,分離為運行于內(nèi)核態(tài)的k-driver和運行于用戶態(tài)的u_driver兩個組件; 步驟二,在內(nèi)核態(tài)建立動態(tài)可加載內(nèi)核模塊k-mod ; 步驟三,在用戶態(tài)建立動態(tài)鏈接庫u-1 ib。
2.根據(jù)權(quán)利要求1所述的嵌入式Linux下用戶態(tài)驅(qū)動程序的實現(xiàn)方法,其特征在于:所述步驟一中的k-driver,包括性能相關(guān)的熱點代碼和數(shù)據(jù)通道,以Linux的可加載動態(tài)模塊的方式運行于內(nèi)核態(tài)。
3.根據(jù)權(quán)利要求1所述的嵌入式Linux下用戶態(tài)驅(qū)動程序的實現(xiàn)方法,其特征在于:所述步驟一中的u-driver,包括驅(qū)動程序中與性能無關(guān)的非關(guān)鍵操作以及優(yōu)先級較低的代碼,以一個普通進(jìn)程的形式運行于用戶態(tài)。
4.根據(jù)權(quán)利要求1所述的嵌入式Linux下用戶態(tài)驅(qū)動程序的實現(xiàn)方法,其特征在于:所述步驟二中的k-mod,注冊為一個設(shè)備驅(qū)動程序并實現(xiàn)了字符設(shè)備接口用來與u-lib通信;它實現(xiàn)的功能包括與u-driver進(jìn)行通信、追蹤k-driver與u_driver間共享的數(shù)據(jù)結(jié)構(gòu)。
5.根據(jù)權(quán)利要求1所述的嵌入式Linux下用戶態(tài)驅(qū)動程序的實現(xiàn)方法,其特征在于:所述步驟二中的u-lib,實現(xiàn)為一個鏈接到u-driver的多線程庫,具有的功能包括請求k-driver提供服務(wù)、執(zhí)行來自k_mod的函數(shù)調(diào)用請求。
6.根據(jù)權(quán)利要求1所述的嵌入式Linux下用戶態(tài)驅(qū)動程序的實現(xiàn)方法,其特征在于:所述步驟二的k-mod和步驟三的u-lib,共同提供了 k-driver和u-driver之間的通信,使得k-driver可以調(diào)用u-driver中的函數(shù),u-driver同樣能夠調(diào)用k-driver中的函數(shù),k-mod和u-lib相互配合跟蹤k-driver和u-driver兩個模塊的共享變量和全局?jǐn)?shù)據(jù),任何一方對數(shù)據(jù)的改變都要通知另一方,保證兩者數(shù)據(jù)的同步。
【文檔編號】G06F9/445GK103593189SQ201310565007
【公開日】2014年2月19日 申請日期:2013年11月14日 優(yōu)先權(quán)日:2013年11月14日
【發(fā)明者】周蘭江, 黃銀閣 申請人:昆明理工大學(xué)