android 底層開發(fā)_第1頁
android 底層開發(fā)_第2頁
android 底層開發(fā)_第3頁
android 底層開發(fā)_第4頁
android 底層開發(fā)_第5頁
已閱讀5頁,還剩41頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、近年來,手機(jī)移動平臺越來越火爆。打開自己的QQ算了一下,在線好友共有31個,其中用手機(jī)上的有13個,手機(jī)用戶占了42%;打開新浪微博、天涯和貓撲等網(wǎng)站,各種終端設(shè)備的發(fā)貼、回貼更是數(shù)不勝數(shù)。目前,手機(jī)平臺如日中天的要數(shù)是iOS和Android了,尤其是iOS,Symbian已沒落,WP7在掙扎。iOS一如既往地走Apple特色的封閉道路,然而它的強(qiáng)大在于能夠建立一個完整的生態(tài)系統(tǒng),喬布斯確實是天之驕子,沒有之一;相反,Android奉行開放政策。注意,Android是開放,不是開源,從Android被踢出Linux  Kernel主線代碼,可以看出為什么說Android是開放而不是開

2、源的: Mac是如何被開放的IBM PC打得一敗涂地的。Google能夠重現(xiàn)IBM當(dāng)年的輝煌嗎?不好說,吃一塹,長一智,Apple還是一個偉大的公司的。然而,個人還是看好Google,看好Android.      既然看好移動平臺,看好Android,那還等什么,趕緊研究一下吧。工欲善其事,必先利其器。相信大家都知道Android的APP的是用Java寫的,運行在Dalvik虛擬機(jī)上,還有,Android的系統(tǒng)是基于Linux Kernel 2.6的。那么,要想深入了解Android系統(tǒng)的各種細(xì)節(jié),當(dāng)然少不了Linux Kernel的知識了。本人水平有

3、限,對Linux Kernel也是略知皮毛,望與大家共勉,在此,推薦幾本幾天Linux Kernel的經(jīng)典書籍:      1. Linux Kernel Development.      2. Understanding the Linux Kernel.      3. Linux Device Drivers.      4. Linux內(nèi)核源代碼情景分析.看了Linux Kernel的書,當(dāng)然也要看一下Android的書了,這

4、樣可以對Android平臺長什么樣子有一個感性的認(rèn)識,推薦下面兩本書:      1. Professional Android Application Development.      2. Google Android SDK開發(fā)范例大全.      如果可以一邊看書,一邊照著例子實戰(zhàn)一下,那就更好不過了:)。后面,我將會總結(jié)一些自己學(xué)習(xí)過程覺得有用的知識出來,與大家分享、交流。開始我們的Android之旅吧。 在Ubuntu上下載、編譯和安裝Android最

5、新源代碼分類: Android2011-06-21 23:15 4357人閱讀 評論(41) 收藏 舉報        看完了前面說的幾本書之后,對Linux Kernel和Android有一定的認(rèn)識了,是不是心里蠢蠢欲動,想小試牛刀自己編譯一把Android源代碼了呢?一直習(xí)慣使用Windows系統(tǒng),而Android源代碼是不支持在Windows上編譯上,于是決定使用虛擬機(jī)安裝Ubuntu,然后下載、編譯和安裝Android源代碼。     一. 環(huán)境準(zhǔn)備。

6、60;    1. 磁盤空間預(yù)留20G左右,內(nèi)存3G,因為一邊要跑主機(jī),一邊要跑虛擬機(jī),內(nèi)存要求還是比較高的,這樣才會比較流暢。     2. 安裝。我的操作系統(tǒng)是Win7,VMWare的版本要新一點的,舊版本的VMWare在網(wǎng)絡(luò)支持上比較差,由于要在虛擬機(jī)上下載Android源代碼,沒有網(wǎng)絡(luò)是萬萬不行的。     3. 安裝好VMWare后,接下來就安裝Ubuntu系統(tǒng)了。我選擇目前最新的版本ubuntu-11.04-alternate-i386,從網(wǎng)上查到的資料說,要編譯Android源代碼,Ubuntu的最低

