標籤:虛擬檔案系統 多媒體 結構 電腦體系 驅動 作業系統 inf event ipc
【導語】在Android系統移植中,有很重要的一個部分工作,就是為新平台上的硬體裝置移植驅動程式。因為Android系統是基於Linux kernel核心構建,所以這裡說的移植驅動程式,其實就是基於Android系統平台開發適應行動裝置的Linux核心驅動程式。
一. Android系統中Linux核心與裝置驅動
Android系統中使用了Linux核心作為自己的作業系統,除了linux的通用代碼之外,主要還包含三個方面的東西:
Android系統中Linux核心與裝置驅動的結構如示:
Android系統通常用於行動裝置和其他的嵌入式裝置,因此都基於ARM體繫結構,在ARM體繫結構具有多種處理器。因此,對於不同對的處理器,基於相同的外圍裝置,驅動程式也可能不一樣。
需要說明的是中的Goldfish:
Android模擬器通過運行一個Goldfish的虛擬CPU ,Goldfish用來運行arm926t指令集(arm926t屬於armv5構架),並且模擬了輸入/輸出,比如鍵盤輸入和LCD 輸出。這個模擬器其實是在qemu之上開發的,輸入/輸出是基於libSDL的。既然Goldfish是被模擬器啟動並執行虛擬CPU,那麼當Android在真實的硬體裝置上運行時,我們就需要去掉它。
二. Android系統上的裝置驅動
- 基本圖形化使用者介面(GUI)部分:包括顯示部分、使用者輸入部分和硬體相關的加速部分,還包括媒體編解碼和OpenGL等。
- 音視頻輸入輸出部分:包括音頻、視頻輸出和網路攝影機等。
- 串連部分:包括無線區域網路、藍芽、GPS等。
- 電話部分:包括通話、GSM等。
- 附屬組件:包括感應器、背光、震動器等。
具體來說是有以下:
- [x] Display顯示部分:包括FrameBuffer驅動和Gralloc模組。
- [x] Input使用者輸入部分:包括Event驅動和EventHub。
- [x] Codec多媒體編解碼:包括硬體Codec驅動和Codec外掛程式,例如OpenMax。
- [x] 3DAccelerator(3D加速器)部分:包括硬體OpenGL驅動和OpenGL外掛程式。
- [x] Audio音頻部分:包括Audio驅動和Audio硬體抽象層。
- [x] VideoOut視頻輸出部分:包括視頻顯示驅動和Overlay硬體抽象層。
- [x] Camera網路攝影機部分:包括Camera驅動(通常是v4l2)和Camera硬體抽象層。
- [x] Phone電話部分:包括Modem驅動程式和RIL庫。
- [x] GPS全球定位系統部分:包括GPS驅動(例如串口)和GPS硬體抽象層。
- [x] Wi-Fi無線區域網路部分:包括Wlan驅動和協議和Wi-Fi的適配層。
- [x] BlueTooth藍芽部分:包括BT驅動和協議及BT的適配層。
- [x] Sensor感應器部分:包括Sensor驅動和Sensor硬體抽象層。
- [x] Vibrator震動器部分:包括Vibrator驅動和Vibrator硬體抽象層。
- [x] Light背光部分:包括Light驅動和Light硬體抽象層。
- [x] Alarm警告器部分:包括Alarm驅動和RTC系統和使用者空間調用。
- [x] Battery電池部分:包括電池部分驅動和電池的硬體抽象層。
在實際應用中,通過下面的圖,感受下一個量產的平板中用到了哪些硬體,體會下其中涉及到的驅動:
三.Android系統專用驅動
看一下Google為基於Linux kernel而定製的Android系統專用驅動程式:
(1)Android Binder
Android Binder是基於OpenBinder架構的一個驅動,用於Android平台的處理序間通訊(InterProcess
Communication,IPC)。原來的Linux系統上層應用的處理序間通訊主要是D-bus(Desktop bus),採用訊息匯流排的方式來進行IPC。
原始碼位於drivers/staging/android/binder.c。
(2)Android電源管理
Android電源管理是基於標準Linux電源管理系統的輕量級Android電源管理驅動,針對嵌入式裝置做
了很多最佳化。利用鎖和定時器來切換系統狀態,控制裝置在不同狀態下的功耗,已達到節能的目的。
原始碼位於:
- [ ] kernel/power/earlysuspend.c
- [ ] kernel/power/consoleearlysuspend.c
- [ ] kernel/power/fbearlysuspend.c
- [ ] kernel/power/wakelock.c
- [ ] kernel/power/userwakelock.c
Android5.0版本引用JobSchedule發送器,以便增加裝置續航時間。
(3)低記憶體管理器(Low Memory Killer)
比Linux的標準的OOM(Out Of Memory)機制更加靈活,它可以根據需要
殺死進程以釋放需要的記憶體。原始碼位於 drivers/staging/ android/lowmemorykiller.c。
(4)匿名共用記憶體(Ashmem)
為進程間提供大塊共用記憶體,同時為核心提供回收和管理這個記憶體的機制。原始碼位於
mm/ashmem.c。
(5)Android PMEM(Physical)
PMEM用於向使用者空間提供連續的實體記憶體地區,DSP和某些裝置只能工作在連續的物
理記憶體上。
原始碼位於drivers/misc/pmem.c。
(6)Android Logger
一個輕量級的日誌裝置,用於抓取Android系統的各種日誌,是Linux所沒有的。
原始碼位於drivers/staging/android/logger.c。
(7)Android Alarm
提供了一個定時器,用於把裝置從睡眠狀態喚醒,同時它還提供了一個即使在裝置睡眠時也會
啟動並執行時鐘基準。原始碼位於drivers/rtc/alarm.c。
(8)USB Gadget驅動
一個基於標準 Linux USB gadget驅動架構的裝置驅動,Android的USB驅動是基於gaeget架構的。
原始碼位於
- [ ] drivers/usb/gadget/android.c
- [ ] drivers/usb/gadget/f_adb.c
- [ ] drivers/usb/gadget/f_mass_storage.c
(9)Android Ram Console
為了提供調試功能,Android允許將調試日誌資訊寫入一個被稱為RAM Console的裝置
裡,它是一個基於RAM的Buffer。原始碼位於drivers/staging/android / ram_console.c。
(10)Android timed device
提供了對裝置進行定時控制的功能,目前支援vibrator和LED裝置。原始碼位於
drivers/staging/android /timed_output.c(timed_gpio.c)。
(11)Yaffs2 檔案系統
Android採用Yaffs2作為MTD nand flash檔案系統,原始碼位於fs/yaffs2/目錄下。
Yaffs2是一個快速穩定的應用於NAND和NOR Flash的跨平台的嵌入式裝置檔案系統,同其他Flash檔案系統相比,
Yaffs2能使用更小的記憶體來儲存其運行狀態,因此它佔用記憶體小。Yaffs2的記憶體回收非常簡單而且快速,因此能表
現出更好的效能。Yaffs2在大容量的NAND Flash上的效能表現尤為突出,非常適合大容量的Flash儲存。
四.Android驅動開發主要工作
Linux系統將裝置驅動分為以下三類:
(1)字元裝置
指只能一個位元組一個位元組讀寫的裝置,不能隨機讀取裝置記憶體中的某一資料,讀取資料需要按照先後資料。字元裝置是面向流的裝置,常見的字元裝置有滑鼠、鍵盤、串口、控制台和LED裝置等。
(2)塊裝置
指可以從裝置的任意位置讀取一定長度資料的裝置。塊裝置包括硬碟、磁碟、隨身碟和SD卡等。
(3)網路裝置
為支援通過檔案介面處理網路連接,Linux使用了源於BSD的通訊端抽象,通訊端keil看作應用程式、檔案介面、核心的網路之間的代理。
驅動程式是介於系統和硬體之間的橋樑,實現硬體和系統之間的互動是我們底層開發的主要任務。在Android系統中,我們一般需要編寫核心級和使用者級的程式來完成具體的任務。
4.1 實現系統和硬體之間互動的幾種方式
(1).編寫自己的系統調用
系統調用是使用者級程式訪問核心最基本的方法,Linux提供了很多標準的系統調用(參見核心代碼樹中的include/asm-i386/unistd.h和arch/i386/kernel/entry.S檔案),並且允許我們添加自己的系統調用來實現和核心的資訊交換;
(2).編寫驅動程式
Linux有一個重要的理念就是“一切皆檔案”(everything is a file)。
使用者空間的應用程式通過系統提供的統一互動介面 open() —— read() —— write() —— ioctl() —— close()方法,訪問檔案系統中/dev/目錄下的一個檔案來訪問運行於核心空間的驅動程式,並通過驅動程式中實現的功能達到對硬體的訪問。
(3). 使用proc 檔案系統
proc是Linux提供的一種特殊的檔案系統,推出它的目的就是提供一種便捷的使用者和核心間的互動方式。proc 檔案系統相對是比較簡單的,不過proc檔案的讀寫並不統一,讀資料的buf指標直接指向的就是使用者態的地址,可以用sprintf進行寫入;而寫方法卻是核心態的地址,需要用get_user或者 copy_from_user之類的方法。
(4).使用虛擬檔案系統
有些核心開發人員認為利用ioctl()系統調用往往會似的系統調用意義不明確,而且難控制。而將資訊放入到proc檔案系統中會使資訊組織混亂,因此也不贊成過多使用。他們建議實現一種孤立的虛擬檔案系統來代替ioctl()和/proc,因為檔案系統介面清楚,而且便於使用者空間訪問,同時利用虛擬檔案系統使得利用指令碼執行系統管理任務更家方便、有效。
(5).使用記憶體映像
Linux通過記憶體映像機制來提供使用者程式對記憶體直接存取的能力。記憶體映像的意思是把核心中特定部分的記憶體空間映射到使用者級程式的記憶體空間去。也就是說,使用者空間和核心空間共用一塊相同的記憶體。
4.2 核心空間和使用者空間的互動
上面講了系統與硬體互動的幾種方式提到了,在具體的互動中,驅動程式驅動具體的硬體模組工作時涉及到一個核心空間和使用者空間互動的概念。
現代的電腦體繫結構中儲存管理通常都包含保護機制。提供保護的目的,是要避免系統中的一個任務訪問屬於另外的或屬於作業系統的儲存地區。如在IntelX86體系中,就提供了特權級這種保護機制,通過特權層級的區別來限制對儲存地區的訪問。
基於這種構架,Linux作業系統對自身進行了劃分:一部分核心軟體獨立於普通應用程式,運行在較高的特權層級上,(Linux使用Intel體系的特權級3來運行核心。)它們駐留在被保護的記憶體空間上,擁有訪問硬體裝置的所有許可權,Linux將此稱為核心空間 。
相對的,其它部分被作為應用程式在使用者空間 執行。它們只能看到允許它們使用的部分系統資源,並且不能使用某些特定的系統功能,不能直接存取硬體,不能直接存取核心空間,當然還有其他一些具體的使用限制。(Linux使用Intel體系的特權級0來運行使用者程式。)
通過下面的圖,看一下核心空間與使用者空間的互動關係:
著作權聲明:本文為博主【limin13215】原創文章,歡迎轉載,轉載請註明連結地址! 72676518
Android系統移植:驅動篇