配套系列教学视频链接:
说明
系统:Android10.0
设备: FireFly RK3399 (ROC-RK3399-PC-PLUS)
前言
init进程在启动会去加载后缀为.prop的属性问文件, 将属性文件中的属性加载到共享内存中, 这样系统就有了默认的一些属性, 本章节介绍常见属性文件,以及这些文件是如何生成的。
一,属性文件介绍
init进程启动代码system/core/init/property_service.cpp,会调用如下函数来加载属性:
void property_load_boot_defaults(bool load_debug_prop) {
// TODO(b/117892318): merge prop.default and build.prop files into one
// We read the properties and their values into a map, in order to always allow properties
// loaded in the later property files to override the properties in loaded in the earlier
// property files, regardless of if they are "ro." properties or not.
std::map<std::string, std::string> properties;
if (!load_properties_from_file("/system/etc/prop.default", nullptr, &properties)) {
// Try recovery path
if (!load_properties_from_file("/prop.default", nullptr, &properties)) {
// Try legacy path
load_properties_from_file("/default.prop", nullptr, &properties);
}
}
load_properties_from_file("/system/build.prop", nullptr, &properties);
load_properties_from_file("/vendor/default.prop", nullptr, &properties);
load_properties_from_file("/vendor/build.prop", nullptr, &properties);
if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_Q__) {
load_properties_from_file("/odm/etc/build.prop", nullptr, &properties);
} else {
load_properties_from_file("/odm/default.prop", nullptr, &properties);
load_properties_from_file("/odm/build.prop", nullptr, &properties);
}
load_properties_from_file("/product/build.prop", nullptr, &properties);
load_properties_from_file("/product_services/build.prop", nullptr, &properties);
load_properties_from_file("/factory/factory.prop", "ro.*", &properties);
if (load_debug_prop) {
LOG(INFO) << "Loading " << kDebugRamdiskProp;
load_properties_from_file(kDebugRamdiskProp, nullptr, &properties);
}
for (const auto& [name, value] : properties) {
std::string error;
if (PropertySet(name, value, &error) != PROP_SUCCESS) {
LOG(ERROR) << "Could not set '" << name << "' to '" << value
<< "' while loading .prop files" << error;
}
}
property_initialize_ro_product_props();
property_derive_build_fingerprint();
update_sys_usb_config();
}
以上会显示加载属性文件的先后顺序, 文件里面的内容大概如下格式:
ro.actionable_compatible_property.enabled=true
ro.postinstall.fstab.prefix=/system
ro.secure=1
security.perf_harden=1
常见的属性文件介绍如下:
/system/etc/prop.default | 设置ro.debuggable, vm,dex优化相关属性,如果没有该文件,就尝试加载/prop.default,再没有就加载/default.prop |
/system/build.prop | 系统编译属性,如ro.system.build.date系统编译时间,版本等, |
/vendor/default.prop | 厂商默认属性, 如: ro.bionic.arch=arm64 ro.bionic.cpu_variant=cortex-a53 ro.bionic.2nd_arch=arm ro.bionic.2nd_cpu_variant=cortex-a15 |
/vendor/build.prop | 厂商编译属性, 如厂商型号,cpu abi列表: ro.vendor.product.cpu.abilist32=armeabi-v7a,armeabi ro.vendor.product.cpu.abilist64=arm64-v8a ro.product.board=rk30sdk ro.board.platform=rk3399 |
/odm/etc/build.prop | odm编译属性,记录编译时间, 产品信息, 支持的cpu结构: ro.odm.product.cpu.abilist=arm64-v8a,armeabi-v7a,armeabi ro.odm.product.cpu.abilist32=armeabi-v7a,armeabi ro.odm.product.cpu.abilist64=arm64-v8a ro.odm.build.id=QD4A.200805.003 ro.odm.build.tags=release-keys ro.odm.build.type=userdebug ro.product.odm.brand=rockchip ro.product.odm.device=rk3399_roc_pc_plus ro.product.odm.manufacturer=rockchip ro.product.odm.model=ROC-RK3399-PC-PLUS ro.product.odm.name=rk3399_roc_pc_plus Android Q以下版本是找/odm/default.prop和/odm/build.prop |
/product/build.prop | 产品编译属性:也是记录编译时间, 产品信息: ro.product.product.brand=rockchip ro.product.product.device=rk3399_roc_pc_plus ro.product.product.manufacturer=rockchip ro.product.product.model=ROC-RK3399-PC-PLUS ro.product.product.name=rk3399_roc_pc_plus |
二, 属性文件内容的组成
属性文件中的属性是来自哪里的呢?比如/system/build.prop,其实可以直接查看里面的内容,是由以下信息组成的:
build/make/tools/buildinfo_common.sh build/make/tools/buildinfo.sh | 两个脚本会根据build/core/version_defaults.mk里获取各种变量值来赋值给不同属性 |
device/rockchip/rk3399/rk3399_roc_pc_plus/system.prop | 实际是一个变量system_prop_file包含的值 |
ADDITIONAL_BUILD_PROPERTIES | 主要是PRODUCT_PROPERTY_OVERRIDES这个变量赋值, 而这个变量就是我们开发时经常用于自定义属性的, 一般在产品配置目录下定义, 另外就是main.mk中默认增加的属性 |
在./build/make/core/main.mk中可以清晰的看到ADDITIONAL_BUILD_PROPERTIES里面包含了什么:
179 ifneq ($(BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED), true)
180 ADDITIONAL_BUILD_PROPERTIES += $(PRODUCT_PROPERTY_OVERRIDES)
181 else
182 ifndef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
183 ADDITIONAL_BUILD_PROPERTIES += $(PRODUCT_PROPERTY_OVERRIDES)
184 endif
185 endif
231 ifneq ($(TARGET_BUILD_VARIANT),user)
232 ADDITIONAL_BUILD_PROPERTIES += ro.bionic.ld.warning=1
233 else
234 # Enable it for user builds as long as they are not final.
235 ifneq ($(PLATFORM_VERSION_CODENAME),REL)
236 ADDITIONAL_BUILD_PROPERTIES += ro.bionic.ld.warning=1
237 endif
238 endif
239
240 ADDITIONAL_BUILD_PROPERTIES += ro.treble.enabled=${PRODUCT_FULL_TREBLE}
其实PRODUCT_PROPERTY_OVERRIDES就比较重要, 我们定制新的默认属性,经常在mk文件中给这个变量赋值。
/vendor/build.prop内容是由以下信息组成的:
特定的几个产品和厂商相关属性
build/make/tools/buildinfo_common.sh
BOOTIMAGE_BUILD_PROPERTIES
ADDITIONAL VENDOR BUILD PROPERTIES
三, 属性文件的生成过程
至于这些文件具体是如何生成的,可以直接在build/make/core/Makefile文件中搜索:
build.prop, vendor build.prop, odm build.prop, product build.prop, vendor default.prop等关键词,就可以知道如下:
195 # -----------------------------------------------------------------198 BUILDINFO_SH := build/make/tools/buildinfo.sh
199 BUILDINFO_COMMON_SH := build/make/tools/buildinfo_common.sh
build/make/tools/buildinfo.sh脚本:
#!/bin/bash
echo "# begin build properties"
echo "# autogenerated by buildinfo.sh"
echo "ro.build.id=$BUILD_ID"
echo "ro.build.display.id=$BUILD_DISPLAY_ID"
echo "ro.build.version.incremental=$BUILD_NUMBER"
echo "ro.build.version.sdk=$PLATFORM_SDK_VERSION"
echo "ro.build.version.preview_sdk=$PLATFORM_PREVIEW_SDK_VERSION"
echo "ro.build.version.preview_sdk_fingerprint=$PLATFORM_PREVIEW_SDK_FINGERPRINT"
echo "ro.build.version.codename=$PLATFORM_VERSION_CODENAME"
echo "ro.build.version.all_codenames=$PLATFORM_VERSION_ALL_CODENAMES"
echo "ro.build.version.release=$PLATFORM_VERSION"
echo "ro.build.version.security_patch=$PLATFORM_SECURITY_PATCH"
echo "ro.build.version.base_os=$PLATFORM_BASE_OS"
echo "ro.build.version.min_supported_target_sdk=$PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION"
echo "ro.build.date=`$DATE`"
echo "ro.build.date.utc=`$DATE +%s`"
echo "ro.build.type=$TARGET_BUILD_TYPE"
echo "ro.build.user=$BUILD_USERNAME"
echo "ro.build.host=$BUILD_HOSTNAME"
echo "ro.build.tags=$BUILD_VERSION_TAGS"
echo "ro.build.flavor=$TARGET_BUILD_FLAVOR"
if [ -n "$BOARD_BUILD_SYSTEM_ROOT_IMAGE" ] ; then
echo "ro.build.system_root_image=$BOARD_BUILD_SYSTEM_ROOT_IMAGE"
fi
if [ -n "$AB_OTA_UPDATER" ] ; then
echo "ro.build.ab_update=$AB_OTA_UPDATER"
fi
# These values are deprecated, use "ro.product.cpu.abilist"
# instead (see below).
echo "# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,"
echo "# use ro.product.cpu.abilist instead."
echo "ro.product.cpu.abi=$TARGET_CPU_ABI"
if [ -n "$TARGET_CPU_ABI2" ] ; then
echo "ro.product.cpu.abi2=$TARGET_CPU_ABI2"
fi
echo "ro.product.cpu.abilist=$TARGET_CPU_ABI_LIST"
echo "ro.product.cpu.abilist32=$TARGET_CPU_ABI_LIST_32_BIT"
echo "ro.product.cpu.abilist64=$TARGET_CPU_ABI_LIST_64_BIT"
if [ -n "$PRODUCT_DEFAULT_LOCALE" ] ; then
echo "ro.product.locale=$PRODUCT_DEFAULT_LOCALE"
fi
echo "ro.wifi.channels=$PRODUCT_DEFAULT_WIFI_CHANNELS"
echo "# ro.build.product is obsolete; use ro.product.device"
echo "ro.build.product=$TARGET_DEVICE"
echo "# Do not try to parse description or thumbprint"
echo "ro.build.description=$PRIVATE_BUILD_DESC"
if [ -n "$BUILD_THUMBPRINT" ] ; then
echo "ro.build.thumbprint=$BUILD_THUMBPRINT"
fi
echo "# end build properties"
build/make/tools/buildinfo_common.sh脚本
#!/bin/bash
partition="$1"
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <partition>" 1>&2
exit 1
fi
echo "# begin common build properties"
echo "# autogenerated by $0"
echo "ro.${partition}.build.date=`$DATE`"
echo "ro.${partition}.build.date.utc=`$DATE +%s`"
echo "ro.${partition}.build.fingerprint=$BUILD_FINGERPRINT"
echo "ro.${partition}.build.id=$BUILD_ID"
echo "ro.${partition}.build.tags=$BUILD_VERSION_TAGS"
echo "ro.${partition}.build.type=$TARGET_BUILD_TYPE"
echo "ro.${partition}.build.version.incremental=$BUILD_NUMBER"
echo "ro.${partition}.build.version.release=$PLATFORM_VERSION"
echo "ro.${partition}.build.version.sdk=$PLATFORM_SDK_VERSION"
echo "ro.product.${partition}.brand=$PRODUCT_BRAND"
echo "ro.product.${partition}.device=$PRODUCT_DEVICE"
echo "ro.product.${partition}.manufacturer=$PRODUCT_MANUFACTURER"
echo "ro.product.${partition}.model=$PRODUCT_MODEL"
echo "ro.product.${partition}.name=$PRODUCT_NAME"
echo "# end common build properties"
system/build.prop文件的生成过程, 在build/make/core/Makefile中有如下描述
391 ifdef TARGET_SYSTEM_PROP
392 system_prop_file := $(TARGET_SYSTEM_PROP)
393 else
394 system_prop_file := $(wildcard $(TARGET_DEVICE_DIR)/system.prop)
395 endif
396 $(intermediate_system_build_prop): $(BUILDINFO_SH) $(BUILDINFO_COMMON_SH) $(INTERNAL_BUILD_ID_MAKEFILE) $(BUILD_SYSTEM)/version_defaults.mk $(system_prop_file) $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(API_FINGERPRINT)
397 @echo Target buildinfo: $@
398 @mkdir -p $(dir $@)
399 $(hide) echo > $@
400 ifneq ($(PRODUCT_OEM_PROPERTIES),)
401 $(hide) echo "#" >> $@; \
402 echo "# PRODUCT_OEM_PROPERTIES" >> $@; \
403 echo "#" >> $@;
404 $(hide) $(foreach prop,$(PRODUCT_OEM_PROPERTIES), \
405 echo "import /oem/oem.prop $(prop)" >> $@;)
406 endif
407 $(hide) PRODUCT_BRAND="$(PRODUCT_SYSTEM_BRAND)" \
408 PRODUCT_MANUFACTURER="$(PRODUCT_SYSTEM_MANUFACTURER)" \
409 PRODUCT_MODEL="$(PRODUCT_SYSTEM_MODEL)" \
410 PRODUCT_NAME="$(PRODUCT_SYSTEM_NAME)" \
411 PRODUCT_DEVICE="$(PRODUCT_SYSTEM_DEVICE)" \
412 $(call generate-common-build-props-with-product-vars-set,system,$@)
413 $(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
414 TARGET_BUILD_FLAVOR="$(TARGET_BUILD_FLAVOR)" \
415 TARGET_DEVICE="$(TARGET_DEVICE)" \
416 PRODUCT_DEFAULT_LOCALE="$(call get-default-product-locale,$(PRODUCT_LOCALES))" \
417 PRODUCT_DEFAULT_WIFI_CHANNELS="$(PRODUCT_DEFAULT_WIFI_CHANNELS)" \
418 PRIVATE_BUILD_DESC="$(PRIVATE_BUILD_DESC)" \
419 BUILD_ID="$(BUILD_ID)" \
420 BUILD_DISPLAY_ID="$(BUILD_DISPLAY_ID)" \
421 DATE="$(DATE_FROM_FILE)" \
422 BUILD_USERNAME="$(BUILD_USERNAME)" \
423 BUILD_HOSTNAME="$(BUILD_HOSTNAME)" \
424 BUILD_NUMBER="$(BUILD_NUMBER_FROM_FILE)" \
425 BOARD_BUILD_SYSTEM_ROOT_IMAGE="$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)" \
426 AB_OTA_UPDATER="$(AB_OTA_UPDATER)" \
427 PLATFORM_VERSION="$(PLATFORM_VERSION)" \
428 PLATFORM_SECURITY_PATCH="$(PLATFORM_SECURITY_PATCH)" \
429 PLATFORM_BASE_OS="$(PLATFORM_BASE_OS)" \
430 PLATFORM_SDK_VERSION="$(PLATFORM_SDK_VERSION)" \
431 PLATFORM_PREVIEW_SDK_VERSION="$(PLATFORM_PREVIEW_SDK_VERSION)" \
432 PLATFORM_PREVIEW_SDK_FINGERPRINT="$$(cat $(API_FINGERPRINT))" \
433 PLATFORM_VERSION_CODENAME="$(PLATFORM_VERSION_CODENAME)" \
434 PLATFORM_VERSION_ALL_CODENAMES="$(PLATFORM_VERSION_ALL_CODENAMES)" \
435 PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION="$(PLATFORM_MIN_SUPPORTED_TARGE_SDK_VERSION)" \
436 BUILD_VERSION_TAGS="$(BUILD_VERSION_TAGS)" \
437 $(if $(OEM_THUMBPRINT_PROPERTIES),BUILD_THUMBPRINT="$(BUILD_THUMBPRINT_FROM_FILE)") \
438 TARGET_CPU_ABI_LIST="$(TARGET_CPU_ABI_LIST)" \
439 TARGET_CPU_ABI_LIST_32_BIT="$(TARGET_CPU_ABI_LIST_32_BIT)" \
440 TARGET_CPU_ABI_LIST_64_BIT="$(TARGET_CPU_ABI_LIST_64_BIT)" \
441 TARGET_CPU_ABI="$(TARGET_CPU_ABI)" \
442 TARGET_CPU_ABI2="$(TARGET_CPU_ABI2)" \
443 bash $(BUILDINFO_SH) >> $@
444 $(hide) $(foreach file,$(system_prop_file), \
445 if [ -f "$(file)" ]; then \
446 echo Target buildinfo from: "$(file)"; \
447 echo "" >> $@; \
448 echo "#" >> $@; \
449 echo "# from $(file)" >> $@; \
450 echo "#" >> $@; \
451 cat $(file) >> $@; \
452 echo "# end of $(file)" >> $@; \
453 fi;)
454 $(if $(FINAL_BUILD_PROPERTIES), \
455 $(hide) echo >> $@; \
456 echo "#" >> $@; \
457 echo "# ADDITIONAL_BUILD_PROPERTIES" >> $@; \
458 echo "#" >> $@; )
459 $(hide) $(foreach line,$(FINAL_BUILD_PROPERTIES), \
460 echo "$(line)" >> $@;)
461 $(hide) build/make/tools/post_process_props.py $@ $(PRODUCT_SYSTEM_PROPERTY_BLACKLIST)
462
463 build_desc :=
464
465 ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY)))
466 INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img
467 else
468 INSTALLED_RECOVERYIMAGE_TARGET :=
469 endif
470
471 $(INSTALLED_BUILD_PROP_TARGET): $(intermediate_system_build_prop) $(INSTALLED_RECOVERYIMAGE_TARGET)
472 @echo "Target build info: $@"
473 $(hide) grep -v 'ro.product.first_api_level' $(intermediate_system_build_prop) > $@
474
上面大体是如下过程:
1,buildinfo.sh和buildinfo_common.sh脚本会输出很多property值给build.prop
2,system_prop_file变量代表的文件的内容会被到build.prop文件里去,system_prop_file代表的文件可以由TARGET_SYSTEM_PROP变量定义,也可以是device目录下的system.prop文件, 在build目录搜索结果如下:
./build/make/core/Makefile:404:system_prop_file := $(TARGET_SYSTEM_PROP)
./build/make/core/Makefile:406:system_prop_file := $(wildcard $(TARGET_DEVICE_DIR)/system.prop)
3,ADDITIONAL_BUILD_PROPERTIES主要是PRODUCT_PROPERTY_OVERRIDES这个变量赋值, 而这个变量就是我们开发时经常用于自定义属性的, 一般在产品配置目录下定义, 另外就是main.mk中默认增加的属性
4,将out/target/product/${target_device}/obj/ETC/system_build_prop_intermediates里的build.prop拷贝到out/target/product/${target_device}/system/目录下
大家在看build/make/core/Makefile时可能涉及到一下函数, 很多函数都是在build/core/definitions.mk中定义:
collapse-pairs | 作用是将ADDITIONAL_DEFAULT_PROPERTIES和PRODUCT_DEFAULT_PROPERTY_OVERRIDES两个变量里的所有赋值语句’=’两端的空格去掉 |
uniq-pairs-by-first-component | 作用就是对ADDITIONAL_DEFAULT_PROPERTIES里的赋值语句去重,如果有发现对同一个property_name赋值多次,则只保留第一个值。 |
post_process_props.py | 用法: post_process_props.py $@ (PRODUCT_SYSTEM_PROPERTY_BLACKLIST) 作用: 删除default.prop文件中指定的property(在函数的第二个参数中指定,没有则表明不指定),并且检查每个property名字和值的长度是否超过最大值,在这个python脚本中还可以根据需求再修改一次property值作为预置。 |
/vendor/build.prop文件生成的过程:
482 ifdef property_overrides_split_enabled
483 FINAL_VENDOR_BUILD_PROPERTIES += \
484 $(call collapse-pairs, $(PRODUCT_PROPERTY_OVERRIDES))
485 FINAL_VENDOR_BUILD_PROPERTIES := $(call uniq-pairs-by-first-component, \
486 $(FINAL_VENDOR_BUILD_PROPERTIES),=)
487 endif # property_overrides_split_enabled
488
489 $(INSTALLED_VENDOR_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(intermediate_system_build_prop)
490 @echo Target vendor buildinfo: $@
491 @mkdir -p $(dir $@)
492 $(hide) echo > $@
493 ifeq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true)
494 $(hide) echo ro.boot.dynamic_partitions=true >> $@
495 endif
496 ifeq ($(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS),true)
497 $(hide) echo ro.boot.dynamic_partitions_retrofit=true >> $@
498 endif
499 $(hide) grep 'ro.product.first_api_level' $(intermediate_system_build_prop) >> $@ || true
500 $(hide) echo ro.vendor.build.security_patch="$(VENDOR_SECURITY_PATCH)">>$@
501 $(hide) echo ro.vendor.product.cpu.abilist="$(TARGET_CPU_ABI_LIST)">>$@
502 $(hide) echo ro.vendor.product.cpu.abilist32="$(TARGET_CPU_ABI_LIST_32_BIT)">>$@
503 $(hide) echo ro.vendor.product.cpu.abilist64="$(TARGET_CPU_ABI_LIST_64_BIT)">>$@
504 $(hide) echo ro.product.board="$(TARGET_BOOTLOADER_BOARD_NAME)">>$@
505 $(hide) echo ro.board.platform="$(TARGET_BOARD_PLATFORM)">>$@
506 $(hide) echo ro.hwui.use_vulkan="$(TARGET_USES_VULKAN)">>$@
507 ifdef TARGET_SCREEN_DENSITY
508 $(hide) echo ro.sf.lcd_density="$(TARGET_SCREEN_DENSITY)">>$@
509 endif
510 $(hide) $(call generate-common-build-props,vendor,$@)
511 $(hide) echo "#" >> $@; \
512 echo "# BOOTIMAGE_BUILD_PROPERTIES" >> $@; \
513 echo "#" >> $@;
514 $(hide) echo ro.bootimage.build.date=`$(DATE_FROM_FILE)`>>$@
515 $(hide) echo ro.bootimage.build.date.utc=`$(DATE_FROM_FILE) +%s`>>$@
516 $(hide) echo ro.bootimage.build.fingerprint="$(BUILD_FINGERPRINT_FROM_FILE)">>$@
517 $(hide) echo "#" >> $@; \
518 echo "# ADDITIONAL VENDOR BUILD PROPERTIES" >> $@; \
519 echo "#" >> $@;
520 $(hide) cat $(INSTALLED_ANDROID_INFO_TXT_TARGET) | grep 'require version-' | sed -e 's/require version-/ro.build.expect./g' >> $@
521 ifdef property_overrides_split_enabled
522 $(hide) $(foreach line,$(FINAL_VENDOR_BUILD_PROPERTIES), \
523 echo "$(line)" >> $@;)
524 endif # property_overrides_split_enabled
525 $(hide) build/make/tools/post_process_props.py $@ $(PRODUCT_VENDOR_PROPERTY_BLACKLIST)
四, 总结
了解属性文件的生成过程, 就可以很方便的去定制系统默认的属性, 比如修改system.prop文件, 新增变量PRODUCT_PROPERTY_OVERRIDES。