7、版本是8.04。下載好后,安裝時采用一直默認(rèn)安裝即可。     4. 安裝Git工具。Android源代碼采用Git工具來管理,與SVN相比,這是一種分布式的源代碼管理工具,而SVN是集中式的源代碼管理工具。要安裝Git工具,在Ubuntu上執(zhí)行以下命令即可:     USER-NAMEMACHINE-NAME:$ sudo apt-get install git-core gnupg     5. 安裝Java SDK。在Ubuntu上執(zhí)行以下命令:  

8、   USER-NAMEMACHINE-NAME:$  sudo add-apt-repository ppa:ferramroberto/java      USER-NAMEMACHINE-NAME:$  sudo apt-get update     USER-NAMEMACHINE-NAME:$  sudo apt-get install sun-java6-jre sun-java6-plugin    

9、USER-NAMEMACHINE-NAME:$  sudo apt-get install sun-java6-jdk                   6. 依賴的其它包。在Ubuntu上執(zhí)行以下命令:      USER-NAMEMACHINE-NAME:$ sudo apt-get install flex bison gperf libsdl-dev libesd0-

10、dev libwxgtk2.6-dev build-essential zip curl     7. 調(diào)試工具。在Ubuntu上執(zhí)行以下命令:      USER-NAMEMACHINE-NAME:$ sudo apt-get install valgrind     二. 下載Android源代碼工程。      1. 下載repo工具。在Ubuntu上執(zhí)行以下命令:    

11、0; USER-NAMEMACHINE-NAME:$ wget      USER-NAMEMACHINE-NAME:$ chmod 777 repo     USER-NAMEMACHINE-NAME:$ cp repo /bin/     2. 下載Android最新版本源代碼。在Ubuntu上執(zhí)行以下命令:     USER-NAMEMACHINE-NAME:$ mkdir Android&

12、#160;    USER-NAMEMACHINE-NAME:$ cd Android     USER-NAMEMACHINE-NAME:/Android$ repo init -u git:/     USER-NAMEMACHINE-NAME:/Android$ repo sync     經(jīng)過漫長的等待(我下載了兩三天)后,就可以把Android源代碼下載下來了。其間可能還有經(jīng)歷下載中斷的情況,這時只要重新執(zhí)行repo

13、 sync就可以了。     三. 編譯Android源代碼。     1. 編譯。在Android目錄下執(zhí)行以下命令:     USER-NAMEMACHINE-NAME:/Android$ make     第一次編譯要等待比較久的時間,編譯成功后,可以看到下面的輸出:     Target system fs image:    out/target/product/generic/obj/

14、PACKAGING/systemimage_intermediates/system.img     Install system fs image: out/target/product/generic/system.img     Target ram disk: out/target/product/generic/ramdisk.img     Target userdata fs image: out/target/product/generic/userdata.img  

15、   Installed file list: out/target/product/generic/installed-files.txt      2. 編譯過程中可能會遇到的問題。     問題一:You are attempting to build on a 32-bit system.     兩個地方需要個修改:     1)修改build/core目錄下的main.mk文件:    

16、0;ifeq ($(BUILD_OS),linux)     build_arch := $(shell uname -m)     #Change the following line for building on a 32-bit system.     #ifneq (64,$(findstring 64,$(build_arch)     ifneq (i686,$(findstring i686,$(build_arch)   

17、60; $(warning *)     $(warning You are attempting to build on a 32-bit system.)     $(warning Only 64-bit build environments are supported beyond froyo/2.2.)     2)找到下列文件:     /external/clearsilver/cgi/Android.mk     /externa

18、l/clearsilver/cs/Android.mk     /external/clearsilver/java-jni/Android.mk     /external/clearsilver/util/Android.mk     修改LOCAL_CFLAGS和LOCAL_LDFLAGS變量:     # This forces a 64-bit build for Java6     # Change the followin

19、g two lines for building on a 32-bit system.     # LOCAL_CFLAGS += -m64     # LOCAL_LDFLAGS += -m64     LOCAL_CFLAGS += -m32     LOCAL_LDFLAGS += -m32     問題二:Undefined reference to _dso_handle'   

20、;   external/stlport/src/monetary.cpp:39: undefined reference to _dso_handle'out/target/product/vm/obj/SHARED_LIBRARIES/libstlport_intermediates/src/locale.o: In function _static_initialization_and_destruction_0':     external/stlport/src/locale.cpp:29: undefined ref

