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.0 and higher supports mounting /system, /vendor, or /odm as early as init's first stage (that is, before SElinux is initialized).

Fstab entries

In Android 9 and lower, devices can specify fstab entries for early mounted partitions using device tree overlays (DTOs). In Android 10 and higher, devices must specify fstab entries for early mounted partitions using an fstab file in the first stage ramdisk. Android 10 introduces the following fs_mgr flags for use in the fstab file:

  • first_stage_mount indicates that a partition will be mounted by the first stage init.
  • logical indicates that this is a dynamic partition.
  • avb=vbmeta-partition-name specifies the vbmeta partition. The first stage init initializes this partition before mounting other partitions. The argument for this flag can be omitted if the vbmeta partition for the entry has already been specified by another fstab entry in a previous line.

The following example shows fstab entries to set the system, vendor, and product partitions as logical (dynamic) partitions.

#<dev>  <mnt_point> <type>  <mnt_flags options> <fs_mgr_flags>
system   /system     ext4    ro,barrier=1     wait,slotselect,avb=vbmeta_system,logical,first_stage_mount
vendor   /vendor     ext4    ro,barrier=1     wait,slotselect,avb=vbmeta,logical,first_stage_mount
product  /product    ext4    ro,barrier=1     wait,slotselect,avb,logical,first_stage_mount

In this example, the vendor specifies the vbmeta partition using the fs_mgr flag avb=vbmeta, but product omits the vbmeta argument because vendor has already added vbmeta to the list of partitions.

Devices running Android 10 and higher must place the fstab file in the ramdisk and in the vendor partition.

Ramdisk

The fstab file location in the ramdisk depends on how a device uses ramdisk.

Devices with a boot ramdisk must place the fstab file in the boot ramdisk root. If the device has both a boot ramdisk and a recovery ramdisk, no changes are required to the recovery ramdisk. Example:

PRODUCT_COPY_FILES +=  device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_RAMDISK)/fstab.$(PRODUCT_PLATFORM)

Devices that use recovery as a ramdisk must use the kernel command line parameter androidboot.force_normal_boot=1 to decide whether to boot into Android or continue booting into recovery. Devices Launching with Android 12 or greater with kernel version 5.10 or later must use bootconfig to pass the androidboot.force_normal_boot=1 parameter. In these devices, the first stage init does a switch root operation to /first_stage_ramdisk before mounting the early mount partitions, so devices must place the fstab file in $(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk. Example:

PRODUCT_COPY_FILES +=  device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM)

Vendor

All devices must place a copy of the fstab file into /vendor/etc. This is because the first stage init frees the ramdisk after it completes the early mounting of partitions and performs a switch root operation to move the mount at /system to /. Any subsequent operations needing to access fstab files must therefore use the copy in /vendor/etc. Example:

PRODUCT_COPY_FILES +=  device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.$(PRODUCT_PLATFORM)

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";
            };
          };
        };
      };
    };