Partition layout

In Android 10, the root file system is no longer included in ramdisk.img and is instead merged into system.img (that is, system.img is always created as if BOARD_BUILD_SYSTEM_ROOT_IMAGE was set). Devices launching with Android 10:

  • Use a system-as-root partition layout (automatically enforced by the build with no options to change the behavior).
  • Must use a ramdisk, which is required for dm-linear.
  • Must set BOARD_BUILD_SYSTEM_ROOT_IMAGE to false. This setting is used only to differentiate between devices that use a ramdisk and devices that don't use a ramdisk (and instead mount system.img directly).

The meaning of a system-as-root configuration differs between Android 9 and Android 10. In an Android 9 system-as-root configuration, BOARD_BUILD_SYSTEM_ROOT_IMAGE is set to true, which forces the build to merge the root file system into system.img then mount system.img as the root file system (rootfs). This configuration is mandatory for devices launching with Android 9 but is optional for devices upgrading to Android 9 and for devices running lower versions of Android. In an Android 10 system-as-root configuration, the build always merges $TARGET_SYSTEM_OUT and $TARGET_ROOT_OUT into system.img; this config is the default behavior for all devices running Android 10.

Android 10 makes further changes to support dynamic partitions, a userspace partitioning system that enables over-the-air (OTA) updates to create, resize, or destroy partitions. As part of this change, the Linux kernel can no longer mount the logical system partition on devices running Android 10, so this operation is handled by the first stage init.

The following sections describe the system-as-root requirements for system-only OTAs, provide guidance on updating devices to use system-as-root (including partition layout changes and dm-verity kernel requirements). For details on changes to ramdisk, see Ramdisk Partitions.

About system-only OTAs

System-only OTAs, which enable Android releases to update system.img and product.img without changing other partitions, require a system-as-root partition layout. All devices running Android 10 must use a system-as-root partition layout to enable system-only OTAs.

  • A/B devices, which mount the system partition as rootfs, already use system-as-root and don't require changes to support system OTAs.
  • Non-A/B devices, which mount the system partition at /system, must be updated to use a system-as-root partition layout to support system OTAs.

For details on A/B and non-A/B devices, refer to A/B (Seamless) System Updates.

Use vendor overlay (<=AOSP 14)

Vendor overlay allows you to overlay changes to the vendor partition at device boot time. A vendor overlay is a set of vendor modules in the product partition that get overlaid on the vendor partition when the device boots, replacing and adding to the existing modules.

When the device boots, the init process completes the first stage mount and reads the default properties. Then it searches /product/vendor_overlay/<target_vendor_version> and mounts each subdirectory on its corresponding vendor partition directory, if the following conditions are met:

  • /vendor/<overlay_dir> exists.
  • /product/vendor_overlay/<target_vendor_version>/<overlay_dir> has the same file context as /vendor/<overlay_dir>.
  • init is allowed to mount on the file context of /vendor/<overlay_dir>.

Implement vendor overlay

Install vendor overlay files in /product/vendor_overlay/<target_vendor_version>. Those files overlay the vendor partition when the device boots, replacing files of the same name and adding any new files. Vendor overlay can't remove files from the vendor partition.

Vendor overlay files must have the same file context as the target files they replace in the vendor partition. By default, the files in the /product/vendor_overlay/<target_vendor_version> directory have the vendor_file context. If there are file context mismatches between vendor overlay files and the files they replace, specify that in the device-specific sepolicy. File context is set at the directory level. If the file context of a vendor overlay directory doesn't match the target directory, and the correct file context isn't specified in the device-specific sepolicy, that vendor overlay directory isn't overlaid onto the target directory.

To use vendor overlay, the kernel must enable OverlayFS by setting CONFIG_OVERLAY_FS=y. Also, the kernel must be merged from the common kernel 4.4 or later, or patched with "overlayfs: override_creds=off option bypass creator_cred".

Vendor overlay implementation example