21、erence to _dso_handle'out/target/product/vm/obj/SHARED_LIBRARIES/libstlport_intermediates/src/locale_impl.o: In function _static_initialization_and_destruction_0':     external/stlport/src/locale_impl.cpp:31: undefined reference to _dso_handle'out/target/product/vm/obj/SHA

22、RED_LIBRARIES/libstlport_intermediates/src/locale_impl.o: In function std:_Locale_impl:make_classic_locale()':     external/stlport/src/locale_impl.cpp:670: undefined reference to _dso_handle'     external/stlport/src/locale_impl.cpp:667: undefined reference to

23、_dso_handle'out/target/product/vm/obj/SHARED_LIBRARIES/libstlport_intermediates/src/locale_impl.o:external/stlport/src/locale_impl.cpp:604: more undefined     references to _dso_handle' follow     collect2: ld returned 1 exit status      

24、;修改external/stlport/dll_main.cpp,加入以下聲明:     extern "C"             void * _dso_handle = 0;           四. 編譯SDK,這一步是可選的。     1. 編譯。執(zhí)行以下命令:     USER-NAMEMACHINE-N

25、AME:/Android$ make sdk     2. 編譯過程中可能會遇到的問題。     問題一:找不到bios.bin和vgabios-cirrus.bin文件     couldn't locate source file: usr/share/pc-bios/bios.bin     couldn't locate source file: usr/share/pc-bios/vgabios-ci

26、rrus.bin     注意,這里的usr/share目錄指的是/Android/out/host/linux-x86目錄下的usr/share目錄,修改辦法是復(fù)制/Android/prebuilt/common下的pc-bios文件夾到/Android/out/host/linux-x86/usr/share即可:     USER-NAMEMACHINE-NAME:/Android$ cp /Android/prebuilt/common/pc-bios /Android/out/host/linux-x86

27、/usr/share    問題二:找不到ddmlib-tests.jar、 ninepath-tests.jar 、common-tests.jar 和sdkuilib-tests.jar文件    在/Android/out/host/linux-x86/framework這個目錄下,可以找到以下幾個文件common.jar、ddmlib.jar、ninepatch.jar、sdkuilib.jar這四個文件,然后將它們分別復(fù)制一份,并重命名,命名的原則很簡單,就是在原有的名字后面跟上tests即可。   &#

28、160;五. 安裝編譯好的Android鏡像到模擬器上。    1. 設(shè)置環(huán)境變量:    USER-NAMEMACHINE-NAME:/Android$ export PATH=$PATH:/Android/out/host/linux-x86/bin     USER-NAMEMACHINE-NAME:/Android$ export ANDROID_PRODUCT_OUT=/Android/out/target/product/generic   &

29、#160;其中,/Android/out/host/linux-x86/bin有我們要執(zhí)行的emulator命令,而/Android/out/target/product/generic是Android鏡像存放目錄,下面執(zhí)行emulator命令時會用到。    2. 運行模擬器。    USER-NAMEMACHINE-NAME:/Android$ emulator    模擬器運行需要四個文件,分別是Linux Kernel鏡像zImage和Android鏡像文件system.img、user

30、data.img和ramdisk.img。執(zhí)行emulator命令時,如果不帶任何參數(shù),則Linux Kernel鏡像默認(rèn)使用/Android/prebuilt/android-arm/kernel目錄下的kernel-qemu文件,而Android鏡像文件則默認(rèn)使用ANDROID_PRODUCT_OUT目錄下的system.img、userdata.img和ramdisk.img,也就是我們剛剛編譯出來的鏡像問題。    當(dāng)然,我們也可以以指定的鏡像文件來運行模擬器,即運行emulator時,即:    USER-NAMEMACHI

31、NE-NAME:/Android$ emulator -kernel ./prebuilt/android-arm/kernel/kernel-qemu -sysdir ./out/target/product/generic -system system.img -data userdata.img -ramdisk ramdisk.img    到這里,我們就可以在模擬器上運行我們自己編譯的Android鏡像文件了,是不是很酷呢?但是注意,這里說的Android鏡像文件,只是包括system.img、userdata.img和ramdisk.img這

