一、驅(qū)動(dòng)
驅(qū)動(dòng)是內(nèi)核的一部分其监,作為直接訪問物理硬件的一個(gè)軟件層萌腿,用于應(yīng)用程序與物理硬件設(shè)備通信。內(nèi)核包含多種驅(qū)動(dòng)抖苦,如WIFI毁菱、USB米死、Audio、藍(lán)牙贮庞、相機(jī)峦筒、顯示驅(qū)動(dòng)。
二窗慎、設(shè)備
(1)設(shè)備驅(qū)動(dòng)程序三類:字符設(shè)備驅(qū)動(dòng)程序物喷、塊設(shè)備驅(qū)動(dòng)程序、網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序遮斥;
(2)對(duì)應(yīng)Linux三類設(shè)備:字符設(shè)備峦失、塊設(shè)備、網(wǎng)絡(luò)設(shè)備术吗;
(3)常見字符設(shè)備:鼠標(biāo)尉辑、鍵盤、串口较屿、控制臺(tái)等隧魄;
(4)常見塊設(shè)備:各種硬盤、flash磁盤吝镣、RAM磁盤等堤器;
(5)網(wǎng)絡(luò)設(shè)備(網(wǎng)絡(luò)接口):eth0、eth1末贾,注:網(wǎng)絡(luò)設(shè)備沒有設(shè)備節(jié)點(diǎn)闸溃,應(yīng)用程序通過Socket訪問網(wǎng)絡(luò)設(shè)備。由于網(wǎng)絡(luò)設(shè)備面向報(bào)文拱撵,較難實(shí)現(xiàn)相關(guān)read辉川、write等文件讀寫函數(shù),所以驅(qū)動(dòng)的實(shí)現(xiàn)也與字符設(shè)備和塊設(shè)備不同拴测。
字符設(shè)備:字符設(shè)備是能夠像字節(jié)流(類似文件)一樣被訪問的設(shè)備乓旗,由字符設(shè)備驅(qū)動(dòng)程序來實(shí)現(xiàn)這種特性。字符設(shè)備驅(qū)動(dòng)程序通常至少要實(shí)現(xiàn)open集索、close屿愚、read、write系統(tǒng)調(diào)用务荆。字符設(shè)備通過文件系統(tǒng)節(jié)點(diǎn)來訪問妆距,這些設(shè)備文件和普通文件之間的唯一差別在于對(duì)普通文件的訪問可以前后移動(dòng)訪問位置,而大多數(shù)字符設(shè)備是一個(gè)只能順序訪問的數(shù)據(jù)通道函匕。一個(gè)字符設(shè)備是一種字節(jié)流設(shè)備娱据,對(duì)設(shè)備的存取只能按順序按字節(jié)存取而不能隨機(jī)訪問,字符設(shè)備沒有請(qǐng)求緩沖區(qū)盅惜,所有的訪問請(qǐng)求都是按順序執(zhí)行的中剩。但目前一些高級(jí)字符設(shè)備也可以從指定位置一次讀取一塊數(shù)據(jù)忌穿。
塊設(shè)備:塊設(shè)備也是通過文件系統(tǒng)節(jié)點(diǎn)(設(shè)備節(jié)點(diǎn))來訪問。塊設(shè)備上能夠容納文件系統(tǒng)结啼。在大多數(shù)unix系統(tǒng)中掠剑,進(jìn)行I/O操作時(shí)塊設(shè)備每次只能傳輸一個(gè)或多個(gè)完整的塊,而每塊包含512字節(jié)(或更2的更高次冪字節(jié)的數(shù)據(jù))郊愧。linux可以讓應(yīng)用程序像字符設(shè)備一樣讀寫塊設(shè)備澡腾,允許一次傳遞任意多字節(jié)的數(shù)據(jù)。因而糕珊,塊設(shè)備和字符設(shè)備的區(qū)別僅僅在于內(nèi)核內(nèi)部管理數(shù)據(jù)的方式,也就是內(nèi)核及驅(qū)動(dòng)程序之間的軟件接口毅糟,而這些不同對(duì)用戶來講是透明的红选。在內(nèi)核中,和字符驅(qū)動(dòng)程序相比姆另,塊驅(qū)動(dòng)程序具有完全不同的接口喇肋。存儲(chǔ)設(shè)備一般屬于塊設(shè)備,塊設(shè)備有請(qǐng)求緩沖區(qū)迹辐,并且支持隨機(jī)訪問而不必按照順序去存取數(shù)據(jù)蝶防,比如你可以先存取后面的數(shù)據(jù),然后再存取前面的數(shù)據(jù)明吩。Linux下的磁盤設(shè)備都是塊設(shè)備间学,盡管在Linux下有塊設(shè)備節(jié)點(diǎn),但應(yīng)用程序一般是通過文件系統(tǒng)及其高速緩存來訪問塊設(shè)備印荔,而不是直接通過設(shè)備節(jié)點(diǎn)來讀寫塊設(shè)備上的數(shù)據(jù)低葫。
網(wǎng)絡(luò)設(shè)備(網(wǎng)絡(luò)接口):網(wǎng)絡(luò)設(shè)備不同于字符設(shè)備和塊設(shè)備,它是面向報(bào)文的而不是面向流的仍律,它不支持隨機(jī)訪問嘿悬,也沒有請(qǐng)求緩沖區(qū)。由于不是面向流的設(shè)備水泉,因此將網(wǎng)絡(luò)接口映射到文件系統(tǒng)中的節(jié)點(diǎn)比較困難善涨。內(nèi)核和網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序間的通訊,完全不同于內(nèi)核和字符以及塊驅(qū)動(dòng)程序之間的通訊草则,內(nèi)核調(diào)用一套和數(shù)據(jù)報(bào)傳輸相關(guān)的函數(shù)而不是read钢拧,write。網(wǎng)絡(luò)設(shè)備(網(wǎng)絡(luò)接口)沒有像字符設(shè)備和塊設(shè)備一樣的設(shè)備號(hào)畔师,只有一個(gè)唯一的名字娶靡,如eth0、eth1等看锉,而這個(gè)名字也不需要與設(shè)備文件節(jié)點(diǎn)對(duì)應(yīng)姿锭。
字符設(shè)備與塊設(shè)備區(qū)別:
1塔鳍、字符設(shè)備是面向流的,最小訪問單位是字節(jié)呻此;而塊設(shè)備是面向塊的轮纫,最小訪問單位是512字節(jié)或2的更高次冪。
2焚鲜、字符設(shè)備只能順序按字節(jié)訪問掌唾,而塊設(shè)備可隨機(jī)訪問。
3忿磅、塊設(shè)備上可容納文件系統(tǒng)糯彬,訪問形式上,字符設(shè)備通過設(shè)備節(jié)點(diǎn)訪問葱她,而塊設(shè)備雖然也可以通過設(shè)備節(jié)點(diǎn)訪問撩扒,但一般是通過文件系統(tǒng)來訪問數(shù)據(jù)。
三吨些、設(shè)備節(jié)點(diǎn)
Linux使用對(duì)文件一樣的管理方式來管理設(shè)備搓谆,所有設(shè)備都以文件的形式存放在/dev目錄下,系統(tǒng)中的每個(gè)字符設(shè)備或者塊設(shè)備都必須為其創(chuàng)建一個(gè)設(shè)備文件豪墅,它包含了該設(shè)備的設(shè)備類型(塊設(shè)備或字符設(shè)備)泉手、設(shè)備號(hào)(主設(shè)備號(hào)和次設(shè)備號(hào))以及設(shè)備訪問控制屬性等。設(shè)備節(jié)點(diǎn)通過mknod命令創(chuàng)建偶器,也可以由Udev用戶工具軟件在系統(tǒng)啟動(dòng)后根據(jù)/sys目錄下每個(gè)設(shè)備的實(shí)際信息創(chuàng)建斩萌,使用后一種方式可以為每個(gè)設(shè)備動(dòng)態(tài)分配設(shè)備號(hào)。
主設(shè)備號(hào):驅(qū)動(dòng)程序在初始化時(shí)屏轰,會(huì)注冊(cè)它的驅(qū)動(dòng)及對(duì)應(yīng)主設(shè)備號(hào)到系統(tǒng)中术裸,這樣當(dāng)應(yīng)用程序訪問設(shè)備節(jié)點(diǎn)時(shí),系統(tǒng)就知道它所訪問的驅(qū)動(dòng)程序亭枷∠眨可通過/proc/devices文件查看系統(tǒng)設(shè)備的主設(shè)備號(hào);
次設(shè)備號(hào):驅(qū)動(dòng)程序遍歷設(shè)備時(shí)叨粘,每發(fā)現(xiàn)一個(gè)它能驅(qū)動(dòng)的設(shè)備猾编,就創(chuàng)建一個(gè)設(shè)備對(duì)象,并為其分配一個(gè)次設(shè)備號(hào)以區(qū)分不同的設(shè)備升敲。這樣當(dāng)應(yīng)用程序訪問設(shè)備節(jié)點(diǎn)時(shí)驅(qū)動(dòng)程序就可以根據(jù)次設(shè)備號(hào)知道它說訪問的設(shè)備了答倡。
四、設(shè)備節(jié)點(diǎn)驴党、設(shè)備驅(qū)動(dòng)及物理設(shè)備三者之間的關(guān)聯(lián)
Linux中設(shè)備節(jié)點(diǎn)通過“mknod”命令創(chuàng)建瘪撇,創(chuàng)建時(shí)需要指定主設(shè)備號(hào)和次設(shè)備號(hào),即指定對(duì)應(yīng)的驅(qū)動(dòng)程序和對(duì)應(yīng)的物理設(shè)備(訪問設(shè)備節(jié)點(diǎn)時(shí)就相當(dāng)于通過其設(shè)備號(hào)訪問驅(qū)動(dòng)程序進(jìn)而間接訪問到物理設(shè)備)。主設(shè)備號(hào)用來區(qū)分不同種類的設(shè)備倔既,而次設(shè)備號(hào)用來區(qū)分同一類型的多個(gè)設(shè)備恕曲。對(duì)于常用設(shè)備,Linux有約定俗成的編號(hào)渤涌,如硬盤的主設(shè)備號(hào)是3
理解:應(yīng)用程序通過訪問設(shè)備節(jié)點(diǎn)讀取主設(shè)備號(hào)和次設(shè)備號(hào)佩谣,通過主設(shè)備號(hào)找對(duì)應(yīng)的驅(qū)動(dòng),通過次設(shè)備號(hào)對(duì)應(yīng)到具體物理設(shè)備实蓬。注:1個(gè)驅(qū)動(dòng)對(duì)應(yīng)一類設(shè)備茸俭,并用唯一主設(shè)備號(hào)標(biāo)識(shí)。
Linux支持的各種設(shè)備的主設(shè)備號(hào)定義在include/linux/major.h文件中安皱,已經(jīng)在官方注冊(cè)的主設(shè)備號(hào)和次設(shè)備號(hào)在Documentation/devices.txt文件中调鬓。
五、Android內(nèi)核和Linux內(nèi)核的區(qū)別[引用]
Android系統(tǒng)最底層是Linux酌伊,并且在中間加上了一個(gè)Dalvik / ART的Java虛擬機(jī)袖迎,從表面層看是Android運(yùn)行庫。每個(gè)Android應(yīng)用都運(yùn)行在自己的進(jìn)程上腺晾,享有Dalvik / ART虛擬機(jī)為它分配的專有實(shí)例,并支持多個(gè)虛擬機(jī)在同一設(shè)備上高效運(yùn)行辜贵,虛擬機(jī)執(zhí)行的是專有格式的可執(zhí)行文件(.dex) - 該格式經(jīng)過優(yōu)化悯蝉,以將內(nèi)存好用降到最低。
Android內(nèi)核和Linux內(nèi)核的差別主要體現(xiàn)在如下11個(gè)方面:
Android Binder
Android Binder是基于Openbinder框架的一個(gè)驅(qū)動(dòng)托慨,用于提供Android平臺(tái)的進(jìn)程間的通信(IPC)鼻由。原來的Linux系統(tǒng)上層應(yīng)用的進(jìn)程間通信主要是D-bus,采用消息總線的方式來進(jìn)行IPC厚棵。其源代碼位于drivers/staging/android/binder.cAndroid電源管理(PM)
Android電源管理是一個(gè)基于標(biāo)準(zhǔn)Linux電源管理系統(tǒng)的輕量級(jí)Andorid電源管理驅(qū)動(dòng)蕉世,針對(duì)嵌入式設(shè)備做了很多優(yōu)化。利用鎖和定時(shí)器來切換系統(tǒng)狀態(tài)婆硬,控制設(shè)備在不同狀態(tài)下的功耗狠轻,以達(dá)到節(jié)能的目的。其源碼位于kernel/power/earlysuspend.c kernel/power/consoleearlysuspend.c kernel/power/fbearysuspend.c kernel/power/wakelock.c kernel/power/userwakelock.c低內(nèi)存管理器(Low memory Killer)
Android中低內(nèi)存管理器和linux標(biāo)準(zhǔn)的OOM相比彬犯,器機(jī)制更加靈活向楼,可以根據(jù)需要?dú)⑺肋M(jìn)程來釋放需要的內(nèi)存。Low memory Killer的代碼非常簡(jiǎn)單谐区,里面關(guān)鍵是函數(shù)Lowmem_shrinker().作為一個(gè)模塊在初始化時(shí)調(diào)用register_shrike注冊(cè)一個(gè)Lowmen_shriker湖蜕,它會(huì)被vm在內(nèi)存緊張的情況下調(diào)用。源碼位于drivers/staging/android/lowmemorykiller.c匿名共享內(nèi)存(Ashmem)
匿名共享內(nèi)存為進(jìn)程間提供大塊共享內(nèi)存宋列,同時(shí)為內(nèi)核提供回收和管理這個(gè)內(nèi)存的機(jī)制昭抒。如果一個(gè)程序嘗試訪問Kernel釋放的一個(gè)共享內(nèi)存塊,它將會(huì)受到一個(gè)錯(cuò)誤提示,然后重新分配內(nèi)存并重載數(shù)據(jù)灭返。其源碼位于mm/ashmem.cAndroid PMEM(Phsical)
PMEM用于向用戶空間提供連續(xù)的物理內(nèi)存區(qū)域盗迟,DSP和某些設(shè)備只能工作在連續(xù)的物理內(nèi)存上。驅(qū)動(dòng)中提供了mmap婆殿、open/release和ioctl等接口诈乒。Android Logger
Android Logger是一個(gè)輕量級(jí)的日志設(shè)備,用于抓取Android系統(tǒng)的各種日志婆芦,是Linux鎖沒有的Android Alarm
Android Alarm提供了一個(gè)定時(shí)器用于把設(shè)備從睡眠狀態(tài)喚醒怕磨,同時(shí)它也提供了一個(gè)即使在設(shè)備睡眠是也會(huì)運(yùn)行的時(shí)鐘基準(zhǔn)。其源碼位于driver/rtc/alarm.c drivers/rtc/alarm-dev.cUSB Gadget驅(qū)動(dòng)
此驅(qū)動(dòng)是一個(gè)具有標(biāo)準(zhǔn)Linux USB gadget驅(qū)動(dòng)框架的設(shè)備驅(qū)動(dòng)消约,Android的USB驅(qū)動(dòng)是基于gadget框架的肠鲫。其源碼位于如下文件:
drivers/usb/gadget/android.c drivers/usb/gadget/f_adb.c drivers/usb/gadget/f_mass_storage.cAndroid Ram Console
為了提供調(diào)試功能,Android允許將調(diào)試日志信息寫入一個(gè)被稱為RAM Console的設(shè)備里或粮,它是一個(gè)基于RAM的Buffer其源碼位于drviers/staging/android/ram_console.cAndroid timed device
Android timed device提供了對(duì)設(shè)備進(jìn)行定時(shí)控制功能导饲,目前僅僅支持vibrator和LED設(shè)備。其源碼為drviers/staging/adnroid/timed_output.cYaffs2文件系統(tǒng)
在Android系統(tǒng)中氯材,采用Yaffs2作為MTD NAND FLASH文件系統(tǒng)渣锦。Yaffs2是一個(gè)快速穩(wěn)定的應(yīng)用于NAND和NOR FLash的跨平臺(tái)的嵌入式設(shè)備文件性,同其他Flash文件系統(tǒng)相比氢哮,Yaffs2使用更小的內(nèi)存來保存運(yùn)行狀態(tài)袋毙,因此它占用內(nèi)存小冗尤;Yaffs2的垃圾回收非常簡(jiǎn)單而且快速听盖,因此能夠達(dá)到更好的性能;其源代碼位于fs/yaffs2目錄