周德榮,夏 齡
(四川民族學院 網絡信息中心,四川 康定 6 2 6 0 0 1)
L i n u x platform驅動架構實現機制研究與應用
周德榮,夏 齡
(四川民族學院 網絡信息中心,四川 康定 6 2 6 0 0 1)
Linux 2.6內核開發了全新的設備驅動模型,實現了設備驅動到總線和核心層的抽象,platform是基于新設備驅動模型的虛擬總線.本文采用linux 2.6.25.8內核源碼,介紹了設備驅動模型原理,詳細分析了platform總線驅動架構在linux內核中的實現機制,以TQ2440開發板為測試平臺,基于platform驅動架構設計實現了按鍵驅動.實驗表明,此方法切實可行,驅動具有較好植移性和安全性.
設備驅動模型;platform;sysfs;按鍵驅動
隨著技術的不斷進步,系統的拓撲結構越來越復雜,系統支持的設備數量巨增,對智能電源管理、熱插拔以及p l u g a n dp l a y的支持要求也越來越高,為適應這種形勢的需要,L i n u x2.6內核開發了全新的設備模型.L i n u x設備驅動模型采用面向對象的思想,完成從設備驅動到總線和核心層的抽象.platform是設備驅動模型中基于設備驅動模型核心層的一個虛擬總線,基于platform驅動架構驅動設計方式在新版linux內核中大量使用.
L i n u x設備驅動模型是為了系統地管理所有設備,內核通過k o b j e c t s和k s e t s底層數據結構來實現基本對象及其層次關系,底層數據結構之上實現的設備模型的核心組件總線,設備,驅動結構及相互操作.
1.1 底層關鍵數據結構
設備驅動模型底層主要涉及k o b j e c t內核對象、K s e t內核對象集合兩個數據結構.k o b j e c t是L i n u x2.6新引入的設備管理機制,是設備模型的核心結構,內核中用s t r u c t k o bj e c t表示.k o b j e c t提供基本的對象管理能力,使所有設備在底層具有統一的接口.k o b j e c t主要完成對象的引用計數、s y s f s表示、數據結構粘和、熱插拔事件處理功能.k o b j e c t結構定義為:

k s e t是具有相同類型的k o b j e c t的集合,它有一套操作函數,實現k s e t組織成層次化的結構管理,內核中用k s e t數據結構表示.k s e t數據結構定義為:

包含在k s e t中的所有k o b j e c t被組織成一個雙向循環鏈表l i s t.k s e t數據結構內嵌了一個k o b j e c t對象k o b j,所有屬于這個k s e t的k o b j e c t對象的p a r e n t域均指向這個內嵌的對象.k s e t的引用計數依賴內嵌的k o b j e c t對象的引用計數來實現.u e v e n t_o p s域代表當前u e v e n t的操作集合.
1.2 linux設備模型三要素
在底層數據結構建立內核對象管理機制的基礎上,L i nu x通過總線、設備、設備驅動三個核心組件實現設備模型.總線作為主機和外設的連接通道,任何設備都可以選擇合適的總線連接到主機,總線由s t r u c t bus_t y p e結構描述,每個bus_t y p e對象都對應/s y s/bus目錄下的一個子目錄.設備是連接在總線上的實體,不同設備功能不同.設備由device結構描述.驅動程序是C P U運行時,提供操作設備的軟件接口,所有設備必須配套驅動程序才能正常工作.設備驅動由device_driver結構描述.總線,設備,設備驅動三者關系如圖1所示.
L i n u x初始化時,總線開始掃描設備,找到設備就為其申請一個s t r u c t device結構,通過內核函數將其加入總線中p->device s_k s e t鏈表;每個驅動程序初始化時,注冊s t r u c t device_driver結構,遍歷總線的p->device s_k s e t鏈表,去尋它所支持的設備,找到后把s t r u c t device中的s t r u c t device_driverdriver指向這個driver,而s t r u c tdevice_driver driver把s t r u c t device加入他的那張s t r u c t k l i s t k l i s t_device s鏈表.
1.3 s y s f s文件系統
s y s f s文件系統是linux設備模型的一個重要組成部分.s y s f s是一個在啟動時加載到/s y s的內存文件系統,它用于將系統中的設備組織成層次結構,并向用戶模式程序提供詳細的內核數據結構信息.頂層目錄主要有包含所有的塊設備的B l o c k目錄、所有設備的D e v i c e s目錄、系統所有總線類型的B u s目錄、內核中所有已注冊設備驅動程序的D r i v e r s目錄、系統中設備類型的C l a s s目錄.

圖1 總線,設備,設備驅動的關系
platform驅動架構是在Linux設備驅動模型上實現的,是對總線,設備,驅動進行了再次封裝處理,Linux 2.6新近源碼中大部分驅動程序采用方式對原來驅動進行了改寫,platform總線驅動架構在內核中分platform總線生成,platform設備、plat form驅動三部分實現.
2.1 platform總線
platform總線是linux 2.6內核加入的一種虛擬總線,它主要用于連接S O C上的片上資源.platform總線在內核中用platform_bus_t y p e結構表示,總線本身也是一個設備,L i n u x內核用platform_bus結構表示.linux內核源碼d r i ve r/b a s e/platform.c中定義了plat f o r_bus和platform_bus_t y p e全局內核對象.platform總線作為一個設備在系統啟動時自動創建,具體函數調用流程為:start_k e r n e l()->rest_init()->k e rn e l_init()->d o_basic_se t u p()->driver_init()->platform_bus_init().start_k e r n e l()、rest_init()、k e r n e l_init()和 d o_basic_se t u p()在init/m a i n.c中實現.driver_init()在drivers/b a s e/init.c中實現,platform_bus_init()在drivers/b a s e/platform.c中實現.流程中最終是調用platform_bus_init()完成platform總線生成與注冊,核心代碼如下所示.


