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