This procedure demonstrates implementing a vendor overlay that overlays the directories /vendor/lib/*, /vendor/etc/*, and /vendor/app/*.

  1. Add prebuilt vendor files in device/<vendor>/<target>/vendor_overlay/<target_vendor_version>/:

    device/google/device/vendor_overlay/28/lib/libfoo.so
    device/google/device/vendor_overlay/28/lib/libbar.so
    device/google/device/vendor_overlay/28/etc/baz.xml
    device/google/device/vendor_overlay/28/app/qux.apk
    
  2. Install the prebuilt vendor files to product/vendor_overlay in device/google/device/device.mk:

    PRODUCT_COPY_FILES += \
        $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)
    
  3. Define file contexts if the target vendor partition files have contexts other than vendor_file. Because /vendor/lib/* uses the vendor_file context, this example doesn't include that directory.

    Add the following to device/google/device-sepolicy/private/file_contexts:

    /(product|system/product)/vendor_overlay/[0-9]+/etc(/.*)?   u:object_r:vendor_configs_file:s0
    /(product|system/product)/vendor_overlay/[0-9]+/app(/.*)?   u:object_r:vendor_app_file:s0
    
  4. Allow the init process to mount the vendor overlay on file contexts other than vendor_file. Because the init process already has permission to mount on the vendor_file context, this example doesn't define the policy for vendor_file.

    Add the following to device/google/device-sepolicy/public/init.te:

    allow init vendor_configs_file:dir mounton;
    allow init vendor_app_file:dir mounton;
    

Validate vendor overlay

To validate the vendor overlay configuration, add files in /product/vendor_overlay/<target_vendor_version>/<overlay_dir> and check if the files are overlaid on the files in /vendor/<overlay_dir>.

For userdebug builds, there is a test module for Atest:

$ atest -v fs_mgr_vendor_overlay_test

Update to system-as-root

To update non-A/B devices to use system-as-root, you must update the partitioning scheme for boot.img and system.img, set up dm-verity, and remove any boot dependencies on the device-specific root folders.

Update partitions

Unlike A/B devices that repurpose /boot as the recovery partition, non-A/B devices must keep the /recovery partition separate as they don't have the fallback slot partition (for example, from boot_a to boot_b). If /recovery is removed on non-A/B device and made similar to the A/B scheme, recovery mode could break during a failed update to the /boot partition. For this reason, the /recovery partition must be a separate partition from /boot for non-A/B devices, which implies that the recovery image continues to be updated in a deferred manner (that is, the same as in devices running Android 8.1.0 or lower).

The following table lists image partition differences for non-A/B devices before and after Android 9.

Image Ramdisk (before 9) System-as-root (after 9)
boot.img Contains a kernel and a ramdisk.img:
ramdisk.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
Contains a normal boot kernel only.
recovery.img Contains a recovery kernel and a recovery ramdisk.img.
system.img Contains the following:
system.img
  -/
    - bin/
    - etc
    - vendor -> /vendor
    - ...
Contains the merged content of original system.img and ramdisk.img:
system.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/
      - bin/
      - etc/
      - vendor -> /vendor
      - ...
    - vendor/ (mount point)
    - odm/ (mount point)
    ...

The partitions themselves don't change; both ramdisk and system-as-root use the following partition scheme:

  • /boot
  • /system
  • /system
  • /recovery
  • /vendor, etc.

Set up dm-verity

In system-as-root, the kernel must mount system.img under / (mount point) with dm-verity. AOSP supports the following dm-verity implementations for system.img.

vboot 1.0

For vboot 1.0, the kernel must parse Android-specific metadata on /system, then convert to dm-verity params to set up dm-verity (requires these kernel patches). The following example shows dm-verity related settings for system-as-root in kernel command line:

ro root=/dev/dm-0 rootwait skip_initramfs init=/init
dm="system none ro,0 1 android-verity /dev/sda34"
veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f

vboot 2.0

For vboot 2.0 (AVB), the bootloader must integrate external/avb/libavb, which then parses the hashtree descriptor for /system, converts it to dm-verity params, and finally passes the params to the kernel through the kernel command line. (Hashtree descriptors of /system might be on /vbmeta or on /system itself.)

vboot 2.0 requires the following kernel patches:

The following example shows dm-verity related settings for system-as-root in kernel command line:

ro root=/dev/dm-0 rootwait  skip_initramfs init=/init

dm="1 vroot none ro 1,0 5159992 verity 1
PARTUUID=00000016-0000-0000-0000-000000000000
PARTUUID=00000016-0000-0000-0000-000000000000 4096 4096 644999 644999
sha1 d80b4a8be3b58a8ab86fad1b498640892d4843a2
8d08feed2f55c418fb63447fec0d32b1b107e42c 10 restart_on_corruption
ignore_zero_blocks use_fec_from_device
PARTUUID=00000016-0000-0000-0000-000000000000 fec_roots 2 fec_blocks
650080 fec_start 650080"

Use device-specific root folders

With system-as-root, after the generic system image (GSI) is flashed on the device (and before running Vendor Test Suite tests), any device-specific root folders added with BOARD_ROOT_EXTRA_FOLDERS are gone because the entire root directory content has been replaced by the system-as-root GSI. The removal of these folders might cause the device to become unbootable if a dependency on the device-specific root folders exists (for example, they're used as mount points).

To avoid this issue, don't use BOARD_ROOT_EXTRA_FOLDERS to add device-specific root folders. If you need to specify device-specific mount points, use /mnt/vendor/<mount point> (added in these changelists). These vendor-specific mount points can be directly specified in both the fstab device tree (for first-stage mount) and the /vendor/etc/fstab.{ro.hardware} file without additional setup (as fs_mgr creates them under /mnt/vendor/* automatically).