i.MX Android cross-version OTA notes

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX Android cross-version OTA notes

i.MX Android cross-version OTA notes

Preface

With i.MX android, it is often infeasible to directly build an OTA package with a newer android version and apply that OTA package to a device running old version of Android. For example, the OTA package buit with i.MX android-13.0.0_2.0.0 release for evk_8mm cannot be direclty applied on the evk_8mm board running the image built with i.MX android-11.0.0_1.0.0.

In this article, the reason why directly cross-version OTA is infeasible in i.mx android is firstly explained. Then what should be takein into consideration and done before cross-version OTA are described.

 

The way Google update the system for its device

Once Google first time releases a device, it is called a "launch device". it has:

  • codename. Take pixel 3a xl as an example, the codename is bonito
  • Android version. For pixel 3a xl, it's Android 9.0
  • kernel version. For pixel 3a xl, it's 4.9
  • PRODUCT_SHIPPING_API_LEVEL. For pixel 3a xl, it is set to be 28, the same as the SDK version of that Android version.
  • FCM target level. For pixel 3a xl, it's 3

After the system code is updated to a new version, an OTA package can be built with the lunch target aosp_bonito-user or aosp_bonito-userdebug for pixel 3a xl, let's call the updated device "retrofit device"

  • codename is not changed. its device configuration still can be found in "device/google/bonito/"
  • Android version. it is the version the OTA updated to. Four android versions are supported, here they are android 9, 10, 11, 12, which means pixel 3a xl can at most upgraded to android12. "device/google/bonito/" is introduced in android9, and removed in android13.
  • kernel version. not changed after OTA
  • PRODUCT_SHIPPING_API_LEVEL. Not changed in OTA, so after the OTA, the value of property "ro.product.first_api_level" is different from the SDK version.
  • FCM target level. not changed after OTA.

The FCM target level is in the device manifest.xml, corresponds to a specific version of system compatibility.matrix.xml, so HALs provided by this device does not need to have much changes if the FCM target level is not changed.

This is the way Google maintains the system for their devices. This is not the way i.MX Android devices are maintained.

The way i.MX Android update the system to a new version for maintained device

when the code is upaded to a new version for maintained imx devices, all the device are taken as "launch device", so compaired to the previous version, in the new system for the device:

  • the kernel version is changed
  • PRODUCT_SHIPPING_API_LEVEL is changed
  • FCM target level is changed.
  • Physical partitions may also be changed

The FCM target level change means there may be some big changes in the HALs provided by this device.

The PRODUCT_SHIPPING_API_LEVEL change means quite many code logic based on the property "ro.product.first_api_level" execute in different flow.

Fro the partition changes, the OTA package directly build with this updated code often cannot be applied, for example, a new image for the new partition cannot be applied on the board running old system, as it does not have the partition for the image.

Things cannot be changed during OTA

To make things more clear that why direct cross-version OTA is infeasible, it is necessary to know that there are things cannot be changed during OTA.

1. physical partitions cannot be changed during OTA.

related features are:

* dynamic partition

* gki

* boot header version

2. user data on theuserdata partition should not be changed, or data loss may occur during OTA.

the related features are:

* encryption options

encryption options should not be changed, to make new version of android can recognize the data encrypted by the old version of android.

For some  fs_mgr encrypt options, the product_shipping_api_level impacts on the final encryption parameters passed to the kernel. take a look at the following code, even with the same fs_mgr encryption option, if the first_api_level is different, the final encryption parameter is different in different android version.

android10    system/extras/libfscrypt/fscrypt.cpp
    if (filenames_encryption_mode == FS_ENCRYPTION_MODE_AES_256_CTS) {
        // Use legacy padding with our original filenames encryption mode.
        return FS_POLICY_FLAGS_PAD_4;
    } else if (filenames_encryption_mode == FS_ENCRYPTION_MODE_ADIANTUM) {
        // ...snip...
        return (FS_POLICY_FLAGS_PAD_16 | FS_POLICY_FLAG_DIRECT_KEY);
    }
    // ...snip...
    return FS_POLICY_FLAGS_PAD_16;
 