32、三個文件,而Linux Kernel鏡像用的是Android為我們預(yù)編譯好的kernel-qemu鏡像。那么,有沒有辦法使用我們自己編譯的Linux Kernel鏡像呢?答案上肯定的,這樣我們就可以完全DIY自己的Android系統(tǒng)了!我將在下一篇文章描述如果編譯自己的Linux Kernel鏡像,敬請期待 在Ubuntu上下載、編譯和安裝Android最新內(nèi)核源代碼(Linux Kernel)分類: Android2011-06-23 22:53 3612人閱讀 評論(58) 收藏 舉報     

33、60;在前一篇文章提到,從源代碼樹下載下來的最新Android源代碼,是不包括內(nèi)核代碼的,也就是Android源代碼工程默認(rèn)不包含Linux Kernel代碼,而是使用預(yù)先編譯好的內(nèi)核,也就是prebuilt/android-arm/kernel/kernel-qemu文件。那么,如何才能DIY自己的內(nèi)核呢?這篇文章一一道來。      一. 首選,參照前一篇在Ubuntu上下載、編譯和安裝Android最新源代碼準(zhǔn)備好Android源代碼目錄。      二. 下載Linux Kernel for Android

34、源代碼。      1. 使用GIT工具下載,執(zhí)行以下命令:      USER-NAMEMACHINE-NAME:/Android$ mkdir kernel      USER-NAMEMACHINE-NAME:/Android$ cd kernel      USER-NAMEMACHINE-NAME:/Android/kernel$       同樣是經(jīng)過漫長

35、的等待后,在kernel目錄下有一個common目錄,Linux內(nèi)核代碼就在這里了。      2. 下載完成后,可以查看下載的內(nèi)核代碼版本:     USER-NAMEMACHINE-NAME:/Android/kernel$ cd  common      USER-NAMEMACHINE-NAME:/Android/kernel/common$ git  branch      3.

36、0;下載完Android的Linux內(nèi)核代碼后,會發(fā)現(xiàn)在arch/arm/configs下沒有模擬器要使用的硬件配置文件goldfish_defconfig,而這個配置文件是編譯內(nèi)核代碼時需要用到的,因此,需要checkout goldfish版本:     USER-NAMEMACHINE-NAME:/Android/kernel/common$ git branch -a      選擇:      下載完畢后,就能在arch/arm/configs下看到gol

37、dfish_defconfig這個文件了。     三. 編譯內(nèi)核代碼。     1. 導(dǎo)出交叉編譯工具目錄到$PATH環(huán)境變量中去:       USER-NAMEMACHINE-NAME:/Android/kernel/common$      2. 修改common目錄下的Makefile文件的以下兩行為:      # ARCH ?= (SUBARCH)    

38、;  # CROSS_COMPILE?=       ARCH ?= arm  #體系結(jié)構(gòu)為arm      CROSS_COMPILE     ?= arm-eabi- #交叉編譯工具鏈前綴,參考目錄       3. 開始編譯:      USER-NAMEMACHINE-NAME:/Android/kernel/common$ ma

39、ke goldfish_defconfig      USER-NAMEMACHINE-NAME:/Android/kernel/common$ make     編譯成功后,可看到下面兩行:      OBJCOPY arch/arm/boot/zImage      Kernel: arch/arm/boot/zImage is ready      在執(zhí)行make命令前,你也可以執(zhí)行make

40、 menuconfig先配置一下編譯選項。     四. 在模擬器中運行編譯好的內(nèi)核。     1. 在啟動模擬器之前,先設(shè)置模擬器的目錄到環(huán)境變量$PATH中去:     USER-NAMEMACHINE-NAME:/Android$ export PATH=$PATH:/Android/out/host/linux-x86/bin      2. 設(shè)置ANDROID_PRODUCT_OUT環(huán)境變量:     &#

41、160;USER-NAMEMACHINE-NAME:/Android$ export ANDROID_PRODUCT_OUT=/Android/out/target/product/generic      3. 在后臺中指定內(nèi)核文件啟動模擬器:      USER-NAMEMACHINE-NAME:/Android$  emulator -kernel ./kernel/common/arch/arm/boot/zImage &     

