这是一篇翻译,原文链接见文末#
欢迎来到新教程!我会尝试教你如何做一个device-tree。这是ROM最重要的部分之一,现在开始!
作为例子的是三星手机和7.0ROM
- 理解device-tree的文件结构
首先从文件夹开始:
- bluebooth | 这个文件夹包含了一些文件和C头文件,用来定义手机的蓝牙的一些特性(默认蓝牙名称,Bluetooth library name(.hcd),WBS forcing,低耗能支持)
- cmhw | CyanogenMod Hardware,包含了一些Java类来使得一些基本功能工作,比如震动强度,显示颜色校准等
- configs | 文件夹里包含了一些子文件夹,里面有一些来自原生固件的文件,如audio,WiFi,GPS,key-layout,NFC等,这些文件有时被修改,也有时保持原生(audio经常被修改)
- include | 这里包含了所有的来自手机硬件的需要进行修改的C头文件(例:samsung_audio.h来自hardware/samsung/,这个文件被修改以定义大量的capture、speakers devices)
- init | init文件夹包含了一些简单的C或C++函数来选择手机运行ROM的优秀版本(啥的优秀版本)(例:SM-A310FD支持双卡,因此函数在检测FD models时的时候会开启双卡支持)
- libshims | 这是一个可选的文件夹,对所有的设备都不必需,这里包含了一些抽象函数类似API的方式提供给手机
- overlay | 这个文件夹是最终的部分。它为framework、应用等包含了XML配置文件,保持framework与原生一致是很重要的(使用apktool?)
- ramdisk | 这个文件夹包含从内核提取的原生ramdisk作为基础,根据权限和服务等进行修改
- ril | 这里包含了一些Java函数来使radio功能工作(网络切换、处理电话、检测SIM卡等)
- sepolicy | 这个文件夹里包含了一些*.te文件,其中包含了相机、audio、应用的权限。
文件:
- Android.mk | 这个makefile存在于很多文件夹中。目的是在用户调用正确的build命令时,building脚本可以正确检测到device-tree
- BoardConfig.mk | 这个makefile是最重要的文件之一,包含了board的定义(分区大小,include路径、overlay路径、CPU、Soc等等)
- Lineage.mk | 这个文件是首先被building脚本读取的,仅包含了产品名称、代号、制造商还有是平板还是手机,并且link device.mk
- device.mk | 这个文件包含了所有的需要使用或者需要复制的包、应用、权限和库,也包含了设备编译apps的时候需要的大小(例:xhdpi)
- extract-files.sh+setup-makefiles.sh | 这些shell脚本被调用来创建vendor(通过ADB从proprietary-files.txt拉取需要的文件到vendor文件夹)
- proprietary-files.txt | 这个文本文件一行一个文件,决定了AOSP需要的来自原生固件的文件(audio库、图形库(例如OpenGL、MALI驱动等),等等)
- system.prop | 这个文件包含了一些需要被复制到build.prop的属性,包含了一些设置,比如RIL类、库、支持,要使用的WLAN接口,显示大小等等
- 基本文件
现在我们解释完文件结构了,开始研究基本文件。
A. Android.mk
# Here we define a variable called "LOCAL_PATH" that just contain the path to the device tree (ex: /device/samsung/a3xeltexx)
# 这里我们定义了一个叫做"LOCAL_PATH"的变量,仅包含了device-tree的目录,这个call my-dir大概就是取当前文件夹,这个my-dir竟然是个函数,build/envsetup.sh生成的,对call来说,这个my-dir相当于表达式,调用完之后返回一个变量,再用$去获取其值
LOCAL_PATH := $(call my-dir)
# Here we open an if statement that will be true if the user requested to build that device.
# 开始了一个if语句,在用户要求build此设备的时候为真,思考,如果目标设备与这个一致的话,那么filter之后是有东西的,ifneq的两个参数一个有东西,一个为空,那么就是不相等,即执行下面的语句;如果目标设备与device不一致,filter出来的是空的,那么ifneq里面相等,不执行下面语句。
ifneq ($(filter a3xeltexx,$(TARGET_DEVICE)),)
# Here we call other makefiles in the device-tree
# 调用所有其他的makefiles,看语句的话,这个all-subdir-makefiles也是一个函数,也就是调用当前目录下面的所有子文件夹下的makefile
include $(call all-subdir-makefiles,$(LOCAL_PATH))
# Here we clean variables
#...算了,大概知道这个是清除变量用的就行
include $(CLEAR_VARS)
# Here we close the if statement.
endif
B. Lineage.mk
# Note: the lineage.mk can also be called slim.mk, pa.mk, aoscp.mk, etc...
# Depending on the ROM to build. LineageOS based roms will use lineage.mk
# 这个可以根据ROM不同叫的名字也不同,原来如此,甭管叫啥都一样会被调用的
# Inherit device configuration
# 继承设备配置,我猜这个inherit-product的功能是从device.mk获取设备配置
$(call inherit-product, device/samsung/a3xeltexx/device.mk)
# Inherit from the common Open Source product configuration
# 从开源产品配置里面继承公共配置
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
# Inherit common CM phone.
# 从CM的公共配置里面继承
$(call inherit-product, vendor/cm/config/common_full_phone.mk)
# Set those variables here to overwrite the inherited values.
# 设置专有参数来覆盖继承的值
PRODUCT_NAME := lineage_a3xeltexx
PRODUCT_DEVICE := a3xeltexx
PRODUCT_BRAND := samsung
PRODUCT_MANUFACTURER := samsung
C. Proprietary-files.txt
# Note: the proprietary-files.txt contains files needed to make the phone or features working.
# 这里包含的是一些能够使手机或者功能正常工作的文件
# Consider below values as example.
# Scaler CSC
lib/libexynosscaler.so
lib/libexynosgscaler.so
lib/libexynosutils.so
# Gralloc
lib/hw/gralloc.exynos5.so
# GPS
bin/gpsd
bin/gps.cer
lib/hw/gps.default.so
lib/libwrappergps.so
lib/libfloatingfeature.so
# Graphics
vendor/lib/egl/libGLES_mali.so
# etc.... There is much more files to pull :D
# 等等,有太多需要拉取的文件了
# 这个是vendor里面的吗?
D. System.prop
# Note: again, consider below values as example.
# Note 2: system.prop need to define HWUI and Dalvik values that you can find in stock firmware.
# system.prop需要定义一些可以在原生固件里面找到的HWUI和Dalvik的相关参数
# media
media.stagefright.legacyencoder=1
media.stagefright.less-secure=1
# Graphics
ro.opengles.version=196609
ro.sf.lcd_density=320
# HWC
debug.hwc.force_gpu=1
- BoardConfig
来谈谈BoardConfig.mk
感觉这块东西变化太多,像这个里面很多东西4c的device都没有
# This is a example. It's uncomplete.
这是一个不可编译的例子
# You can refer to GitHub to see complete BoardConfig.mk
# Platform
# Here we define our manufacturer, based board (exynos5), target board (exynos7580), our slsi variant
# 这里定义生产商,等等等等,也不大认识,到时候看4c的现有的应该就认得了
BOARD_VENDOR := samsung
TARGET_BOARD_PLATFORM := exynos5
TARGET_SOC := exynos7580
TARGET_SLSI_VARIANT := cm
# Arch
# Here we define our CPU
# 大概是cpu相关的东西,架构啊什么的,结合4c的到时候再看吧
TARGET_BOARD_SUFFIX := _32
TARGET_ARCH := arm
TARGET_ARCH_VARIANT := armv7-a-neon
TARGET_CPU_ABI := armeabi-v7a
TARGET_CPU_ABI2 := armeabi
TARGET_CPU_VARIANT := cortex-a53
TARGET_CPU_CORTEX_A53 := true
# Bootloader
TARGET_BOOTLOADER_BOARD_NAME := universal7580
# Define device codename we support
# 定义支持的设备代号
TARGET_OTA_ASSERT_DEVICE := a3xelte,a3xeltexx,a3xelteub,a3xeltedo,a3xeltekx
# Define device-tree path
# 定义device-tree的路径,这是个奇怪的问题,大概是后面有什么会用到这个
DEVICE_PATH := device/samsung/a3xeltexx
# Include path
# 原来如此!
# include里面是与手机相关的头文件
# 所以后面的语句实际上很多就是将device里面的各种东西给包含进来
TARGET_SPECIFIC_HEADER_PATH += $(DEVICE_PATH)/include
# Bluetooth
BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := $(DEVICE_PATH)/bluetooth
# Hardware
# 喔,其实就到这里
BOARD_HARDWARE_CLASS += $(DEVICE_PATH)/cmhw
# Init
# 这两个参数我也不知道是啥
TARGET_INIT_VENDOR_LIB := libinit_sec
TARGET_UNIFIED_DEVICE := true
# Kernel
# 内核配置?路径,架构
TARGET_KERNEL_CONFIG := lineage-a3xeltexx_defconfig
TARGET_KERNEL_SOURCE := kernel/samsung/a3xeltexx
TARGET_KERNEL_ARCH := arm64
TARGET_KERNEL_HEADER_ARCH := arm64
# Extracted with libbootimg
# 用libbooting提取,这个东西小米是不是没有啊,没找到哎
BOARD_CUSTOM_BOOTIMG_MK := hardware/samsung/mkbootimg.mk
BOARD_KERNEL_SEPARATED_DT := true
BOARD_MKBOOTIMG_ARGS := --kernel_offset 0x00008000 --ramdisk_offset 0x01000000 --tags_offset 0x00000100 --board SRPOJ08A000KU
TARGET_CUSTOM_DTBTOOL := dtbhtoolExynos
# Partitions sizes
BOARD_HAS_NO_MISC_PARTITION := false
TARGET_USERIMAGES_USE_EXT4 := true
BOARD_BOOTIMAGE_PARTITION_SIZE := 33554432 # 32MB
BOARD_RECOVERYIMAGE_PARTITION_SIZE := 39845888 # 38MB
BOARD_CACHEIMAGE_PARTITION_SIZE := 209715200 # 200MB
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 3145728000 # 3GB
BOARD_USERDATAIMAGE_PARTITION_SIZE := 12096372736 # 11GB
BOARD_FLASH_BLOCK_SIZE := 4096
# .dat compression
BLOCK_BASED_OTA := true
# PowerHAL
TARGET_POWERHAL_VARIANT := samsung
# Properties
TARGET_SYSTEM_PROP += $(DEVICE_PATH)/system.prop
# Charger
BACKLIGHT_PATH := /sys/devices/14800000.dsim/backlight/panel/brightness
# Recovery
TARGET_RECOVERY_FSTAB := $(DEVICE_PATH)/ramdisk/fstab.samsungexynos7580
# Radio
BOARD_RIL_CLASS := ../../../$(DEVICE_PATH)/ril
BOARD_MODEM_TYPE := tss310
# NFC
BOARD_NFC_CHIPSET := pn547
# Here we include the vendor
-include vendor/samsung/a3xeltexx/BoardConfigVendor.mk
- The device.mk
谈谈device.mk,:
的作用似乎是分割路径,那么是不是这样理解,有一些文件需要复制到ROM的某些路径下面,就从这里设置如何复制,其实也就是提供了两个路径,会有其他脚本去处理,我不清楚这么理解对不对
# Note: this is an example. This is uncomplete
# Include layers
DEVICE_PACKAGE_OVERLAYS += device/samsung/a3xeltexx/overlay
# Define screen size for prebuilt apps
PRODUCT_AAPT_CONFIG := xlarge
PRODUCT_AAPT_PREF_CONFIG := xhdpi
PRODUCT_AAPT_PREBUILT_DPI := hdpi mdpi
# Use dtbhtoolExynos to build dt.img
PRODUCT_PACKAGES += \
dtbhtoolExynos
# Screen size for boot animation
TARGET_SCREEN_HEIGHT := 1280
TARGET_SCREEN_WIDTH := 720
# Copying audio files
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/configs/audio/audio_policy.conf:system/etc/audio_policy.conf \
$(LOCAL_PATH)/configs/audio/mixer_paths.xml:system/etc/mixer_paths.xml
# Copying bluetooth files
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/bluetooth/bt_vendor.conf:system/etc/bluetooth/bt_vendor.conf
# Copying GPS config files
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/configs/gps/gps.conf:system/etc/gps.conf \
$(LOCAL_PATH)/configs/gps/gps.xml:system/etc/gps.xml
# Advertise we support theres features
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.ethernet.xml:system/etc/permissions/android.hardware.ethernet.xml \
frameworks/native/data/etc/android.hardware.sensor.compass.xml:system/etc/permissions/android.hardware.sensor.compass.xml \
frameworks/native/data/etc/android.hardware.sensor.gyroscope.xml:system/etc/permissions/android.hardware.sensor.gyroscope.xml \
frameworks/native/data/etc/android.hardware.sensor.heartrate.xml:system/etc/permissions/android.hardware.sensor.heartrate.xml \
frameworks/native/data/etc/android.hardware.sensor.light.xml:system/etc/permissions/android.hardware.sensor.light.xml \
frameworks/native/data/etc/android.hardware.sensor.stepcounter.xml:system/etc/permissions/android.hardware.sensor.stepcounter.xml \
frameworks/native/data/etc/android.hardware.sensor.stepdetector.xml:system/etc/permissions/android.hardware.sensor.stepdetector.xml \
frameworks/native/data/etc/android.hardware.nfc.xml:system/etc/permissions/android.hardware.nfc.xml \
frameworks/native/data/etc/android.hardware.nfc.hce.xml:system/etc/permissions/android.hardware.nfc.hce.xml \
frameworks/native/data/etc/com.android.nfc_extras.xml:system/etc/permissions/com.android.nfc_extras.xml
# Include our GPS shim
PRODUCT_PACKAGES += \
libshim_gpsd
# Include our edited ramdisk
PRODUCT_PACKAGES += \
fstab.samsungexynos7580 \
init.baseband.rc \
init.samsung.rc \
init.samsungexynos7580.rc \
init.samsungexynos7580.usb.rc \
init.wifi.rc \
ueventd.samsungexynos7580.rc \
init.battery.rc
- Details
到这里就结束啦
Also, i didn't explained how to fill include, etc...
For that part, i recommend you to use a device-tree near from your device, you copy it, then you adapt it to your device (change codename, manufacturer, screen size, CPU, etc....)
Making a device-tree is a lot of copy from other device-tree, github commits, etc...
这是一篇翻译
内容来源[XDA]/android/software/guide-how-to-make-device-tree-phone-t3698419