戴明華,李長云,曾志浩,崔海燕
(湖南工業大學計算機與通信學院,湖南 株洲 412008)
嵌入式Linux驅動程序框架研究綜述*
戴明華,李長云,曾志浩,崔海燕
(湖南工業大學計算機與通信學院,湖南 株洲 412008)
嵌入式Linux的驅動框架能縮短開發周期,因此構建框架對驅動開發有著很重要的意義.介紹了目前驅動研究現狀,闡述了構建嵌入式Linux驅動框架的方式并進行了評價,探析了未來基于Linux內核的Android操作系統的驅動框架實現.
嵌入式驅動框架;Android驅動;實現方法;可移植
以嵌入式操作系統為核心的嵌入式系統,能運行于各種不同體系結構的微處理器上,兼容性好,內核體積小,效率比較高,具有高度的模塊化和可擴展性.對設備的支持需要相應的驅動程序.嵌入式 Linux是以Linux為基礎的嵌入式系統,在原來的Linux基礎上裁剪而成的精簡的操作系統,它被廣泛應用在移動電話、機頂盒、數據網絡、遠程通信、醫療電子、交通運輸計算機外設、工業控制、媒體播放器、消費性電子產品以及航空航天等領域中.目前,嵌入式Linux開發主要集中在設備驅動開發上;在嵌入式Linux中,驅動占有內核代碼的70%以上,驅動開發的質量關系到整個系統的穩定[1],大多數驅動沒有標準化,在移植的時候,驅動代碼一般由硬件制造者而不是專業內核編程者編寫.由于Linux驅動和內核共享地址空間等原因造成移植開發的驅動穩定性不夠[2],為了更快且較穩定地開發驅動,建立驅動框架來減少開發周期和增強穩定性就很有研究價值.本文非常全面地介紹了嵌入式驅動程序框架,分析優點的同時也對框架存在的問題和未來研究方向提出了我們的觀點.
嵌入式Linux驅動程序是操作系統內核和硬件之間的接口,連接硬件設備和文件系統,是硬件的一部分特殊響應定義好的內部編程接口.硬件設備在Linux看來只是一個設備文件,這些文件一般稱作設備文件,使得應用程序可以像操作普通文件一樣對硬件設備進行操作.嵌入式Linux系統的驅動程序分為字符設備驅動、塊設備驅動和網絡設備驅動三種,字符設備是指存取時沒有緩存的設備;塊設備的讀寫都有緩存來支持,并且塊設備必須能夠隨機存取.典型的字符設備包括鼠標、鍵盤、串行口、音頻設備等.塊設備主要包括硬盤軟盤設備、CD-ROM以及各種flash等.
設備驅動是作為文件系統的一個模塊存在的,它既負責和硬件的交互,同時通過掛載在文件系統上和內核聯系起來.
驅動程序的構成主要包括三個重要部分[3]:1)初始化.在靜態鏈接驅動中由__init修飾的函數和在可加載驅動中用入口點函數init_module()對驅動進行初始化,初始化包括硬件相關參數、申請內存、注冊.2)獨立的設備的接口.該接口由struct file_operations這個數據結構來實現,系統調用和驅動程序通過數據結構struct file_operations聯系起來.這個結構的每一個成員的名字都對應著一個系統調用,系統調用通過設備文件的主設備號找到相應的設備驅動程序.3)硬件相關部分.這一部分和硬件直接相關,包括I/O服務和中斷服務.
這是Linux的設備驅動程序編寫工作的基本原理.因此設備驅動程序的實現首先要初始化,然后實現file_operations的各個域,最后靜態鏈接或動態加載驅動程序.
框架的方式一種是從驅動開發的角度,從同類型設備中找出相似點,包括數據結構、接口函數、注冊與注銷函數、中斷的申請與釋放函數,使用模塊化編程思想.
另一種是從面向對象的角度,驅動中建立可重用的類庫,用來封裝常用的數據結構和算法,將程序的加載、初始化、卸載等相關流程進行封裝管理[4].
從能否動態加載的角度看,Linux中的驅動程序可分為可動態加載和卸載的內核模塊和靜態鏈接的內核,而根據Linux對驅動的管理方式則可以把驅動分為字符驅動、塊設備驅動和網絡驅動,應用程序對字符設備的每一個I/O操作,都會傳遞給系統內核對應的驅動程序,而對于塊設備的操作,要經過系統的緩沖區管理,間接傳遞給驅動程序處理.網絡驅動則是基于BSD UNIX的套接字機制,在系統和驅動程序之間定義有專門的數據結構進行數據傳輸,系統提供流量控制機制和多協議支持.可見字符設備,塊設備和網絡設備所用的驅動差別很大,因此在構建驅動框架的時候分類型構建框架更加容易找到通性.
字符設備驅動程序是最基本、最常用的驅動程序結構,只要是不掛載文件系統的設備,都可以用字符設備去描述.
一個字符設備是一種可以當作一個字節流來存取的設備就如同一個文件,這樣的驅動常常實現常用的系統調用,串口是最為常見的字符設備,它很好地展現了字節流的抽象.字符設備通過文件系統結點來存取,相對于可以隨機存取普通文件,字符設備僅僅是數據通道,因此只能順序存取.
文獻[5]給出嵌入式設備驅動驅動程序的共性,包括:讀、寫、中斷、時鐘.實現嵌入式設備驅動流程,總結了傳統驅動基本組成部分:模塊初始化函數;模塊卸載函數;設備驅動程序接口,李健等人[6]在基于嵌入式實時操作系統的驅動框架中通過屏蔽底層硬件處理器、規范總線接口、抽象設備訪問接口,結合設備驅動表、設備表、文件描述符表、總線驅動支持、設備中斷處理機制給出設備驅動基本框架.該驅動框架包括1、I/O標準接口2、文件描述符管理3、設備表、驅動表4、文件系統管理5、通信協議層6、協議適配層7、底層驅動層8、實時操作系統支持接口.該框架支持了目前主流的總線及設備,支持集成了傳統I/O系統的文件系統、網絡協議棧等模塊,能夠支持各種設備,又能使各子系統信息互通,增強了可移植性.
文獻[4]從代碼的可重用的角度出發,用面向對象的方法,封裝對驅動生命周期和行為管理的驅動框架,將C++語言引入到內核中,加速了開發速度,該方法改變了傳統上使用c語言開發內核,使用c++來實現驅動與內核的兼容,內核能對c++編碼的驅動進行加載卸載,同時,c++的繼承等重要特性依然保留在驅動程序中.
在字符程序的框架中,按照代碼的框架來寫只適合用來開發比較簡單的驅動,在復雜驅動的開發中,至少要使用文獻[6]中的框架或者用可重用的面向對象的方法,才能不針對每一個具體的硬件作出大范圍的修改,硬件開發者也不需要了解太多關于硬件的細節也可進行驅動的開發.
關于塊設備驅動的研究甚少,主要由于有部分塊設備驅動可以用字符驅動形式來開發,如PCI、LCD等.
在塊設備中比較典型的有flash,它由于芯片的存儲布局以及存儲操作與字符型完全不同,不能按照字符型設備驅動進行開發.以flash為例,驅動主要功能包括[7]:初始化、用接口函數和內核函數完成內核與用戶之間的數據交換以及檢測設備錯誤信息.塊設備都以塊作為單位進行數據讀寫,要構建緩存來存放臨時數據,塊設備中大容量的數據使得糾錯機制成為塊設備驅動不可忽視的一部分[8].
網絡設備與字符與塊這兩種I/O驅動完全不同,在Linux里有專門的處理機制.Linux的網絡系統主要是基于BSD unix的socket機制.系統支持對發送數據和接收數據的緩存,提供流量控制機制,提供對多協議的支持.文獻[9]中網絡設備驅動體系結構可以分為四個層次,即協議接口、網絡設備接口、驅動功能層、網絡媒介,網絡設備被抽象為一個接口,是一個對網絡設備的操作集合.如下圖:

