最近开始投入Android的怀抱。说来惭愧,08年就听说这东西,当时也有同事投入去看,因为恶心Java,始终对这玩意无感,没想到现在不会这个嵌入式都快要没法搞了。为了不中年失业,所以只能回过头又来学。
首先还是说Android是基于Linux内核的,所以说骨子里还是linux,但是针对移动端,进行了深度优化。在这里结合GPT还有网上的信息,简单总结一下:
1 首先当然是前后端的分离。
有点类似Openwrt的发展。在之前,linux要开发图形程序是比较复杂的,QT,还有几个库,要么要收费,要么难以学习,最关键是和硬件平台绑定,换到新硬件要做移植。所以谷歌在操盘的时候,直接用Java做了前端GUI。Java以前也有J2SE的传统。这样搞的好处也显而易见,前端和硬件分离,不管什么硬件,都不用改代码了。IOS因为平台封闭,所以选了类C语言(具体机制待研究)。
所以首先的差异就是前端App要用Java开发,所以这个基本上绕不开。必须要学一下。
在前端App的层面,谷歌提供了大量的原生应用,比如电话,计算器,日历,email等。简化了很多开发。
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这些也都换了。
3 驱动层的差异。(部分来自GPT)
Linux以前是标准的ioctl接口,Android改成了HAL接口,本质当然换汤不换药,多了一层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可能对调度策略进行定制,以适应移动设备的特殊需求,例如更好的响应性和电源管理。
驱动总览:
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,常用命令大同小异。
5 用户层差异
主要就是运行的文件系统,一些重要的守护进程,然后一些工具的了解。
守护进程列表:
安卓启动流程:
文件结构
重要服务的位置:
6 源码结构
看起来好像使用envsetup.sh,lunch还有make就够了。但是还是要深入了解一下。
这部分核心要点一个是如何新增设备,另一个是如何新增一个app。最后就是怎么在启动脚本里面加东西。
安卓的编译加速使用了CCache,我在之前公司曾经建议使用这玩意 ,不过后面被否了。。。
7 Fastboot
也就是俗称的刷机模式。是一个Android特有的工具,在Linux上没有。Android通过特定手段进入该模型,上位机配合一个exe文件。实现操作固件的一些功能。
在我看来本质上就是对bootloader的一个封装,好像官方名也叫bootloader interface, 提供的功能也是uboot命令行的那些,分区,升级,刷固件,主备分区管理,系统变量的设置。常规嵌入式开发中,规划分区也是很重要的工作,貌似Android不能修改分区。
里面有Recovery模式和Fastboot模式,一个主要专注系统恢复,一个功能更全面。
8 HAL层
因为现在要搞驱动改法,这部分要重点写一下,有另外一篇。
JNI示例(TODO)-CSDN博客
9 调试方法的学习
主要是ADB,这个比较简单,之前有写过。可能有一些细节,以后用到再说吧。
ADB的使用-CSDN博客
=====================================================
最后简单总结一下,从Linux转到Android做嵌入式开发的几个要点:
1 熟悉Andorid sdk的结构,运行环境,启动流程。怎么新增一个app,一个设备。
2 用Java开发App还是要懂。
3 Android的新增机制,SELinux,调度,电源管理,Binder,ADB调试之类的要学学。
4 HAL层编写。这个相对简单一些,就是格式。
5 Android驱动层的一些实现,FrameBuffer(貌似现在换了),V4L2,ALSA,USB的gaeget框架,可能都要看看。
就写这么多吧,还有的看到再写写。
重要参考资料:Embedded Android,ChatGPT。