42、0;4. 用adb工具連接模擬器,查看內(nèi)核版本信息,看看模擬器上跑的內(nèi)核是不是我們剛才編譯出來的內(nèi)核:      USER-NAMEMACHINE-NAME:/Android$ adb shell      這時候如果是第一次運行 adb shell命令,會看到以下輸出,不用管它,再運行一次adb shell命令就可以了。      * daemon not running. start it now on port 5037 *     

43、60;* daemon started successfully *      error: device offline      切換到proc目錄:      rootandroid:/ # cd proc      rootandroid:/proc # cat version      Linux version 2.6.29-gb0d93fb-dirty (luoubuntu-11-0

44、4) (gcc version 4.4.3 (GCC) ) #1 Fri Jun 3 23:17:24 HKT 2011    從機(jī)器名luoubuntu-11-04和日期1 Fri Jun 3 23:17:24 HKT 2011可以看出,模擬器使用的內(nèi)核即為剛剛編譯出來的內(nèi)核。 如何單獨編譯Android源代碼中的模塊分類: Android2011-06-24 22:07 2223人閱讀 評論(6) 收藏 舉報      第一次下載好Android源代碼工程后,我

45、們通常是在Android源代碼工程目錄下執(zhí)行make命令,經(jīng)過漫長的等待之后,就可以得到Android系統(tǒng)鏡像system.img了。以后如果我們修改了Android源代碼中的某個模塊或者在Android源代碼工程新增一個自己的模塊,是不是還是執(zhí)行make命令呢?答案是否定的,Google為我們準(zhǔn)備了另外的命令來支持編譯單獨的模塊,以及重新打包system.img的命令。在繼續(xù)學(xué)習(xí)Android源代碼之前,就讓我們先來看看這個命令吧。      一. 首先在Android源代碼目錄下的build目錄下,有個腳本文件envsetup.sh,執(zhí)行這個腳本文件

46、后,就可以獲得一些有用的工具:      USER-NAMEMACHINE-NAME:/Android$ .  ./build/envsetup.sh      注意,這是一個source命令,執(zhí)行之后,就會有一些額外的命令可以使用:      - croot: Changes directory to the top of the tree.      - m: Makes from the top of the

47、tree.      - mm: Builds all of the modules in the current directory.      - mmm: Builds all of the modules in the supplied directories.      - cgrep: Greps on all local C/C+ files.      - jgrep: Greps on all local Java f

