VTS Testing with Debug Ramdisk

Since Android 10, the Generic System Image (GSI) used to run CTS-on-GSI/VTS compliance testing changed from userdebug to user build type in order to be release signed. This is a problem for VTS testing because VTS requires adb root to run, but adb root isn't available on an user build device.

The debug ramdisk (or debug boot image) is introduced to enable adb root on an user build device whose bootloader is unlocked. This simplifies the testing flow by using the same user build GSI system.img for CTS-on-GSI and VTS-on-GSI. For STS setup, using another userdebug OEM system.img is still required.

The following table shows image and build type changes for compliance testing in Android 10.

Test suite Test with Build Debug ramdisk adb root? Android 9 -> 10 build variant change
CTS OEM’s system user N N No change
CTS-on-GSI GSI user N N

userdebug -> user GSI

release signed

STS OEM’s system userdebug N Y New in Q
VTS GSI user Y Y

userdebug -> user GSI

release signed

Overview

These additional image files are generated under the build folder (${ANDROID_PRODUCT_OUT}):

  • boot-debug.img
  • vendor_boot-debug.img

When boot-debug.img is flashed onto the boot partition of the device, the userdebug version of the system sepolicy file and an additional property file, adb_debug.prop, are loaded. This allows adb root with the user build system.img (either GSI’s or the OEM’s).

For Generic Kernel Image (GKI) using devices that have a vendor_boot partition, boot-debug.img mustn't be flashed, as the boot partition must be flashed with a certified GKI image. Instead vendor_boot-debug.img should be flashed onto the vendor_boot partition in order to facilitate debug ramdisk.

Prerequisites for using a debug ramdisk

The debug ramdisk is provided by the OEM running the compliance tests. It mustn't be release signed, and it can only be used if the device is unlocked.

The debug ramdisk won't be generated or used for upgrading devices with:

  • BOARD_BUILD_SYSTEM_ROOT_IMAGE true
  • skip_initramfs in kernel command line

Android 12 GSI

No additional instruction is required to use debug ramdisk with Android 12 GSI.

Starting from 09/29/2021, debug ramdisks no longer require updating with the repack_bootimg tool. Android 12 GSI build after SGR1.210929.001 (7777720) incorporates the up-to-date userdebug_plat_sepolicy.cil file in its system.img and ignores userdebug_plat_sepolicy.cil from the debug ramdisk. See the CLs for details.

Android 11 GSI

When the boot-debug.img or vendor_boot-debug.img is used, the system sepolicy gets loaded from the userdebug_plat_sepolicy.cil file in the debug ramdisk of the boot-debug.img or vendor_boot-debug.img. In order to boot GSI images, please always incorporate up-to-date sepolicy changes from the android11-gsi branch to rebuild your boot-debug.img or vendor_boot-debug.img.

Alternatively, the repack_bootimg tool could be used to rebuild a boot-debug.img or vendor_boot-debug.img with updated GSI sepolicy.

Repacking a debug ramdisk

Instead of incorporating sepolicy changes to rebuild boot-debug.img, partners can use repack_bootimg to update the GSI sepolicy file into boot-debug.img (or vendor_boot-debug.img if the device uses GKI).

The steps are as follows:

  1. Download otatools.zip from https://ci.android.com. We recommend downloading from the build artifacts of aosp_arm64-userdebug on aosp-master.

  2. Setup the execution environment for repack_bootimg:

    unzip otatools.zip -d otatools
    export PATH="${PWD}/otatools/bin:${PATH}"
    repack_bootimg --help
    
  3. Download the userdebug_plat_sepolicy.cil or boot-with-debug-ramdisk-${KERNEL_VERSION}.img from the GSI build you are using. For example, if you're using a arm64 GSI from RJR1.211020.001 (7840830), then download from https://ci.android.com/builds/submitted/7840830/aosp_arm64-user/latest.

  4. Update the device boot-debug.img or vendor_boot-debug.img with userdebug_plat_sepolicy.cil:

    repack_bootimg --local --dst_bootimg boot-debug.img \
        --ramdisk_add userdebug_plat_sepolicy.cil:userdebug_plat_sepolicy.cil \
        --ramdisk_add userdebug_plat_sepolicy.cil:first_stage_ramdisk/userdebug_plat_sepolicy.cil
    # If using GKI
    repack_bootimg --local --dst_bootimg vendor_boot-debug.img \
        --ramdisk_add userdebug_plat_sepolicy.cil:userdebug_plat_sepolicy.cil \
        --ramdisk_add userdebug_plat_sepolicy.cil:first_stage_ramdisk/userdebug_plat_sepolicy.cil
    

    With boot-with-debug-ramdisk-${KERNEL_VERSION}.img:

    repack_bootimg --src_bootimg boot-with-debug-ramdisk-5.4.img \
        --dst_bootimg boot-debug.img \
        --ramdisk_add first_stage_ramdisk/userdebug_plat_sepolicy.cil:userdebug_plat_sepolicy.cil \
        --ramdisk_add first_stage_ramdisk/userdebug_plat_sepolicy.cil:first_stage_ramdisk/userdebug_plat_sepolicy.cil
    # If using GKI
    repack_bootimg --src_bootimg boot-with-debug-ramdisk-5.4.img \
        --dst_bootimg vendor_boot-debug.img \
        --ramdisk_add first_stage_ramdisk/userdebug_plat_sepolicy.cil:userdebug_plat_sepolicy.cil \
        --ramdisk_add first_stage_ramdisk/userdebug_plat_sepolicy.cil:first_stage_ramdisk/userdebug_plat_sepolicy.cil
    

    The arguments of --ramdisk_add can be adjusted according to the device configurations. See the next section for detailed explanation.

