已經有一些的文章介紹Android內核了,本系列篇將從Linux內核的角度來分析Android的內核,希望給初學者提夠有用的信息。本章將簡單的介紹 Android內核的全貌,起到一個拋磚引玉的作用。從下一篇開始將詳細介紹每一個Android內核驅動程序及其作用。
Android內核是基于Linux 2.6內核的(目前最新開發(fā)版本是2.6.31),它是一個增強內核版本,除了修改部分Bug外,它提供了用于支持Android平臺的設備驅動,其核心驅動主要包括:
Android Binder ,基于OpenBinder框架的一個驅動,用于提供Android平臺的進程間通訊(IPC,inter-process communication)。
源代碼位于drivers/staging/android/binder.c
Android電源管理(PM) ,一個基于標準Linux電源管理系統(tǒng)的輕量級的Android電源管理驅動,針對嵌入式設備做了很多優(yōu)化。
源代碼位于kernel/power/earlysuspend.c
kernel/power/consoleearlysuspend.c
kernel/power/fbearlysuspend.c
kernel/power/wakelock.c
kernel/power/userwakelock.c
低內存管理器(Low Memory Killer) ,相對于Linux標準OOM(Out Of Memory)機制更加靈活,它可以根據(jù)需要殺死進程來釋放需要的內存。
源代碼位于drivers/staging/android/lowmemorykiller.c
匿名共享內存(ashmem) ,為進程間提供大塊共享內存,同時為內核提供回收和管理這個內存的機制。
源代碼位于mm/ashmem.c
Android PMEM(Physical) ,PMEM用于向用戶空間提供連續(xù)的物理內存區(qū)域,DSP和某些設備只能工作在連續(xù)的物理內存上。
源代碼位于drivers/misc/pmem.c
Android Logger ,一個輕量級的日志設備,用于抓取Android系統(tǒng)的各種日志。
源代碼位于drivers/staging/android/logger.c
Android Alarm ,提供了一個定時器用于把設備從睡眠狀態(tài)喚醒,同時它也提供了一個即使在設備睡眠時也會運行的時鐘基準,
源代碼位于drivers/rtc/alarm.c
USB Gadget驅動 ,一個基于標準Linux USB gadget驅動框架的設備驅動,Android的USB驅動是基于gaeget框架的,
源代碼位于drivers/usb/gadget/
Android Ram Console ,為了提供調試功能,Android允許將調試日志信息寫入一個被稱為RAM Console的設備里,它是一個基于RAM的Buffer。
源代碼位于drivers/staging/android/ram_console.c。
Android timed device ,提供了對設備進行定時控制功能,目前支持vibrator和LED設備。
源代碼位于drivers/staging/android/timed_output.c(timed_gpio.c)。
Yaffs2文件系統(tǒng) ,Android 采用Yaffs2作為MTD nand flash文件系統(tǒng),源代碼位于fs/yaffs2/目錄下。Yaffs2是一個快速穩(wěn)定的應用于NAND和NOR Flash的跨平臺的嵌入式設備文件系統(tǒng),同其他Flash文件系統(tǒng)相比,Yaffs2使用更小的內存來保存他的運行狀態(tài),因此它占用內存小;Yaffs2的垃圾回收非常簡單而且快速,因此能達到更好的性能;Yaffs2在大容量的NAND Flash上性能表現(xiàn)尤為明顯,非常適合大容量的Flash存儲。
Android內核添加或修改的文件很多,下面的列表描述了Android Emulator內核的文件:
drivers/misc/kernel_debugger.c
drivers/misc/pmem.c
drivers/misc/qemutrace/qemu_trace_sysfs.c
drivers/misc/qemutrace/qemu_trace.c
drivers/misc/qemutrace/qemu_trace.h
drivers/misc/uid_stat.c
drivers/staging/android/lowmemorykiller.c
drivers/staging/android/logger.c
drivers/staging/android/timed_output.h
drivers/staging/android/ram_console.c
drivers/staging/android/timed_gpio.c
drivers/staging/android/logger.h
drivers/staging/android/binder.h
drivers/staging/android/binder.c
drivers/staging/android/timed_output.c
drivers/staging/android/timed_gpio.h
drivers/rtc/alarm.c
drivers/rtc/rtc-goldfish.c
drivers/net/pppolac.c
drivers/net/ppp_mppe.c
drivers/net/pppopns.c
drivers/video/goldfishfb.c
drivers/switch/switch_class.c
drivers/switch/switch_gpio.c
drivers/char/dcc_tty.c
drivers/char/goldfish_tty.c
drivers/watchdog/i6300esb.c
drivers/input/misc/gpio_event.c
drivers/input/misc/gpio_input.c
drivers/input/misc/gpio_output.c
drivers/input/misc/keychord.c
drivers/input/misc/gpio_axis.c
drivers/input/misc/gpio_matrix.c
drivers/input/keyreset.c
drivers/input/keyboard/goldfish_events.c
drivers/input/touchscreen/synaptics_i2c_rmi.c
drivers/usb/gadget/android.c
drivers/usb/gadget/f_adb.h
drivers/usb/gadget/f_mass_storage.h
drivers/usb/gadget/f_adb.c
drivers/usb/gadget/f_mass_storage.c
drivers/mmc/host/goldfish.c
drivers/power/goldfish_battery.c
drivers/leds/ledtrig-sleep.c
drivers/mtd/devices/goldfish_nand_reg.h
drivers/mtd/devices/goldfish_nand.c
kernel/power/earlysuspend.c
kernel/power/consoleearlysuspend.c
kernel/power/fbearlysuspend.c
kernel/power/wakelock.c
kernel/power/userwakelock.c
kernel/cpuset.c
kernel/cgroup_debug.c
kernel/cgroup.c
mm/ashmem.c
include/linux/ashmem.h
include/linux/switch.h
include/linux/keychord.h
include/linux/earlysuspend.h
include/linux/android_aid.h
include/linux/uid_stat.h
include/linux/if_pppolac.h
include/linux/usb/android.h[!--empirenews.page--]
include/linux/wifi_tiwlan.h
include/linux/android_alarm.h
include/linux/keyreset.h
include/linux/synaptics_i2c_rmi.h
include/linux/android_pmem.h
include/linux/kernel_debugger.h
include/linux/gpio_event.h
include/linux/wakelock.h
include/linux/if_pppopns.h
net/ipv4/sysfs_net_ipv4.c
net/ipv4/af_inet.c
net/ipv6/af_inet6.c
net/bluetooth/af_bluetooth.c
security/commoncap.c
fs/proc/base.c
Android內核配置
Android 是基于 Linux 的 , 對于一個新的設備,我們 首先要 編譯一個支持 Android 的 Kernel ,那么如何 使 你的 Kernel Android 化呢?除了要移植前面提到的驅動之外,就是如何配置你的 Kernel 來支持 Android 平臺,這可以參考 Goldfish 的內核配置文件 - arch/arm/configs/goldfish_defconfig 。
一般來說,我們會基于一個平臺標準內核配置選項來配置 Android 內核,你可以根據(jù)具體的硬件平臺來選擇 Android 內核的配置選項,可以參考下面的 Android 內核配置列表:
一般需要支持的內核選項
ANDROID_PARANOID_NETWORK
ASHMEM
CONFIG_FB_MODE_HELPERS
CONFIG_FONT_8x16
CONFIG_FONT_8x8
CONFIG_YAFFS_SHORT_NAMES_IN_RAM
DAB
EARLYSUSPEND
FB
FB_CFB_COPYAREA
FB_CFB_FILLRECT
FB_CFB_IMAGEBLIT
FB_DEFERRED_IO
FB_TILEBLITTING
HIGH_RES_TIMERS
INOTIFY
INOTIFY_USER
INPUT_EVDEV
INPUT_GPIO
INPUT_MISC
LEDS_CLASS
LEDS_GPIO
LOCK_KERNEL
LkOGGER
LOW_MEMORY_KILLER
MISC_DEVICES
NEW_LEDS
NO_HZ
POWER_SUPPLY
PREEMPT
RAMFS
RTC_CLASS
RTC_LIB
SWITCH
SWITCH_GPIO
TMPFS
UID_STAT
UID16
USB_FUNCTION
USB_FUNCTION_ADB
USER_WAKELOCK
VIDEO_OUTPUT_CONTROL
WAKELOCK
YAFFS_AUTO_YAFFS2
YAFFS_FS
YAFFS_YAFFS1
YAFFS_YAFFS2
但是Android推薦不要支持下面兩個功能:
CONFIG_YAFFS_DISABLE_LAZY_LOAD
DNOTIFY
配置好后,就可以用Toolchain來編譯內核了。編譯內核比較簡單,以Emulator的kernel為例:
- git clone git://android.kernel.org/kernel/common.git kernel-emulator
- cd kernel-emulator
- export ARCH=arm
- export CROSS_COMPILE=arm-eabi-
- export PATH=
- make goldfish_defconfig
- make
Google對 2.6.25 內核里做了什么改動呢?
有家公司專門比較了標準內核和android 內核,發(fā)現(xiàn) google 修改了 75 個文件,增加了 88 個文件。改公司還對這些被修改的和新增的文件做了注解。
Goldfish -- 44 Files
Android模擬器運行了一個被 google 叫做 “ 金魚 " 的虛擬 CPU. 金魚運行 arm926t 指令集( arm926t 是屬于 armv5 架構);并且仿真了輸入輸出:比如鍵盤輸入和 LCD 輸出。這個模擬器其實是在 qemu 之上開發(fā)的,輸入輸出基于 libSDL.
內核里這個Goldfish 接口實現(xiàn)了這個虛擬 “ 金魚 ”CPU 的一些接口,如果想在真實設備上運行 android, 這些接口肯定要去掉的。
arm926ej的介紹見 http://www.arm.com/products/CPUs/ARM926EJ-S.html
YAFFS2 -- 35 Files
不同于PC 機,文件是存儲在硬盤上的;手機使用 FLASH 作為存儲介質。 HTC 的 G1 使用 NANDFLASH—— 這中存儲目前已經相當普及了 , 而且種類也頗多, (SLC,MLC 等等),存儲密度也越來越高(已經出現(xiàn)幾十 G 大小的 NANDFLASH) ,價格也越來越低。
YAFFS2是專門用在 FLASH 上的文件系統(tǒng), “YAFFS2” 是 "Yet Another Flash File System, 2nd edition" 的縮寫。 YAFFS2 為 Linux 內核提供了一個高效訪問 NANDFLASH 的接口。但是 NANDFLASH 的支持并不包含在標準的 2.6.25 內核中,所以 Google 在其中添加了對 NANDFLASH 的支持。
藍牙 -- 10 files
在藍牙通訊協(xié)議棧里Google 修改了 10 個文件。這些改動解決了一些跟藍牙耳機相關的明顯的 bug ,以及一些藍牙調試和訪問控制相關的函數(shù)。
調度器 -- 5 files
Android內核還修改了進程調度和時鐘相關策略,這個改動就比較深入了。其目的和效果估計在一段時間后才能找到。
為android 新增的功能 -- 28 files
除了修正一些bug 以及其他的改動, android 還增加了一些新的 “ 子系統(tǒng) ” ,這些系統(tǒng)都比較重要。
IPC Binder
IPC Binder是一種 IPC( 進程間通信)機制。它是的進程能夠為其他進程提供服務 —— 還是通過標準的 linux 系統(tǒng)調用 api 。 IPC Binder 的概念起源于一家叫做 “Be.Inc" 的公司,在 Google 之前就已經被然后被用到 Palm 軟件里去了。
Low Memory Killer
其實內核里已經有一個類似的功能, 叫做"oom killer", 就是 out of memory killer, 當內存不夠的時候,改策略會試圖結束一個進程。不知道為什么 Google 重新實現(xiàn)了這個策略。
Ashmem
Ashmem,全程 Anonymous SHared MEMory, 翻譯成中文就是匿名共享內存。這個功能使得進程間能夠共享大塊的內存。比如說,系統(tǒng)可以使用 Ashmem 保存一些圖標,多個應用程序可以訪問這個共享內存來獲取圖標。 Ashmem 為內核提供了一種回收這些使用完的共享內存塊的辦法 , 如果一個進程試圖訪問這些已經被回收的內存塊,它將會得到錯誤的返回值,以便它重新進行內存塊分配和數(shù)據(jù)初始化。[!--empirenews.page--]
RAM Console and Log Device
為了調試方便,Android 添加了一個功能,使得調試信息可以輸入到一個內存塊中。此外, Android 添加了一個獨立的日志模塊,這樣用戶空間的進程能夠讀寫日志消息,調試打印信息等。
Android Debug Bridge
嵌入式設備的調試的確比較麻煩。為了便于調試,google 設計了這個調試工具,可以叫做 "ADB" ,使用 USB 作為連接方式 ,ADB 可以看作是鏈接 android 的設備和 PC 機的一套協(xié)議。
Android 還添加了其他的東西,比如 real-time clock, switch , timed GPIO 。
Power Management -- 5 files
電源管理對于移動設備來說相當重要,也是最復雜,開發(fā)難度最高的一個功能。Google 添加了一個新的電源管理系統(tǒng),并沒有原先 apm,dpm 等。
其他修改 -- 36 files
除了上述改動之外,還有一些小改動,比如新增的額外的調試功能, 鍵盤背光控制,TCP 網(wǎng)絡管理等等,共涉及 36 個文件。
根據(jù)上述,google 對標準的內核做了很大的改動。相比其他的項目,比如 Nokia N810,Openmoko 等項目中,內核的改動僅僅是增加了某個平臺的支持。所以移植最快也是最可能的辦法是在 google 使用的 kernel 上增加平臺支持。
也有一些開發(fā)人員將google 對 2.6.25 內核的改動做成補丁,直接打在自己開發(fā)的內核上 —— 當然,自己的內核也應該是 2.6.25 ,否則會出問題。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/guoshaobei/archive/2010/08/21/5827399.aspx
Android是基于Linux,而Linux Kernel的目錄結果如下:
瀏覽內核代碼之前,有必要知道內核源碼的整體分布情況,按照慣例,內核代碼安裝在/usr/src/linux目錄下,該目錄下的每一個子目錄都代表了一個特定的內核功能性子集,下面針對2.6.23版本進行簡單描述。
(1)Documentation。
這個目錄下面沒有內核代碼,只有很多質量參差不齊的文檔,但往往能夠給我們提供很多的幫助。
(2)arch。
所有與體系結構相關的代碼都在這個目錄以及include/asm-*/目錄中,Linux支持的每種體系結構在arch目錄下都有對應的子目錄,而在每個體系結構特有的子目錄下又至少包含3個子目錄。
kernel:存放支持體系結構特有的諸如信號量處理和SMP之類特征的實現(xiàn)。
lib:存放體系結構特有的對諸如strlen和memcpy之類的通用函數(shù)的實現(xiàn)。
mm:存放體系結構特有的內存管理程序的實現(xiàn)。
除了這3個子目錄之外,大多數(shù)體系結構在必要的情況下還有一個boot子目錄,包含了在這種硬件平臺上啟動內核所使用的部分或全部平臺特有代碼。
此外,大部分體系結構所特有的子目錄還根據(jù)需要包含了供附加特性使用的其他子目錄。比如,i386目錄包含一個math-emu子目錄,其中包括了在缺少數(shù)學協(xié)處理器(FPU)的CPU上運行模擬FPU的代碼。
(3)drivers。
這個目錄是內核中最龐大的一個目錄,顯卡、網(wǎng)卡、SCSI適配器、PCI總線、USB總線和其他任何Linux支持的外圍設備或總線的驅動程序都可以在這里找到。
(4)fs。
虛擬文件系統(tǒng)(VFS,Virtual File System)的代碼,和各個不同文件系統(tǒng)的代碼都在這個目錄中。Linux支持的所有文件系統(tǒng)在fs目錄下面都有一個對應的子目錄。比如ext2文件系統(tǒng)對應的是fs/ext2目錄。
一個文件系統(tǒng)是存儲設備和需要訪問存儲設備的進程之間的媒介。存儲設備可能是本地的物理上可訪問的,比如硬盤或CD-ROM驅動器,它們分別使用ext2/ext3和isofs文件系統(tǒng);也可能是通過網(wǎng)絡訪問的,使用NFS文件系統(tǒng)。
還有一些虛擬文件系統(tǒng),比如proc,它以一個標準文件系統(tǒng)出現(xiàn),然而,它其中的文件只存在于內存中,并不占用磁盤空間。
(5)include。
這個目錄包含了內核中大部分的頭文件,它們按照下面的子目錄進行分組。
include/asm-*/,這樣的子目錄有多個,每一個都對應著一個arch的子目錄,比如include/asm-alpha、include/asm-arm、include/asm-i386等。每個子目錄中的文件都定義了支持給定體系結構所必須的預處理器宏和內聯(lián)函數(shù),這些內聯(lián)函數(shù)多數(shù)都是全部或部分使用匯編語言實現(xiàn)的。
編譯內核時,系統(tǒng)會建立一個從include/asm目錄到目標體系結構特有的目錄的符號鏈接。比如對于arm平臺,就是include/asm-arm到include/asm的符號鏈接。因此,體系結構無關部分的內核代碼可以使用如下形式包含體系相關部分的頭文件。
#include
include/linux/,與平臺無關的頭文件都在這個目錄下面,它通常會被鏈接到目錄/usr/include/linux(或者它里面的所有文件會被復制到/usr/include/linux目錄下面)。因此用戶應用程序里和內核代碼里的語句:
#include
包含的頭文件的內容是一致的。
include目錄下的其他子目錄,在此不做贅述。
(6)init。
內核的初始化代碼。包括main.c、創(chuàng)建早期用戶空間的代碼以及其他初始化代碼。
(7)ipc。
IPC,即進程間通信(interprocess communication)。它包含了共享內存、信號量以及其他形式IPC的代碼。
(8)kernel。
內核中最核心的部分,包括進程的調度(kernel/sched.c),以及進程的創(chuàng)建和撤銷(kernel/fork.c和kernel/exit.c)等,和平臺相關的另外一部分核心的代碼在arch/*/kernel目錄。
(9)lib。
庫代碼,實現(xiàn)了一個標準C庫的通用子集,包括字符串和內存操作的函數(shù)(strlen、mmcpy和其他類似的函數(shù))以及有關sprintf和atoi的系列函數(shù)。與arch/lib下的代碼不同,這里的庫代碼都是使用C編寫的,在內核新的移植版本中可以直接使用。
(10)mm。
包含了體系結構無關部分的內存管理代碼,體系相關的部分位于arch/*/mm目錄下。
(11)net。
網(wǎng)絡相關代碼,實現(xiàn)了各種常見的網(wǎng)絡協(xié)議,如TCP/IP、IPX等。
(12)scripts。
該目錄下沒有內核代碼,只包含了用來配置內核的腳本文件。當運行make menuconfig或者make xconfig之類的命令配置內核時,用戶就是和位于這個目錄下的腳本進行交互的。[!--empirenews.page--]
(13)block。
block層的實現(xiàn)。最初block層的代碼一部分位于drivers目錄,一部分位于fs目錄,從2.6.15開始,block層的核心代碼被提取出來放在了頂層的block目錄。
(14)crypto。
內核本身所用的加密API,實現(xiàn)了常用的加密和散列算法,還有一些壓縮和CRC校驗算法。
(15)security。
這個目錄包括了不同的Linux安全模型的代碼,比如NSA Security-Enhanced Linux。
(16)sound。
聲卡驅動以及其他聲音相關的代碼。
(17)usr。
實現(xiàn)了用于打包和壓縮的的cpio等。