VTS Testing with Debug Ramdisk

In Android 10, the generic system image (GSI) used to run CTS-on-GSI/VTS compliance testing changes from userdebug to user build type, because GSI is release signed. However, the adb root command that gives a host root permissions to the Android device under test isn't available in a user build. This is a problem because VTS requires adb root to run.

The debug ramdisk is introduced in Android 10 to make adb root possible, if the device is unlocked. This simplifies the testing flow by reusing the same user build GSI system.img. For STS setup, using another userdebug OEM system.img is still required. The following table shows images and build types for the compliance tests 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

Vendor boot debug ramdisk

Starting from Android 11, vendor_boot-debug.img should be flashed onto the /vendor_boot partition in VTS for devices supporting the Generic Kernel Image (GKI) architecture. And a signed GKI boot-${KERNEL_VERSION}.img should be flashed onto the /boot partition instead of a boot-debug-{KERNEL_VERSION}.img.

Prerequisites for using a debug ramdisk

The debug ramdisk is provided by the OEM running the compliance tests. It shouldn'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:

  • skip_initramfs in kernel command line

When you use boot-debug.img, system sepolicy (plat_sepolicy.cil) gets loaded from boot-debug.img. Please always incorporate new sepolicy changes from android{N}-gsi branches to rebuild boot-debug.img, for example, android11-gsi. Otherwise, the device might not be able to boot a new GSI image. This also applies to vendor_boot-debug.img for devices having a /vendor_boot partition.

Repacking a debug ramdisk

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

The steps are as follows:

  1. Download otatools.zip from https://ci.android.com. For example, download it from aosp_arm64-userdebug build artifacts.

  2. Run the following command to check repack_bootimg is available.

    $ unzip otatools.zip -d otatools
    $ export PATH="$PWD"/otatools/bin:"$PATH"
    $ repack_bootimg
  3. Download a generic boot-debug.img from GSI builds. For example, if you're using a generic system.img from RJR1.210330.001_7244771, then download the generic boot-debug-${KERNEL_VERSION}.img from the same version RJR1.210330.001_7244771.

  4. Run the following command to extract the userdebug sepolicy file from boot-debug-${KERNEL_VERSION}.img and update it into the device-specific boot-debug.img (or vendor_boot-debug.img).

    $ repack_bootimg --src_bootimg boot-debug-5.4.img --dst_bootimg boot-debug.img
    $ repack_bootimg --src_bootimg boot-debug-5.4.img --dst_bootimg vendor_boot-debug.img

The 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.

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, 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-debug-{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 locations, with a list of src_path:dst_path pairs. The --help option also gives more examples.

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

$ repack_bootimg --help

AOSP changes

The debug ramdisk changes in AOSP are identified by the debug_ramdisk hashtag.

These additional image files are generated under the build folder out/target/product/$(TARGET_DEVICE):

  • ramdisk-debug.img
  • 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).

This also applies to devices with a vendor_boot-debug.img flashed onto the vendor_boot partition. i.e., the debug files can be loaded from either the /boot or the /vendor_boot partition.