android11    system/extras/libfscrypt/fscrypt.cpp
    if (!is_gki && options->version == 1 && options->filenames_mode == FSCRYPT_MODE_AES_256_CTS) {
        options->flags |= FSCRYPT_POLICY_FLAGS_PAD_4;
    } else {
        options->flags |= FSCRYPT_POLICY_FLAGS_PAD_16;
    }
 
android12  system/extras/libfscrypt/fscrypt.cpp
    if (first_api_level <= __ANDROID_API_Q__ && options->version == 1 &&
        options->filenames_mode == FSCRYPT_MODE_AES_256_CTS) {
        options->flags |= FSCRYPT_POLICY_FLAGS_PAD_4;
    } else {
        options->flags |= FSCRYPT_POLICY_FLAGS_PAD_16;
    }

 The fscrypt version will also impact the result. If not sepcified, the default "version" would be "v1" if the "product_shipping_api_level <= 29" or the default "version" would be "v2".
Some fscrypt functions like "casefold" and "project id" will depend on fscrypt "v2", these functions are enabled by including the "$(call inherit-product, $(SRC_TARGET_DIR)/product/emulated_storage.mk)" in "device/nxp". The "emulated_storage.mk" must not be included if fscrypt "v1" is used.

 * the userdata partition filesystem type

ext4 (used before i.mx android 13.0.0)

f2fs (used from i.mx android 13.0.0)

* The filesystem for the emulated storage on the userdata partition

sdcardfs

fuse

3. The boot control info in misc partition should be able to be recognized before and after OTA

related feature is:

* bootcontrol HAL

4. The bootargs passed by u-boot to kernel cannot be changed if the bootloader is not updated

The related feature is:

* bootconfig is used to pass boot args from android12.0.0_1.0.0. used with vendor boot header v4.

 

it should be known that if dual bootloader of postinstall is used, bootloader can be updated.

 

For these related features. Google does not implement or change them for a "retrofit device", just imlement for change the features for a "launch device", makes direct cross-version OTA feasible for them, because things cannot be changed during OTA are the same between different android versions.

For i.mx android, to implement new features for all maintaied devices, things can be changed during OTA are often changed when update to a new version of android. which makes direct cross-version OTA infeasible. 

 

For the ease of reference, list some feature change history here:

* physical partition change history

bootloader_a/b 4MB 4MB 4MB 4MB 4MB 16MB 16MB 16MB
dtbo_a/b 4MB 4MB 4MB 4MB 4MB 4MB 4MB 4MB
boot_a/b 48MB 48MB 64MB 64MB 64MB 64MB 64MB 64MB
init_boot_a/b - -   -   - 8MB 8MB
vendor_boot_a/b - -   64MB 64MB 64MB 64MB 64MB
misc 4MB 4MB 4MB 4MB 4MB 4MB 4MB 4MB
metadata 2MB 2MB 2MB 2MB 16MB 16MB 64MB 64MB
presistdata 1MB 1MB 1MB 1MB 1MB 1MB 1MB 1MB
super - - 7168MB 3584MB 4096MB 4096MB 4096MB 4096MB
fbmisc 1MB 1MB 1MB 1MB 1MB 1MB 1MB 1MB
vbmeta_a/b 1MB 1MB 1mb 1MB 1MB 1MB 1MB 1MB
system_a/b 2560MB 1536MB - -   - - -
vendor_a/b 256MB 512MB - -   - - -
product_a/b - 1792MB - -   - - -

 

boot_a/b: 48MB → 64MB, Image becames bigger ater enabling some debug options

vendor_boot_a/b: boot header v3. Vendor boot and boot header v3 are MUST to enable GKI feature. 

init_boot_a/b: The init binary in ramdisk is moved from boot.img to init_boot.img. flash gki image from Google does not impact on the vendor modifications on init.

 

for the metadata partition:

2MB → 16MB, requirement of vts "-m vts_gsi_boot_test -t MetadataPartition#MinimumSize"

16MB → 64MB, to make the partition be formated as f2fs, 32MB is not enough, 64MB is used.

metadata partition was firstly mounted in android11, when enable the user data checkpoint feature

* gki feature history

