# 简析 Android 设备树 - 简体中文 ``` 注意:本文介绍的设备树不是内核中的设备树,而是存放于 ROM 源代码中 device 目录的设备特有源代码。 ``` ## 前言 设备树存放了构建 ROM 所需的配置,以及部分对设备功能的扩展(例如 IFAA 和 XiaomiParts)。本文将对 [TH779 Studio - ROM 开源组织下的 Redmi K20 Pro 设备树](https://github.com/hh2333-studio-rom-opensource/android_device_xiaomi_raphael)做简要剖析,尽量用普通人能理解的思维说明每一部分的不同作用,目的是让大多数人知道设备树的构成以及给想学写设备树的人做一个参考。 ## 开始 首先我们看设备树的结构,应当是这样的: ``` . ├── Android.bp ├── Android.mk ├── AndroidProducts.mk ├── audio ├── bluetooth ├── BoardConfig.mk ├── compatibility_matrix.xml ├── config.fs ├── configs ├── device.mk ├── extract-files.sh ├── fingerprint ├── fod ├── gps ├── init ├── libhidl ├── light ├── lineage.dependencies ├── lineage_raphael.mk ├── manifest.xml ├── media ├── odm.prop ├── org.ifaa.android.manager ├── overlay ├── overlay-lineage ├── parts ├── proprietary-files.txt ├── README.md ├── recovery ├── releasetools.py ├── rootdir ├── rro_overlays ├── seccomp ├── setup-makefiles.sh ├── system_ext.prop ├── system.prop ├── vendor.prop └── wifi ``` 我们从图中可以看到,此设备树是由一堆 makefile、blueprint 以及许许多多的配置文件和 HAL 构成。 ## Makefile 首先我们来介绍几个重要的 makefile。 * Android.mk Android.mk 往往用于向构建系统描述源文件、应用以及一些共享库。设备树的根目录中往往会有一个 Android.mk,这个 Android.mk 与前面说的作用有部分不同,它往往在编译检查时判断要构建的设备是否使用此设备树,并对不使用此设备树的设备屏蔽掉此设备树下的 Android.mk(当然,此设备树中在 Android.mk 定义的一些同名模块仍然可以造成冲突,稍后我们将引入 Soong 命名空间这个概念)。 * AndroidProducts.mk 这个是用来指定设备特有 makefile 的。我们可以看到,`PRODUCT_MAKEFILES` 这个 flag 指定了 lineage_raphael.mk 作为设备的构建 makefile,不过需要说的是,像 Google 开源的 Pixel 设备树往往会同时定义多个设备特有 makefile,每个 makefile 分别对应不同的 target。例如我们输入的是 `lunch lineage_raphael-userdebug`,构建系统就会在 `PRODUCT_MAKEFILES` 中寻找到 `PRODUCT_NAME` 为 lineage_raphael 的 target 并使用包含其的 makefile 作为特有 makefile 来进行编译。此外,细心的读者还会发现本文所解析的设备树中还有 `COMMON_LUNCH_CHOICES` 这样一个 flag,这是用于指定设备支持的变体(eng、user 和 userdebug),不同变体的区别都可以在网上找到,本文不再做说明。 * BoardConfig.mk 和它的名字一样,这个 makefile 是用来存放手机相关配置信息的,例如分区、HAL 的构建选项、架构信息等,都是在这个 makefile 中定义的,这个里面的相关 flag 都可以在 ROM 源代码中找到(当然有些 flag 是在设备树里定义的,也可以找到)。 * device.mk 这个 makefile 的名字可以为任意,甚至可以省略。因为它是被 `PRODUCT_MAKEFILES` 中指定的 makefile 包含的,所以这里面的内容也可以直接定义在指定的 makefile 中。这个的主要作用是指定设备应当构建的模块(使用 `PRODUCT_PACKAGES` 这个 flag)和文件(使用 `PRODUCT_COPY_FILES` 这个 flag),复制的文件大多数都是设备树中的配置文件,当然有些未被修改的配置文件(例如权限相关还有部分 audio 和 media 配置)也可以用这个 flag 来复制到设备的相应位置中。 * lineage_raphael.mk 这个我之前已经说过,这是指定在 `PRODUCT_MAKEFILES` 中的 makefile,当 lunch 的时候,构建系统会在这些 makefile 中寻找到相应的 target 并加载相关变量以便构建。因为 build/make 中的部分内容是通用的,所以这个 makefile 往往会从 build/make 中继承一些 makefile,继承后编译系统就会一起加载这些 makefile 的相关内容。 ## 配置文件 * audio、gps、media、wifi 等 正如其字面意思一样,这些文件夹内存放的都是与之相关的配置文件,当部分配置文件不方便归类的时候可以放到 configs 文件夹下。当然,放完配置文件后需要在 device.mk 中使用 `PRODUCT_COPY_FILES` 定义文件。 * seccomp Android O 使用 Linux 内核中的安全计算模式,使得未使用的系统调用无法被应用程序访问。这个文件夹 * overlay * rootdir * manifest.xml 和 compatibility_matrix.xml * system.prop 和 vendor.prop ###### tags: `Android`