最近正在着手研究android,自己雖然還算是熟悉Linux,但對Android可是一竅不通,都說Android就是個裝了UI的Linux,可到底和Linux有什么關系呢?
根據Linux官方文檔,Android分為以下幾層:
- 應用框架。應用框架最常被應用開發者使用。作為硬件開發者,您應該非常了解開發者 API,因為很多此類 API 都可以直接映射到底層 HAL 接口,並可提供與實現驅動程序相關的實用信息。
- Binder IPC。Binder 進程間通信 (IPC) 機制允許應用框架跨越進程邊界並調用 Android 系統服務代碼,這使得高級框架 API 能與 Android 系統服務進行交互。在應用框架級別,開發者無法看到此類通信的過程,但一切似乎都在“按部就班地運行”。
- 系統服務。系統服務是專注於特定功能的模塊化組件,例如窗口管理器、搜索服務或通知管理器。應用框架 API 所提供的功能可與系統服務通信,以訪問底層硬件。Android 包含兩組服務:“系統”(諸如窗口管理器和通知管理器之類的服務)和“媒體”(涉及播放和錄制媒體的服務)。
- 硬件抽象層 (HAL)。HAL 可定義一個標准接口以供硬件供應商實現,這可讓 Android 忽略較低級別的驅動程序實現。借助 HAL,您可以順利實現相關功能,而不會影響或更改更高級別的系統。HAL 實現會被封裝成模塊,並會由 Android 系統適時地加載。如需了解詳情,請參閱硬件抽象層 (HAL)。
- Linux 內核。開發設備驅動程序與開發典型的 Linux 設備驅動程序類似。Android 使用的 Linux 內核版本包含一些特殊的補充功能,例如低內存終止守護進程(一個內存管理系統,可更主動地保留內存)、喚醒鎖定(一種
PowerManager
系統服務)、Binder IPC 驅動程序,以及對移動嵌入式平台來說非常重要的其他功能。這些補充功能主要用於增強系統功能,不會影響驅動程序開發。您可以使用任意版本的內核,只要它支持所需功能(如 Binder 驅動程序)即可。不過,我們建議您使用 Android 內核的最新版本。如需了解詳情,請參閱構建內核一文。
對我來說比較關心的就是Android的kernel采用的還是Linux kernel,但很明顯Android加入了自己的東西,對Linux進行了一些修改。於是我開始思考,那Android開發是如何進行的呢?Android 10、11、12和哪些Linux kernel版本相對應?這便是今天的主題。
Linux kernel release
目前需要先講述一下Linux目前開發版本的分類,主要分為四部分:
-
Prepatch
由Linus Torvalds維護和發布,針對Mainline kernel添加了新的feature,主要供Linux開發者和狂熱愛好者進行測試。后面有-rc+數字的版本就屬於Prepatch版本,一般來說數字最大為7,rc7為最后一個prepatch版,之后就會出現下一個mainline版本。prepatch版本一般一星期更新一次。
-
Mainline
Mainline tree由Linus Torvalds維護,每一個Mainline kernel一般9到10個星期會發布一個新的版本。
-
Stable
每一個mainline kernel發布后,就被認為是stable的。比如目前正處於v5.17-rc6的開發中,上一個mainline版本v5.16就被認為是最新的stable版本,對於stable版本的bug fix需要郵件發送給該版本的maintainer,在github上面提交PR是不可行的:-)。
在下一個mainline內核可用之前,通常只有幾個錯誤修復內核版本,除非它被指定為“長期維護內核”(Long Term)。Stable內核更新根據需要發布,通常每周一次。
穩定版本的編號開頭為內核版本編號,末尾再添加一個數字。例如,Linus 發布了 4.4 內核,則基於此內核的穩定內核版本編號為 4.4.1、4.4.2、4.4.3,依此類推。表示穩定內核版本樹時,該序列號通常簡寫為 4.4.y。每個穩定內核版本樹由一位內核開發者維護,該開發者負責為該版本挑選所需的補丁程序以及管理審核/發布流程。
穩定內核的維護期限為當前開發周期。Linus 發布新內核后,上一個穩定內核版本樹就會停止維護,用戶必須轉為使用新發布的內核。
-
Longterm
很多不同的 Linux 用戶都表示希望延長對內核的支持,而不只是幾個月時間。因此,長期維護(LTS) 內核版本應運而生,第一個 LTS 內核 (2.6.16) 在 2006 年發布。從那時起,每年都會選擇一個新的 LTS 內核,並且內核社區會為該內核提供最少 2 年的維護支持
最后需要提一下版本號這個東西,因為看一些早期的書籍,一直告訴我們版本號的奇偶具有含義,類似於w.xx.yy這種版本號,xx被稱為major revision,yy被稱為 minor revision,xx如果為奇數表示為開發版本,為偶數代表穩定版。但這個規則在2004年隨着2.6版本的出現廢棄了,版本號什么也不代表,只是單純的數字罷了。
Does the major version number (4.x vs 5.x) mean anything?
No. The major version number is incremented when the number after the dot starts looking "too big." There is literally no other reason.
同時minor revision也被廢棄,從3.0版本開始后,就沒有minor revision這個東西了。我們看到的minor revision屬於穩定版本編號中的,mainline版本不再具有。總之現在的版本號沒什么特殊含義。
個人感覺Linux的開發流程為Linus維護着Mainline版本,然后發布Prepatch進行測試,隨着測試結束和時間的推進,發布下一個Mainline版本,同時也成為新的穩定版,由對應的維護人員來管理針對該穩定版的bug,並進行更新,而Linus選取合適的feature繼續下一個prepatch版本的構建和發布,不負責穩定版的bug report。類似於下面兩條線
5.16->5.17-rc1->5.17-rc2...(Mainline開發,Linus 負責,兩三個月新版本)
|--5.16.1--5.16.2--5.16.3....(Stable開發,專門Maintainer負責,兩三個月結束)
Android kernel
說完Linux,我們要來說一下Android。
由於各版本之間發生了大量更改(每個版本有 10000-14000 項更改),因此包含大型補丁程序集的基於 Linux 的設備在更新到新版內核時可能會遇到嚴重問題。因此,大多數 SoC 供應商開始使用 LTS 版本對其設備進行標准化,使這些設備能夠直接從 Linux 內核社區接收錯誤和安全更新。Android同樣采用LTS kernel來更新設備內核。
AOSP 通用內核(也稱為 Android 通用內核或 ACK)是 kernel.org 內核的下游,包含與 Android 社區相關但尚未合並到 Mainline 內核或長期支持 (LTS) 內核的補丁程序。這些補丁程序可能包括:
- Android 功能所需的向后移植和精選的上游功能
- 可供 Android 設備使用但仍處於上游開發階段的功能(例如,Energy Aware Scheduler 任務放置優化)。
- 對其他生態系統合作伙伴有用的供應商/原始設備制造商 (OEM) 功能(例如,sdcardfs)。
android-mainline
是 Android 功能的主要開發分支。每當 Linus Torvalds 發布內核版本或候選內核版本時,Linux Mainline 內核就會合並到 android-mainline
中。在 2019 年之前,Android 通用內核是通過克隆最新聲明的 LTS 內核並添加 Android 專用補丁程序來構建的。2019 年,這一過程變成了從 android-mainline
中分支出新的 Android 通用內核。這種新模型以遞增的方式構建內核,從而避免進行大量的向前移植和測試 Android 補丁程序的工作。android-mainline
會經過大量持續不斷的測試,因此該模型可保證內核自發布之日起就具有很高的質量。
當上游聲明新的 LTS 時,相應的通用內核就會從 android-mainline
分支出來。由於通用內核來自於android-mainline
,廠商可以在上游聲明 LTS 版本之前,通過從 android-mainline
進行合並來開始項目。創建新的通用內核分支后,合作伙伴可以將合並來源無縫更改為新的分支。
其他通用內核分支從其關聯 LTS 內核接收定期合並。這通常會在 LTS 版本發布后立即執行。例如,Linux 4.19.64 發布后,便會合並到 4.19 通用內核(例如 android-4.19-q
)中。強烈建議合作伙伴定期執行從通用內核到其產品內核的合並,以便及時獲取最新的 LTS 和特定於 Android 的問題修復。
總結一下,可以理解為android-mainline
跟隨着Linux kernel的mainline同步前進,每當一個LTS版本的內核發布,就會從mainline中分出一個對應的通用內核分支,來跟隨該LTS版本前進,每當LTS版本更新時,新的release就會被盡快合並到對應的通用內核分支,通用內核中包含與 Android 社區相關的的補丁程序。
現在我們已經知道Linux kernel發展和Android中的通用內核發展之間的關系了,那Android platform release(Android 10、11、12這種)和Android中的通用內核有什么關系呢?
功能內核和啟動內核
目前 Android 通用內核也分以下兩種:
-
功能內核
包含最新 Android 平台版本功能的增強內核稱為功能內核。對於 Android 11,功能內核基於內核版本 4.14.y、4.19.y 和 5.4.y。在過去的平台版本中,功能內核與啟動內核相同。但在 Android 12 中,將有兩個功能內核和三個啟動內核。
-
啟動內核
指定的啟動內核可用於啟動搭載特定 Android 平台版本的設備。對於 Android 11,可以使用基於內核版本 4.14.y、4.19.y 和 5.4.y 的內核啟動設備。
每個 Android 平台版本都支持基於三個 Linux 內核版本中的任何一個啟動新設備。如下表所示,Android 11 的啟動內核為 android-4.14-stable
、android-4.19-stable
和 android11-5.4
。
由於更新平台版本時通常不需要升級內核,因此缺少平台版本最新功能的內核仍然可以用來啟動設備。因此,即使設備上的平台版本已升級到 Android 11,為 Android 10 設計的內核(例如 android-4.19-q
)也可以在設備上使用。從 Android 12 開始,為了控制必須支持的穩定版 KMI 的數量,功能內核的數量將少於啟動內核的數量。
通用內核分支類型
通用內核分支目前分為以下三種
-
KMI kernel branch(目前)
KMI kernel有着穩定的kenel Module Interface,KMI通過內核版本和Android platform release來定義,所以分支按照
<androidRelease>-<kernel version>
來命名,比如Android 11的5.4 KMI內核被命名為android11-5.4.
。對於Android 12來說,還有兩個額外的KMI kernel:android12-5.4
和android12-5.10
. -
legacy(以前)
-
dessert kernel branch
只有啟動內核才會創建dessert kernel,只接受來自LTS的合並,不添加新的feature,比如
android-4.9-q
只接收LTS 4.9.y 分支的合並。因為Android 11拋棄了dessert命名,所以本該命名為
android-4.14-r
和android-4.19-r
的分支現在稱為android-4.14-stable
和android-4.19-stable
.從Android 11開始支持KMI kernel而不是dessert kernel,所以命名換成了上面說的KMI命名。 -
release kernel branch
針對每一個啟動內核出現新的Android platform release時進行創建release kernel,當對應的kernel或platform release被拋棄時,該分支也會被拋棄。他們不接受LTS的patch,所以minor number從不發生變化,只在每個月Android Security Bullentin發布時,進行bulletin上patch的更新。
但是在Android 11和之后的平台,合作伙伴必須從 dessert 或 KMI 內核進行合並,才能應用 Android Security bulletin 中引用的補丁程序,因為對於 Android 11 或更高平台版本,不會再創建發布內核。
-
上面都是來自於Android官方文檔中的內容,有些概念實在過於繞。個人理解,一個Android平台可對應多個通用內核(一般是三個),通用內核分為功能內核和啟動內核,如果是Android 11及以前,我們可以對功能內核和啟動內核不做區分。還有一些通用內核層次結構、KMI分支生命周期、內核兼容性的問題可以參考官方文檔,
目前我們大體了解了Linux和android之間的關系。總結一下就是,Android底層的kernel基於Linux kernel,維持了一個android-mainline
分支和上游的Linux kernel mainline同步(該主線由Linus維護,經過9-10個周期會發布新的版本,期間會進行prepatch版本的發布,用來測試),每當一個新的LTS版本確立后,就會從android-mainline
中分支出對應的通用內核分支,加上針對android社區的補丁程序,形成通用內核,每當上游的LTS版本更新時,該分支也會進行合並,不同的通用內核根據上層的android platform release進行相關工作,用於啟動不同的android平台。例如4.14版本的通用內核針對android 10和android 11會有android-4.14-q
和android-4.14-stable
兩個分支,但其內部都是基於Linux kernel v4.14.x這個LTS分支。我們可以根據adb輸入uname -r
來了解手機內部的Linux kernel版本,之后尋找通用內核分支版本進行源代碼的查看。