48、iles.      - resgrep: Greps on all local res/*.xml files.      - godir: Go to the directory containing a file.      這些命令的具體用法,可以在命令的后面加-help來查看,這里我們只關(guān)注mmm命令,也就是可以用它來編譯指定目錄的所有模塊,通常這個目錄只包含一個模塊。      二. 使用mmm命令來編譯指定的模塊,例如Em

49、ail應(yīng)用程序:      USER-NAMEMACHINE-NAME:/Android$ mmm packages/apps/Email/      編譯完成之后,就可以在out/target/product/generic/system/app目錄下看到Email.apk文件了。Android系統(tǒng)自帶的App都放在這具目錄下。另外,Android系統(tǒng)的一些可執(zhí)行文件,例如C編譯的可執(zhí)行文件,放在out/target/product/generic/system/bin目錄下,動態(tài)鏈接庫文件放在out/

50、target/product/generic/system/lib目錄下,out/target/product/generic/system/lib/hw目錄存放的是硬件抽象層(HAL)接口文件,后面的文章里面,我們會陸續(xù)提及到,敬請關(guān)注。      三. 編譯好模塊后,還要重新打包一下system.img文件,這樣我們把system.img運行在模擬器上時,就可以看到我們的程序了。      USER-NAMEMACHINE-NAME:/Android$ make snod   &#

51、160;  四. 參照Ubuntu上下載、編譯和安裝Android最新源代碼一文介紹的方法運行模擬器:      USER-NAMEMACHINE-NAME:/Android$ emulator      這樣一切就搞定了。Android硬件抽象層(HAL)概要介紹和學(xué)習(xí)計劃分類: Android2011-06-25 13:03 3276人閱讀 評論(10) 收藏 舉報      Android的硬件抽象層

52、,簡單來說,就是對Linux內(nèi)核驅(qū)動程序的封裝,向上提供接口,屏蔽低層的實現(xiàn)細(xì)節(jié)。也就是說,把對硬件的支持分成了兩層,一層放在用戶空間(User Space),一層放在內(nèi)核空間(Kernel Space),其中,硬件抽象層運行在用戶空間,而Linux內(nèi)核驅(qū)動程序運行在內(nèi)核空間。為什么要這樣安排呢?把硬件抽象層和內(nèi)核驅(qū)動整合在一起放在內(nèi)核空間不可行嗎?從技術(shù)實現(xiàn)的角度來看,是可以的,然而從商業(yè)的角度來看,把對硬件的支持邏輯都放在內(nèi)核空間,可能會損害廠家的利益。我們知道,Linux內(nèi)核源代碼版權(quán)遵循GNU License,而Android源代碼版權(quán)遵循Apache License,前者在發(fā)布產(chǎn)品時

53、,必須公布源代碼,而后者無須發(fā)布源代碼。如果把對硬件支持的所有代碼都放在Linux驅(qū)動層,那就意味著發(fā)布時要公開驅(qū)動程序的源代碼,而公開源代碼就意味著把硬件的相關(guān)參數(shù)和實現(xiàn)都公開了,在手機(jī)市場競爭激烈的今天,這對廠家來說,損害是非常大的。因此,Android才會想到把對硬件的支持分成硬件抽象層和內(nèi)核驅(qū)動層,內(nèi)核驅(qū)動層只提供簡單的訪問硬件邏輯,例如讀寫硬件寄存器的通道,至于從硬件中讀到了什么值或者寫了什么值到硬件中的邏輯,都放在硬件抽象層中去了,這樣就可以把商業(yè)秘密隱藏起來了。也正是由于這個分層的原因,Android被踢出了Linux內(nèi)核主線代碼樹中。大家想想,Android放在內(nèi)核空間的驅(qū)動程

54、序?qū)τ布闹С质遣煌暾?,把Linux內(nèi)核移植到別的機(jī)器上去時,由于缺乏硬件抽象層的支持,硬件就完全不能用了,這也是為什么說Android是開放系統(tǒng)而不是開源系統(tǒng)的原因。     撇開這些爭論,學(xué)習(xí)Android硬件抽象層,對理解整個Android整個系統(tǒng),都是極其有用的,因為它從下到上涉及到了Android系統(tǒng)的硬件驅(qū)動層、硬件抽象層、運行時庫和應(yīng)用程序框架層等等,下面這個圖闡述了硬件抽象層在Android系統(tǒng)中的位置,以及它和其它層的關(guān)系:     在學(xué)習(xí)Android硬件抽象層的過程中,我們將會學(xué)習(xí)如何在內(nèi)核空間編寫硬件驅(qū)動程序

55、、如何在硬件抽象層中添加接口支持訪問硬件、如何在系統(tǒng)啟動時提供硬件訪問服務(wù)以及 如何編寫JNI使得可以通過Java接口來訪問硬件,而作為中間的一個小插曲,我們還將學(xué)習(xí)一下如何在Android系統(tǒng)中添加一個C可執(zhí)行程序來訪問硬件驅(qū)動程序。由于這是一個系統(tǒng)的學(xué)習(xí)過程,筆者將分成六篇文章來描述每一個學(xué)習(xí)過程,包括:     一. 在Android內(nèi)核源代碼工程中編寫硬件驅(qū)動程序。     二. 在Android系統(tǒng)中增加C可執(zhí)行程序來訪問硬件驅(qū)動程序。     三. 在Androi

56、d硬件抽象層增加接口模塊訪問硬件驅(qū)動程序。     四. 在Android系統(tǒng)中編寫JNI方法在應(yīng)用程序框架層提供Java接口訪問硬件。     五. 在Android系統(tǒng)的應(yīng)用程序框架層增加硬件服務(wù)接口。     六. 在Android系統(tǒng)中編寫APP通過應(yīng)用程序框架層訪問硬件服務(wù)。     學(xué)習(xí)完這六篇文章,相信大家對Android系統(tǒng)就會有一個更深刻的認(rèn)識了,敬請關(guān)注。 在Ubuntu上為Android系統(tǒng)編寫Linux內(nèi)核驅(qū)動程

57、序分類: Android2011-06-26 12:10 3450人閱讀 評論(33) 收藏 舉報        在智能手機(jī)時代,每個品牌的手機(jī)都有自己的個性特點。正是依靠這種與眾不同的個性來吸引用戶,營造品牌凝聚力和用戶忠城度,典型的代表非iphone莫屬了。據(jù)統(tǒng)計,截止2011年5月,AppStore的應(yīng)用軟件數(shù)量達(dá)381062個,位居第一,而Android Market的應(yīng)用軟件數(shù)量達(dá)294738,緊隨AppStore后面,并有望在8月份越過AppStore。隨著Android系統(tǒng)逐步擴(kuò)大

58、市場占有率,終端設(shè)備的多樣性亟需更多的移動開發(fā)人員的參與。據(jù)業(yè)內(nèi)統(tǒng)計,Android研發(fā)人才缺口至少30萬。目前,對Android人才需求一類是偏向硬件驅(qū)動的Android人才需求,一類是偏向軟件應(yīng)用的Android人才需求??偟膩碚f,對有志于從事Android硬件驅(qū)動的開發(fā)工程師來說,現(xiàn)在是一個大展拳腳的機(jī)會。那么,就讓我們一起來看看如何為Android系統(tǒng)編寫內(nèi)核驅(qū)動程序吧。        這里,我們不會為真實的硬件設(shè)備編寫內(nèi)核驅(qū)動程序。為了方便描述為Android系統(tǒng)編寫內(nèi)核驅(qū)動程序的過程,我們使用一個虛擬的硬件設(shè)備,這個設(shè)備只有一個4字

59、節(jié)的寄存器,它可讀可寫。想起我們第一次學(xué)習(xí)程序語言時,都喜歡用“Hello, World”作為例子,這里,我們就把這個虛擬的設(shè)備命名為“hello”,而這個內(nèi)核驅(qū)動程序也命名為hello驅(qū)動程序。其實,Android內(nèi)核驅(qū)動程序和一般Linux內(nèi)核驅(qū)動程序的編寫方法是一樣的,都是以Linux模塊的形式實現(xiàn)的,具體可參考前面Android學(xué)習(xí)啟動篇一文中提到的Linux Device Drivers一書。不過,這里我們還是從Android系統(tǒng)的角度來描述Android內(nèi)核驅(qū)動程序的編寫和編譯過程。       一. 參照前面兩篇文章在Ubuntu上下載、編

60、譯和安裝Android最新源代碼和在Ubuntu上下載、編譯和安裝Android最新內(nèi)核源代碼(Linux Kernel)準(zhǔn)備好Android內(nèi)核驅(qū)動程序開發(fā)環(huán)境。       二. 進(jìn)入到kernel/common/drivers目錄,新建hello目錄:       USER-NAMEMACHINE-NAME:/Android$ cd kernel/common/drivers       USER-NAMEMACHINE-NAME:/Android/kerne

61、l/common/drivers$ mkdir hello       三. 在hello目錄中增加hello.h文件:view plain1. #ifndef _HELLO_ANDROID_H_  2. #define _HELLO_ANDROID_H_  3.   4. #include <linux/cdev.h>  5. #include <linux/semaphore.h>  6.

62、   7. #define HELLO_DEVICE_NODE_NAME  "hello"  8. #define HELLO_DEVICE_FILE_NAME  "hello"  9. #define HELLO_DEVICE_PROC_NAME  "hello"  10. #define HELLO_DEVICE_CLASS_NAME &quo

63、t;hello"  11.   12. struct hello_android_dev   13.     int val;  14.     struct semaphore sem;  15.     struct cdev dev;  16. ;  1

64、7.   18. #endif  這個頭文件定義了一些字符串常量宏,在后面我們要用到。此外,還定義了一個字符設(shè)備結(jié)構(gòu)體hello_android_dev,這個就是我們虛擬的硬件設(shè)備了,val成員變量就代表設(shè)備里面的寄存器,它的類型為int,sem成員變量是一個信號量,是用同步訪問寄存器val的,dev成員變量是一個內(nèi)嵌的字符設(shè)備,這個Linux驅(qū)動程序自定義字符設(shè)備結(jié)構(gòu)體的標(biāo)準(zhǔn)方法。四.在hello目錄中增加hello.c文件,這是驅(qū)動程序的實現(xiàn)部分。驅(qū)動程序的功能主要是向上層提供訪問設(shè)備的寄存器的值,包括讀和寫。這里,提供了三種訪問設(shè)備寄存器的方法,一

65、是通過proc文件系統(tǒng)來訪問,二是通過傳統(tǒng)的設(shè)備文件的方法來訪問,三是通過devfs文件系統(tǒng)來訪問。下面分段描述該驅(qū)動程序的實現(xiàn)。首先是包含必要的頭文件和定義三種訪問設(shè)備的方法:view plain1. #include <linux/init.h>  2. #include <linux/module.h>  3. #include <linux/types.h>  4. #include <linux/fs.h>  5. #

66、include <linux/proc_fs.h>  6. #include <linux/device.h>  7. #include <asm/uaccess.h>  8.   9. #include "hello.h"  10.   11. /*主設(shè)備和從設(shè)備號變量*/  12. static int hello_major 