Path of the userdebug sepolicy

The above repack_bootimg copies file userdebug_plat_sepolicy.cil from the ramdisk of --src_bootimg to the ramdisk of --dst_bootimg. However, the path within a debug ramdisk might be different in different Android versions. In Android 10 and 11, the path is first_stage_ramdisk/userdebug_plat_sepolicy.cil for devices with androidboot.force_normal_boot=1 in the kernel command line. Otherwise, the path is userdebug_plat_sepolicy.cil.

Run the following command to check if there is androidboot.force_normal_boot in the kernel command line:

adb root
adb shell cat /proc/cmdline | grep force_normal_boot

Starting from Android 12, the path within a debug ramdisk is always userdebug_plat_sepolicy.cil, regardless of the existence of androidboot.force_normal_boot=1 in the kernel command line. The following table shows the paths within a debug ramdisk in different Android versions.

Debug image Android 10 Android 11 Android 12
GKI boot-with-debug-ramdisk-${KERNEL_VERSION}.img N/A first_stage_ramdisk/userdebug_plat_sepolicy.cil userdebug_plat_sepolicy.cil
Device-specific boot-debug.img Depends on force_normal_boot Depends on force_normal_boot userdebug_plat_sepolicy.cil
Device-specific vendor_boot-debug.img N/A Depends on force_normal_boot userdebug_plat_sepolicy.cil

You can specify --ramdisk_add to copy files from and to different paths with a list of src_path:dst_path pairs. For example, the following command copies file first_stage_ramdisk/userdebug_plat_sepolicy.cil from an Android 11 boot-with-debug-ramdisk-5.4.img to first_stage_ramdisk/userdebug_plat_sepolicy.cil within an Android 11 vendor_boot-debug.img.

repack_bootimg \
    --src_bootimg boot-with-debug-ramdisk-5.4.img \
    --dst_bootimg vendor_boot-debug.img \
    --ramdisk_add first_stage_ramdisk/userdebug_plat_sepolicy.cil:first_stage_ramdisk/userdebug_plat_sepolicy.cil

If there is no androidboot.force_normal_boot=1 in the kernel command line, then the command should be adjusted as below to change the destination path to userdebug_plat_sepolicy.cil.

repack_bootimg \
    --src_bootimg boot-with-debug-ramdisk-5.4.img \
    --dst_bootimg vendor_boot-debug.img \
    --ramdisk_add first_stage_ramdisk/userdebug_plat_sepolicy.cil:userdebug_plat_sepolicy.cil

If the image passed to --dst_bootimg is configured as an AVB-chained partition, an AVB footer needs to be added after running the repack_bootimg command.

For example, before running repack_bootimg, run the following command to check if a vendor_boot-debug.img has a chained AVB footer.

avbtool info_image --image vendor_boot-debug.img

If it originally has a chained AVB footer, an AVB footer needs to be added after running the repack_bootimg command. Using any test key to sign the vendor_boot-debug.img works because the debug ramdisk can only be used when a device is unlocked, which allows non-release key signed images on the boot or vendor_boot partition.

avbtool add_hash_footer --partition_name vendor_boot \
    --partition_size 100663296 \
    --algorithm SHA256_RSA4096 \
    --key otatools/external/avb/test/data/testkey_rsa4096.pem \
    --image vendor_boot-debug.img