圖1 網絡設備驅動體系結構圖
從Linux的結構來看,Linux所有網絡驅動程序都使用了通用的接口,每個設備都有自己的數據和方法,對于網絡設備程序,由于Linux網絡的驅動程序結構本來有網絡協議接口、網絡設備接口,提供實際功能的功能層、網絡設備媒介,因此在網絡框架上都是在原來的基礎上略加改進.
從Linux的出現到學者開始在Linux架構的基礎上開始驅動的改進和驅動新框架的提出,Linux的三大類驅動都產生了新的開發方式.
本文介紹了驅動的相關概念,闡述了驅動的構成,同時從諸多文獻實現框架的方式中,綜合了各種類型驅動的框架結構,進行了相應評價.現在基于Linux內核的嵌入式操作系統正在興起,這些操作系統下的驅動有著和Linux相似之處.因此,Linux驅動框架的研究能夠推動其它如Android嵌入式操作系統驅動框架的研究.
Android內核是在標準Linux內核的基礎上修改而成的且適應嵌入式硬件環境.Android驅動框架的形成增強了可移植性,提高了效率.由于這是在底層開發,因此在框架構建和可移植性上,主要有以下兩個需要了解:
Android不同于Linux主要體現在沒有使用Linux的C庫——glibc,增加了模擬CPU和文件系統.在驅動支持方面,既開發了基于OpenBinder框架的Android Binder驅動,還擁有電源管理、低內存匿名共享、連續物理內存等專有驅動.在Android系統中,需要有基本的屏幕、觸摸屏、鍵盤等驅動程序,以及音頻、攝像頭、Event、電話的 Modem、Wifi、藍牙等多種設備驅動程序.當進行嵌入式軟件開發時,可移植性是要重點考慮的問題.良好的軟件移植性應該比較好,減少與外圍設備的相關性.軟件的通用性和軟件的性能通常是矛盾的.Linux驅動研究比較充分,而以Linux為內核的其它操作系統開始發展,因此研究應以Linux驅動框架的研究為基礎.
[1]Chou A,Yang J,Chelf B,et al.An empiracle study of operating system errors[J].ACM SIGOPS Operating Systems Review,2001,(5):73-88.
[2]Herder J N,Bos H,Gras B,et al.Construction of a highly dependable operating system[A].Proceedings of the Sixth European Dependable Computing Conference[C].Coimbria:IEEE,2006.
[3]梁金千,張躍,甄成.Linux設備驅動程序架構的研究[J].計算機工程與應用,2002,(8):119 -122.
[4]袁麗慧,彭磊.可重用 Linux設備驅動程序框架[J].計算機工程,2008,(10):89 -94.
[5]李橋.嵌入式Linux設備驅動程序的開發研究[J].計算機與數字工程,2009,(2):87 -97.
[6]李健,李明祿,張激,等.基于嵌入式實時操作系統的驅動框架[J].計算機工程,2007,(21):273 -275.
[7]李勝朝,黃先祥,周召發.嵌入式Linux下塊設備驅動程序的開發[J].機電工程技術,2007,(6):26 -28.
[8]鄭千洪,王黎,高曉蓉.嵌入式平臺上NAND FLASH的驅動實現[J].微計算機信息,2009,(11):103 -105.
[9]張俊才,馬強.Linux下網絡設備驅動程序研究[J].實驗科學與技術,2008,(4):51 -53.
TP311
A
1008-4681(2012)02-0052-02
2011-12-06
戴明華(1985-),男,湖南寧鄉人,湖南工業大學計算機與通信學院碩士生.研究方向:可信軟件.
(責任編校:晴川)