67、= 0;  13. static int hello_minor = 0;  14.   15. /*設(shè)備類別和設(shè)備變量*/  16. static struct class* hello_class = NULL;  17. static struct hello_android_dev* hello_dev = NULL;  

68、;18.   19. /*傳統(tǒng)的設(shè)備文件操作方法*/  20. static int hello_open(struct inode* inode, struct file* filp);  21. static int hello_release(struct inode* inode, struct file* filp);  22. static ssize_t

69、 hello_read(struct file* filp, char _user *buf, size_t count, loff_t* f_pos);  23. static ssize_t hello_write(struct file* filp, const char _user *buf, size_t count, loff_t* f_pos)

70、;  24.   25. /*設(shè)備文件操作方法表*/  26. static struct file_operations hello_fops =   27.     .owner = THIS_MODULE,  28.     .open = hello_open,  29.   &#

71、160; .release = hello_release,  30.     .read = hello_read,  31.     .write = hello_write,   32. ;  33.   34. /*訪問設(shè)置屬性方法*/  35. static ssize_t hello_v

72、al_show(struct device* dev, struct device_attribute* attr,  char* buf);  36. static ssize_t hello_val_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count);

73、  37.   38. /*定義設(shè)備屬性*/  39. static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, hello_val_show, hello_val_store);          定義傳統(tǒng)的設(shè)備文件訪問方法,主要是定義hello_open、hello_release、hello_read和hello_write這四個打開、釋放、讀和寫設(shè)備文件的方法:view

