Mounting Partitions Early

Treble-enabled devices must enable first stage mount to make sure init can load Security-Enhanced Linux (SELinux) policy fragments that are spread across system and vendor partitions. This access also enables the loading of kernel modules as soon as possible after kernel boot.

To perform early mounting, Android must have access to the file systems on which the modules reside. Android 8.x and higher supports mounting /system, /vendor, or /odm as early as init's first stage (that is, before SElinux is initialized). Device makers can use device tree overlays to specify fstab entries for early mounted partitions.

Summary of AOSP early mount changes:

Mounting partitions early, VBoot 1.0

Requirements to early mount partitions with VBoot 1.0 include:

  1. Device node paths must use their by-name symlinks in fstab and devicetree entries. For example, instead of specifying partitions using /dev/block/mmcblk0pX, ensure that partitions are named and the device node is /dev/block/…./by-name/{system,vendor,odm}.
  2. Paths given for PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION and CUSTOM_IMAGE_VERITY_BLOCK_DEVICE in the device configuration for the product (that is, in device/oem/project/device.mk) must match the corresponding block device nodes specified by-name in the fstab/devicetree entries. Example:
    PRODUCT_SYSTEM_VERITY_PARTITION := /dev/block/…./by-name/system
    PRODUCT_VENDOR_VERITY_PARTITION := /dev/block/…./by-name/vendor
    CUSTOM_IMAGE_VERITY_BLOCK_DEVICE := /dev/block/…./by-name/odm
    
  3. Entries provided through device tree overlays must not repeat in the fstab file fragments. For example, when specifying an entry to mount /vendor in the devicetree, the fstab file must not repeat that entry.
  4. Partitions requiring verifyatboot must not be early mounted (doing so is unsupported).
  5. The verity mode/state for verified partitions must be specified in kernel_cmdline using androidboot.veritymode option (existing requirement).

Mounting devicetree early, VBoot 1.0

In Android 8.x and higher, init parses the devicetree and creates fstab entries to mount the partition early during its first stage. An fstab entry takes the form:

src mnt_point type mnt_flags fs_mgr_flags

Devicetree properties are defined to mimic that format:

  • fstab entries must be under /firmware/android/fstab in the devicetree and must have a compatible string set to android,fstab.
  • Each node under /firmware/android/fstab is treated as a single early mount fstab entry. A node must have the following properties defined:
    • dev must point to the device node representing the partition by-name
    • type must be the file system type (as in the fstab files)
    • mnt_flags must be the comma-separated list of mount flags (as in fstab files)
    • fsmgr_flags must be the list of Android fs_mgr flags (as in fstab files)
  • A/B partitions must have a slotselect fs_mgr option.
  • dm-verity enabled partitions must have a verify fs_mgr option.

Example: /system and /vendor on N6P

The following example shows devicetree early mount for system and vendor partitions on Nexus 6P:

/ {
  firmware {
    android {
      compatible = "android,firmware";
  fstab {
    compatible = "android,fstab";
    system {
      compatible = "android,system";
      dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/system";
      type = "ext4";
      mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
      fsmgr_flags = "wait,verify";
    };
    vendor {
      compatible = "android,vendor";
      dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor";
      type = "ext4";
      mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
      fsmgr_flags = "wait";
    };
      };
    };
  };
};

Example: /vendor on Pixel

The following example shows devicetree early mount for /vendor on Pixel (remember to add slotselect for partitions subject to A/B):

/ {
  firmware {
    android {
      compatible = "android,firmware";
      fstab {
        compatible = "android,fstab";
        vendor {
          compatible = "android,vendor";
          dev = "/dev/block/platform/soc/624000.ufshc/by-name/vendor";
          type = "ext4";
          mnt_flags = "ro,barrier=1,discard";
          fsmgr_flags = "wait,slotselect,verify";
        };
      };
    };
  };
};

Mounting partitions early, VBoot 2.0

VBoot 2.0 is Android Verified Boot (AVB). The requirements to early mount partitions with VBoot 2.0 are:

  1. The device node paths must use their by-name symlinks in fstab and devicetree entries. For example, instead of specifying partitions using /dev/block/mmcblk0pX, ensure that the partitions are named and the device node is /dev/block/…./by-name/{system,vendor,odm}.
  2. Build system variables (such as PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION and CUSTOM_IMAGE_VERITY_BLOCK_DEVICE) used for VBoot 1.0 are NOT required for VBoot 2.0. Instead, build variables introduced in VBoot 2.0 (including BOARD_AVB_ENABLE := true) should be defined; for a full configuration, refer to Build System Integration for AVB.
  3. Entries provided through device tree overlays must not repeat in the fstab file fragments. For example, if you specify an entry to mount /vendor in the devicetree, the fstab file must not repeat that entry.
  4. VBoot 2.0 doesn't support verifyatboot, whether early mount is enabled or not.
  5. The verity mode/state for verified partitions must be specified in kernel_cmdline using the androidboot.veritymode option (existing requirement). Make sure to include the following fixes for AVB:

Mounting devicetree early, VBoot 2.0

The configuration in devicetree for VBoot 2.0 is the same as that in VBoot 1.0, with the following exceptions:

  • The fsmgr_flag is switched from verify to avb.
  • All partitions with AVB metadata must be in the VBMeta entry in the devicetree, even when the partition isn't mounting early (for example, /boot).

Example: /system and /vendor on N5X

The following example shows a devicetree early mount for the system and vendor partitions on Nexus 5X. Note that:

  • /system is mounted with AVB and /vendor is mounted without integrity verification.
  • As the Nexus 5X has no /vbmeta partition, so the top-level vbmeta resides at the end of the /boot partition (for details, refer to the AOSP changelist).
    / {
      firmware {
        android {
          compatible = "android,firmware";
          vbmeta {
          compatible = "android,vbmeta";
          parts = "boot,system,vendor";
          };
      fstab {
        compatible = "android,fstab";
        system {
          compatible = "android,system";
          dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/system";
          type = "ext4";
          mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
          fsmgr_flags = "wait,avb";
            };
        vendor {
          compatible = "android,vendor";
          dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor";
          type = "ext4";
          mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
          fsmgr_flags = "wait";
            };
          };
        };
      };
    };
    

Example: /vendor on Pixel

The following example shows mounting /vendor early on a Pixel. Note that:

  • More partitions are specified in the vbmeta entry because those partitions are protected by AVB.
  • All AVB partitions must be included, even if only /vendor is early mounted.
  • Remember to add slotselect for partitions subject to A/B.
    / {
      vbmeta {
          compatible = "android,vbmeta";
      parts = "vbmeta,boot,system,vendor,dtbo";
      };
      firmware {
        android {
          compatible = "android,firmware";
          fstab {
            compatible = "android,fstab";
            vendor {
              compatible = "android,vendor";
              dev = "/dev/block/platform/soc/624000.ufshc/by-name/vendor";
              type = "ext4";
              mnt_flags = "ro,barrier=1,discard";
              fsmgr_flags = "wait,slotselect,avb";
            };
          };
        };
      };
    };