最近開始投入Android的懷抱。說來慚愧,08年就聽說這東西,當時也有同事投入去看,因為惡心Java,始終對這玩意無感,沒想到現在不會這個嵌入式都快要沒法搞了。為了不中年失業,所以只能回過頭又來學。
首先還是說Android是基于Linux內核的,所以說骨子里還是linux,但是針對移動端,進行了深度優化。在這里結合GPT還有網上的信息,這里主要針對相比嵌入式Linux的差異,簡單總結一下:
?
1 首先當然是前后端的分離。
有點類似Openwrt的發展。在之前,linux要開發圖形程序是比較復雜的,QT,還有幾個庫,要么要收費,要么難以學習,最關鍵是和硬件平臺綁定,換到新硬件要做移植。所以谷歌在操盤的時候,直接用Java做了前端GUI。當然,Java以前也有用J2SE做應用的傳統。這樣搞的好處也顯而易見,前端和硬件分離,不管什么硬件,都不用改app代碼了,虛擬機做適配就行了。IOS因為平臺封閉,所以選了類C語言(具體機制空了再看看)。
所以首先的差異就是前端App要用Java開發,所以這個基本上繞不開。框架還是必須要學一下。
在前端App的層面,谷歌提供了Framework,還有大量的原生應用,比如電話,計算器,日歷,email等。簡化了很多開發。
=====================================
按照現在主流的分工,不管是Java還是Kotlin,應該都有專門的工程師。這部分對于嵌入式開發工程師我的理解是不用太懂,但是基本框架要懂,app是怎么怎么調用底層的,這個必須要知道。
試手一下CameraX(TODO)-CSDN博客
?
2 內核的變化(部分內容來自GPT)
Wakelocks: Android引入了"Wakelocks"機制,用于管理設備的喚醒狀態。這是為了優化移動設備的電源管理,確保在需要時設備保持喚醒狀態。就是俗稱的喚醒鎖,貌似這玩意主要是app層在用。
Low Memory Killer: Android引入了Low Memory Killer機制,用于監測并終止占用過多內存的應用程序進程,以維護系統的內存穩定性。這有助于提高系統的性能和響應能力。
Binder IPC(Inter-Process Communication): Android使用了自己的進程間通信機制,稱為Binder。Binder允許Android系統中的不同組件進行通信,例如Activity、Service和BroadcastReceiver。據說這玩意類似Windows上的COM機制。
Ashmem: Android引入了Anonymous Shared Memory(Ashmem)機制,用于進程間共享匿名內存區域。這在Android中的共享內存和圖形子系統中使用。
Logger: Android在內核中添加了用于日志記錄的Logger模塊,以支持Android的日志系統。
Android File System(FUSE): Android引入了FUSE(Filesystem in Userspace)用于文件系統的實現,允許用戶空間程序運行文件系統代碼而不需要修改內核。
安全性增強: Android對Linux內核進行了一些安全性的增強,包括SELinux(Security-Enhanced Linux)的集成,以提高系統的安全性。
調度策略: Android可能會使用不同的調度策略,以適應移動設備的性能和電源管理需求。
庫的替換:好像glibc這些也都換了。
=====================================
大部分都是應用層。Binder是一個重頭,因為涉及到接口。其他了解就行,真用到了再去看也可以。
Tee學習(TODO)-CSDN博客
??
3 驅動層的變化。(部分內容來自GPT)
Linux以前是標準的ioctl接口,Android改成了HAL接口,重要實現都切到了user space,用JNI封裝。這些都要很了解。此外電源管理機制,還有Binder機制要看一下。
內核版本: Linux驅動接口: Linux驅動接口通常是為通用Linux內核設計的,支持各種硬件架構和設備類型。Linux內核在不同的發行版和版本中可能會有一些變化,但整體上是相對一致的。 Android驅動接口: Android使用了經過修改的Linux內核,因此Android驅動接口可能在某些方面與標準的Linux內核驅動接口略有不同。Android還可能引入一些額外的特定于移動設備的驅動需求。
電源管理: Linux驅動接口: Linux提供了通用的電源管理框架,驅動可以利用這些機制進行設備電源的管理。電源管理策略可能因硬件和內核配置而異。 Android驅動接口: Android對電源管理有其專有的需求,引入了Wakelocks等機制,以便更好地適應移動設備的電源管理和喚醒狀態。
進程間通信(IPC): Linux驅動接口: 通常情況下,Linux驅動接口的設計并不直接涉及進程間通信,因為它主要關注設備與內核的交互。 Android驅動接口: Android引入了Binder機制,用于進程間通信。這對于Android中各種組件的通信非常重要,例如Activity、Service和BroadcastReceiver。
設備節點和HAL層: Linux驅動接口: 在標準Linux系統中,設備節點通常位于/dev目錄下,用戶空間可以通過這些設備節點與驅動進行通信。 Android驅動接口: Android引入了硬件抽象層(HAL),這是一個在用戶空間和驅動之間的接口層,用于將Android系統與底層硬件驅動隔離開來。HAL層提供了標準接口,使得不同設備的驅動可以以相似的方式與Android系統進行交互。
調度策略: Linux驅動接口: Linux內核使用通用的進程調度策略,適用于各種設備和場景。 Android驅動接口: Android可能對調度策略進行定制,以適應移動設備的特殊需求,例如更好的響應性和電源管理。
驅動總覽:
=====================================
這部分是重頭,尤其是HAL層的差異,改的挺大的,必須要懂,而且要很懂。然后Android驅動層的一些實現,FrameBuffer(貌似現在換了),V4L2,ALSA,USB的gaeget框架,可能都要看看。當然,后面這部分也是Linux平臺的玩法,區別不大。?
Android的硬件接口HAL-CSDN博客
??
4 安卓運行環境增加的命令
am activity管理器,啟動activity等。直接管理activity的原因可能還是為了調試方便。(猜測)
pm package管理器。這個沒啥好多說的。
svc 服務管理器。和linux標準的service有點接近,但是可以管理的是Android的特定服務,比如藍牙,wifi等等。
input 模擬輸入,主要應該還是用在調試方面。(搞外掛利器?)
getprop/setprop 以前在路由器上,這一套要單獨實現,就是TR069,SNMP之類,現在谷歌整體給你實現了。輕松很多。在嵌入式開發中,這個是大頭。
settings 這個說的主要是設置android。但是和上面的有什么區別呢?還是看了下GPT,setting主要修改和用戶界面相關的東西,主要是app領域。getprop/setprop則更廣,包含一些系統底層屬性,需要的權限也更高,有些要root權限。貌似在嵌入式開發中,主要還是后者。
安卓平臺在本地也集成了一個數據庫,有點類似SQLite。當然,這個就是愛用不用了。
getevent 獲取本地事件。nandread 讀取nand數據。
最后有別于一般用的busybox,安卓用的toolbox,常用命令大同小異。
=================================================
要點有兩個,一個是通過getprop/setprop給adb調試接口,另一個是用getevent,inputs去做定位分析,也都不是太難。其他的知道怎么用就行了。
??
5 用戶層差異
主要就是運行的文件系統,一些重要的守護進程,然后一些工具的了解。
守護進程列表:
安卓啟動流程:
文件結構
重要服務的位置:
文件系統差異(來自GPT)
應用和用戶數據: Android: Android 將應用和用戶數據存儲在 /data 分區中。每個應用程序都有自己的私有數據目錄,其中包含其數據和設置。例如,應用程序的數據庫、緩存和共享首選項通常存儲在 /data/data/<package_name> 目錄下。 嵌入式 Linux: 在一般的嵌入式 Linux 系統中,應用程序的數據和設置通常存儲在 /usr、/var 或其他指定目錄中。
系統文件和可執行文件: Android: Android 的系統文件和可執行文件通常存儲在 /system 分區中。這包括 Android 操作系統的核心文件、系統應用和一些系統級別的設置。 嵌入式 Linux: 一般的嵌入式 Linux 系統的系統文件和可執行文件可能分散在不同的目錄中,通常包括 /bin、/sbin、/lib 等。
可變數據和緩存: Android: 可變數據和緩存通常存儲在 /cache 分區中。這包括一些臨時文件和緩存,可能會在系統啟動時被清理。 嵌入式 Linux: 一般的嵌入式 Linux 系統可能將臨時文件和緩存存儲在 /tmp 目錄下。
外部存儲: Android: 外部存儲通常映射到 /sdcard,用于存儲用戶的媒體文件、下載內容等。 嵌入式 Linux: 嵌入式 Linux 系統也可以使用外部存儲,但其掛載點和目錄結構可能不同,具體取決于設備和系統定制。
硬件相關文件: Android: Android 中可能包含一些硬件相關的文件和節點,如 /dev 目錄下的設備節點,用于與硬件交互。 嵌入式 Linux: 嵌入式 Linux 系統也有 /dev 目錄,但硬件節點的命名和數量可能根據系統的硬件配置而變化。
=======================================
和第4點差不多,沒什么難度,用兩次熟悉就可以了,細節要用的時候知道怎么查就行了。
Android系統目錄介紹_android 目錄-CSDN博客
??
6 源碼結構
看起來好像使用envsetup.sh,lunch還有make就夠了。但是還是要深入了解一下。
這部分核心要點一個是如何新增設備,另一個是如何新增一個app。最后就是怎么在啟動腳本里面加東西。
安卓的編譯加速使用了CCache,我在之前公司曾經建議使用這玩意 ,不過后面被否了。。。
還有一個要了解的就是Android.bp。其實本質就是cmake那種東西。。。
============================================
這個也算次重點吧。主要是要懂編譯環境,各個部分怎么生成的。要懂怎么增加一個設備,或者怎么增加一個App到編譯環境。
CMake小結-CSDN博客
Android SDK學習(TODO)-CSDN博客
AOSP系列—閱讀源碼并熟悉AOSP目錄結構_aospxref-CSDN博客
??
7 Fastboot
也就是俗稱的刷機模式。是一個Android特有的工具,在Linux上沒有。Android通過特定手段進入該模型,上位機配合一個exe文件。實現操作固件的一些功能。
在我看來本質上就是對bootloader的一個封裝,好像官方名也叫bootloader interface, 提供的功能也是uboot命令行的那些,分區,升級,刷固件,主備分區管理,系統變量的設置。常規嵌入式開發中,規劃分區也是很重要的工作,貌似Android不能修改分區。
里面有Recovery模式和Fastboot模式,一個主要專注系統恢復,一個功能更全面。
=====================================================
如果用過uboot的話,看一下用法即可。
?
8 調試方法的學習
主要是ADB,這個比較簡單,之前有寫過。可能有一些細節,以后用到再說吧。
=====================================================
雖然用的很多,但是沒什么難的。
ADB的使用-CSDN博客
?
9 平臺特性的學習
主要是硬件平臺的特性。
======================================================
這個也是重點,畢竟到什么山頭唱什么歌,高通的,瑞芯微的,還是誰的,都要仔細學習。
?
?
就寫這么多吧,還有的看到再寫寫。雖然說換湯不換藥,本質核心還是編程能力。懂不懂這個湯可能就是會不會失業,運氣好工資一個月差幾十K也都有可能。所以還是學學吧。
?
?
?
參考資料:
Embedded Android
ChatGPT