2.2 platform設備與platform驅動
platform設備作為特殊的獨立實體在系統中出現,主要包括基于端口的設備、外圍總線的連接設備,以及大多數集成于S O C的控制器,它們通常都通過C P U總線直接尋址.內核中platform設備用S t r u c tplatform_device結構描述,platf o r m驅動用platform_driver結構描述,如圖2所示.platf o r m_device結構由設備名稱n a m e、設備i d、設備d e v和資源r e s o u r c e組成,N a m e用作與驅動進行匹配,r e s o u r c e是設備使用的資源數據,如I R Q,地址等.通過platform_add_device s()、platform_device_register()和 platform_device_add()函數將平臺設備注冊到platform總線.platform_driver完全遵照設備驅動模型的約定,繼承了device_driver,并進行了封裝,通過platform_driver_register()函數完成平臺驅動注冊,平臺驅動注冊涉及的主要函數調用流程為:platform_driver_register()->driver_register()->bus_add_driver()->driver_a t t a c h()->bus_f o r_e a c h_d e v()->__driver_a t t a c h()->driver_probe_device()->really_probe()->d r v->probe()->driver_b o u n d().platform驅動注冊的核心任務是在driver_probe_device()函數中通過d r v->bus->m a t c h()語句實現調用 platform總線的m a t c h()方法,判斷驅動的名稱和設備的名稱是否相等,相等驅動能處理指定設備,否則驅動不能處理指定設備.然后通過在r e a ll y_probe()方法中執行 d r v->probe(d e v)語句實現調用 platf o r m驅動的probe()方法,完成綁定驅動到設備.

3.1 硬件平臺資源
T Q 2 4 4 0是一個基于S 3 C 2 4 4 0的開發測試平臺,按鍵硬件原理如圖 3所示.S 3 c 2 4 4 0的 G P I O_F 0,G P I O_F 1,G P IO_F 2,G P I O_F 4作為輸入口,讀取按鍵狀態,這四個I/O口分別使用外部中斷 E I N T 0,E I N T 1,E I N T 2,E I N T 4.當按鍵松開時,I/O口處于高電平,得到邏輯1,當按鍵按下時,I/O被拉低,得到邏輯0.

圖3 T Q 2 4 4 0平臺按鍵原理圖
3.2 按鍵驅動實現
通過platform總線架構開發設備驅動流程是:首先定義platform_device,注冊platform_device,實現platform設備注冊到 platform總線.然后定義 platform_driver,注冊 platf o r m_driver,實現編寫platform驅動,并完成驅動和設備的綁定.platform設備和platform驅動分別使用不同的內核模塊實現.
3.2.1 platform設備實現
platform設備是注冊到platform總線的,使用s t r u c t platform_device定義平臺設備,然后通過在模塊初始化函數中調用platform_device_register()執行平臺設備注冊,平臺設備注冊成功后,在platform總線產生名稱為s 3 c 2 4 4 0-k e y的設備.平臺設備定義及注冊的核心代碼如下:

3.2.2 platform驅動實現
platform驅動的實現主要是定義一個s t r u c t platf o r m_driver類型的s 3 c 2 4 4 0_k e y_driver,并實現其成員,然后在模塊初始化函數中通過調用platform_driver_register()實現注冊平臺驅動到platform總線.定義平臺驅動的核心代碼如下:

在s 3 c 2 4 4 0_k e y_driver中s 3 c 2 4 4 0_k e y_probe()是完成查詢系統中是否有對應的設備,有則完成驅動的初始化工作.按鍵驅動采用中斷方式實現,每個按鍵對應一個中斷,實現時對應一個中斷處理函數.在s 3 c 2 4 4 0_k e y_probe()函數中調用m i s c_register()將按鍵作為混亂驅動向內核注冊,實現按鍵的 o p e n()、r e a d()、p o l l()和 c l o s e()功能,在 o p e n()函數中調用r e q u e s t_i r q()實現中斷處理函數與中斷號的綁定,當按下一個鍵時中斷處理程序立即響應.s 3 c 2 4 4 0_k e y_probe()函數的核心代碼框架如下:

基于platform總線的驅動機制與傳統的設備驅動機制相比,platform總線的驅動機制將設備本身的資源注冊進內核,由內核統一管理,驅動程序使用這些資源時使用platf o r m device提供的標準接口進行申請,提高了驅動和資源管理的獨立性,具有較好的移植性和安全性.
〔1〕(印)Sreekrishnan Venkateswaran .Essential Linux Device Drivers[M].Prentice Hall PTR,2009.
〔2〕(美 )Jonathan Corbet,Alessandro Rubini,Greg Kroah-Hartman,魏永明譯.Linux設備驅動程序 (第三版)[M].中國電力出版社,2006.
〔3〕宋寶華.Linux設備驅動開發詳解[M].人民郵電出版社,2008.
〔4〕李俊.嵌入式Linux設備驅動開發詳解[M].人民郵電出版社,2008.
〔5〕孫天澤,袁文菊,等.嵌入式設計及 Linux驅動開發指南——基于ARM 9處理器[M].電子工業出版社,2005.
〔6〕韋東山.嵌入式Linux應用開發完全手冊[M].人民郵電出版社,2008.
T P 3 0 3
A
1673-260X(2010)10-0028-03