74、plain1. /*打開設(shè)備方法*/  2. static int hello_open(struct inode* inode, struct file* filp)   3.     struct hello_android_dev* dev;          4.     

75、;  5.     /*將自定義設(shè)備結(jié)構(gòu)體保存在文件指針的私有數(shù)據(jù)域中,以便訪問設(shè)備時拿來用*/  6.     dev = container_of(inode->i_cdev, struct hello_android_dev, dev);  7.     filp->private_data = dev;  8

76、.       9.     return 0;  10.   11.   12. /*設(shè)備文件釋放時調(diào)用,空實現(xiàn)*/  13. static int hello_release(struct inode* inode, struct file* filp)   14.    &

77、#160;return 0;  15.   16.   17. /*讀取設(shè)備的寄存器val的值*/  18. static ssize_t hello_read(struct file* filp, char _user *buf, size_t count, loff_t* f_pos)   19.     ssize_t&#

78、160;err = 0;  20.     struct hello_android_dev* dev = filp->private_data;          21.   22.     /*同步訪問*/  23.     if(down_inte

79、rruptible(&(dev->sem)   24.         return -ERESTARTSYS;  25.       26.   27.     if(count < sizeof(dev->val)   28.   

80、0;     goto out;  29.               30.   31.     /*將寄存器val的值拷貝到用戶提供的緩沖區(qū)*/  32.     if(copy_to_user(buf, &(dev->val),&

81、#160;sizeof(dev->val)   33.         err = -EFAULT;  34.         goto out;  35.       36.   37.     err 

82、;= sizeof(dev->val);  38.   39. out:  40.     up(&(dev->sem);  41.     return err;  42.   43.   44. /*寫設(shè)備的寄存器值val*/  45. static ssize_t hello_write(st

83、ruct file* filp, const char _user *buf, size_t count, loff_t* f_pos)   46.     struct hello_android_dev* dev = filp->private_data;  47.     ssize_t err = 0;         

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論