Firstly introduced in android11. Some codes are built into modules, put the modules in vendor_boot_a/b partition. vendor_boot_a/b partitions are also firstly introduced in android11

GKI prebuilt binary was integrated from android12

 

The way to handle cross-version OTA for i.mx android

Here are the steps

  • align the partitions within the OTA base code and the OTA target code
    • if the product may be in the development stage, and the OTA base  code can be modified:
      • reserve partitions in OTA base code. for example, OTA from 10 to 11, reserver the vendor_boot partition in android10 partitiont able although there is not vendor_boot.img. change the selinux rules to have update_engine to be able to update this partition.
      • enlarge some partitions in the OTA base code as in the OTA target code. for examples, the bootloader partitions is 16MB in android13. if OTA from android12 to android13 and the android 12 code can be modified, enlarge the bootloader partition to 16MB.
      • as data in userdata and metadata partition is not touched during OTA, modify the mount options of userdata and metadata partitions in OTA target code to be the same as the one in OTA base code.
    • if the product partitions are already shipped, only the OTA target code can be modified: 
      • as data in userdata and metadata partition is not touched during OTA, modify the mount options of userdata and metadata partitions in OTA target code to be the same as the one in the OTA base code.
      • change the partition size to align with the OTA base code
      • partitions like vendor_boot and/or init_boot may need to be removed.
      • remove/change the features related to the removed or changed partitions
  • if dual bootloader is not used:
    • recently in android version update, vendor_boot and init_boot partitions are added, this is related to boot image header version, the images in these partitions are loaded and verified by uboot, so if dual bootloader is not used, uboot code related to these things need to be changed. check the code related to "struct boot_img_hdr" in uboot.
    • the a/b slot metadata format may be changed between the OTA base code and the OTA target code , this a/b slot metadata is accessed by both Android bootctrl HAL and uboot, as dual bootloader is not used, uboot is not upaded, the updated Android bootctrl HAL should also use the same format to access the file.
    • a postinstall mechanism can be used to update the uboot images, but as there is no fallback for the update failure, the risks need to be evaluated.
  • check whether the OTA package can be applied and whether the updated system can boot up
    • an failure example: OTA from android10 to android12, the system fail to boot up because of the PRODUCT_SHIPPING_API_LEVEL/"ro.product.first_api_level" value difference, different encryption options are used for userdata partitions. so the PRODUCT_SHIPPING_API_LEVEL value need to be changed to be the same as the one in the OTA base code.
    • as PRODUCT_SHIPPING_API_LEVEL is changed, the FCM target version and related HALs may also need to be changed, including changes in device manifest.xml and compatibility_matrix.xml. need to check the commit history about what is changed together with the FCM target version change.

 

For dynamic partitions, there are something to be noticed:

  1. OTA from the image without dynamic partitions to use dynamic partitions:
    1. Refer to the code in android10.0.0_2.0.0, there is a demonstration to update 10.0.0_1.0.0 to 10.0.0_2.0.0. In 0.0.0_1.0.0, dynamic partition is not enabled. check the variable "TARGET_USE_RETROFIT_DYNAMIC_PARTITION" and related configurations.
  2. OTA from dynamic partitions to virtual A/B, for example, OTA from android10 to android11
    1. inherit the file "build/make/target/product/virtual_ab_ota_retrofit.mk"
      1. the first time when update from android10 to android11 with OTA, inherit the "build/make/target/product/virtual_ab_ota_retrofit.mk", the BOARD_NXP_DYNAMIC_PARTITIONS_SIZE is set as dynamic paritition is used.
      2. the second time, the device is runing android11 with retrofit virtual A/B feature, this time OTA again, but not cross version, inherit "build/make/target/product/virtual_ab_ota.mk" instead, and the BOARD_NXP_DYNAMIC_PARTITIONS_SIZE  can be set as virtual A/B feature is used.
    2. Devices that were upgraded to dynamic partitions can’t retrofit virtual A/B.
  3. if there are new dynamic partitions in OTA target code, like vendor_dlkm, no additional changes need to be made for it.

Then the customers need to do full xTS test to guarantee the quality.

 

No ratings
Version history
Last update:
‎07-05-2024 12:50 AM
Updated by: