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.
Once Google first time releases a device, it is called a "launch device". it has:
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"
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.
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 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.
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
Here are the steps
For dynamic partitions, there are something to be noticed:
Then the customers need to do full xTS test to guarantee the quality.