本文基于 AOSP Android10_r41 源码环境。
AOSP 添加的可执行程序,可以分为两类:
- C/C++ 可执行程序
- Java 可执行程序
在了解如何给 AOSP 添加可执行程序前,我们需要了解一下ARM + Android 行业流程与 Android 常用的四个分区:
- System 分区
- Vender 分区
- Odm 分区
- Product 分区
1. ARM + Android 行业流程与 Android 分区
ARM + Android 这个行业,一个简化的普遍流程:
- Google 开发迭代 AOSP + Kernel
- 芯片厂商,针对自己的芯片特点,移植 AOSP 和 Kernel,使其可以在自己的芯片上跑起来。
- 方案厂商(很多芯片厂商也扮演了方案厂商的角色),设计电路板,给芯片添加外设,在芯片厂商源码基础上开发外设相关软件,主要是驱动和 hal,改进性能和稳定性。
- 产品厂商,主要是系统软件开发,UI 定制以及硬件上的定制(添加自己的外设),改进性能和稳定性.
Google 开发的通用 Android 系统组件编译后会被存放到 System 分区,原则上不同厂商、不同型号的设备都通用。
芯片厂商和方案厂商针对硬件相关的平台通用的可执行程序、库、系统服务和 app 等一般放到 Vender 分区。(开发的驱动程序是放在 boot 分区的 kernel 部分)
到了产品厂商这里,情况稍微复杂一点,通常针对同一套软硬件平台,可能会开发多个产品。比如:小米 12s,小米12s pro,小米12s ultra 均源于骁龙8+平台。
每一个产品,我们称之为一个 Variant(变体)。
通常情况下,做产品的厂商在同一个硬件平台上针对不同的产品会从硬件和软件两个维度来做定制。
硬件上,产品 A 可能用的是京东方的屏,产品 B 可能用的是三星的屏;差异硬件相关的软件部分都会放在 Odm 分区。这样,产品 A 和产品 B 之间 Odm 以外的分区都是一样的,便于统一维护与升级。(硬件相关的软件共用部分放在 vendor 分区)
软件上,产品 A 可能是带广告的版本,产品 B 可能是不带广告的版本。这些有差异的软件部分都放在 Product 分区,这样产品 A 和产品 B 之间 Product 以外的分区都是一样的,便于统一维护与升级。(软件共用部分都放在 System分区)
总结一下,不同产品之间公共的部分放在 System 和 Vender 分区,差异的部分放在 Odm 和 Product 分区。
2. 动手在系统源码中添加一个 C/C++ 可执行程序
2.1 源码添加
我们先看看如何以源码的方式来添加一个可执行程序。
在 device/Jelly/Rice14
目录下创建如下的文件结构:
hello
├── Android.bp
└── hello.cpp
其中 hello.cpp 的内容如下
#include <cstdio>
int main()
{
printf("Hello Android\n");
return 0;
}
Android.bp是程序的编译配置文件,作用类似于 App 开发中的 gradle.build 文件,其格式为 json。Android.bp 的内容如下:
cc_binary {
//模块类型为可执行文件
name: "hello", //模块名hello
srcs: ["hello.cpp"], //源文件列表
cflags: ["-Werror"], //添加编译选项
}
在 device/Jelly/Rice14/Rice14.mk
中添加:
PRODUCT_PACKAGES += hello
接下来编译系统:
source build/envsetup.sh
lunch Rice14-eng
make -j16
你会发现报错了:
Offending entries:
system/bin/helloworld
build/make/core/main.mk:1414: error: Build failed.
默认情况下,我们的模块会被安装到 System 分区,编译系统限制了我们在 System 分区添加东西,理论上来说, System 分区应该只能由 G