Wczesne montowanie partycji

Urządzenia obsługujące technologię Treble muszą umożliwiać montowanie pierwszego stopnia, aby mieć pewność, że init będzie mógł załadować fragmenty zasad systemu Linux o zwiększonym poziomie zabezpieczeń (SELinux) , które są rozproszone po partycjach system i vendor . Dostęp ten umożliwia także ładowanie modułów jądra tak szybko, jak to możliwe po uruchomieniu jądra.

Aby przeprowadzić wczesny montaż, Android musi mieć dostęp do systemów plików, w których znajdują się moduły. Android 8.0 i nowsze obsługują montowanie /system , /vendor lub /odm już w pierwszym etapie init (to znaczy przed inicjalizacją SElinux).

Wpisy w Fstabie

W systemie Android 9 i starszych urządzeniach można określić wpisy fstab dla wcześniej zamontowanych partycji za pomocą nakładek drzewa urządzeń (DTO) . W systemie Android 10 i nowszych urządzeniach należy określić wpisy fstab dla wcześniej zamontowanych partycji przy użyciu pliku fstab w ramdysku pierwszego stopnia. W systemie Android 10 wprowadzono następujące flagi fs_mgr do użycia w pliku fstab :

  • first_stage_mount wskazuje, że partycja zostanie zamontowana podczas inicjalizacji pierwszego etapu.
  • logical wskazuje, że jest to partycja dynamiczna .
  • avb= vbmeta-partition-name określa partycję vbmeta . Pierwszy etap init inicjuje tę partycję przed zamontowaniem innych partycji. Argument tej flagi można pominąć, jeśli partycja vbmeta dla wpisu została już określona przez inny wpis fstab w poprzednim wierszu.

Poniższy przykład pokazuje wpisy fstab umożliwiające ustawienie partycji system , vendor i product jako partycji logicznych (dynamicznych).

#<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

W tym przykładzie dostawca określa partycję vbmeta przy użyciu flagi fs_mgr avb=vbmeta , ale product pomija argument vbmeta , ponieważ dostawca dodał już vbmeta do listy partycji.

Urządzenia z systemem Android 10 i nowszym muszą umieścić plik fstab w ramdysku i na partycji vendor .

Ramdysk

Lokalizacja pliku fstab na ramdysku zależy od sposobu, w jaki urządzenie korzysta z ramdysku.

Urządzenia z rozruchowym ramdyskiem muszą umieścić plik fstab w katalogu głównym rozruchowego RAMdysku. Jeżeli urządzenie posiada zarówno dysk rozruchowy, jak i dysk odzyskiwania, nie są wymagane żadne zmiany na dysku RAM odzyskiwania. Przykład:

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

Urządzenia korzystające z odzyskiwania jako ramdysku muszą użyć parametru wiersza poleceń jądra androidboot.force_normal_boot=1 aby zdecydować, czy uruchomić system Android, czy kontynuować uruchamianie w trybie odzyskiwania. Urządzenia uruchamiane z systemem Android 12 lub nowszym z jądrem w wersji 5.10 lub nowszej muszą użyć opcji bootconfig, aby przekazać parametr androidboot.force_normal_boot=1 . Na tych urządzeniach init pierwszego stopnia wykonuje operację przełączania katalogu głównego na /first_stage_ramdisk przed zamontowaniem partycji wczesnego montażu, więc urządzenia muszą umieścić plik fstab w $(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk . Przykład:

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

Sprzedawca

Wszystkie urządzenia muszą umieścić kopię pliku fstab w /vendor/etc . Dzieje się tak dlatego, że pierwszy etap init zwalnia ramdysk po zakończeniu wczesnego montowania partycji i wykonaniu operacji przełączania root w celu przeniesienia montowania z /system do / . Wszelkie późniejsze operacje wymagające dostępu do plików fstab muszą zatem korzystać z kopii w /vendor/etc . Przykład:

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

Wczesny montaż partycji, VBoot 1.0

Wymagania dotyczące wcześniejszego montowania partycji za pomocą VBoot 1.0 obejmują:

  1. Ścieżki węzłów urządzeń muszą używać by-name we wpisach fstab i Devicetree. Na przykład zamiast określać partycje za pomocą /dev/block/mmcblk0pX , upewnij się, że partycje mają nazwy, a węzeł urządzenia to /dev/block/…./by-name/{system,vendor,odm} .
  2. Ścieżki podane dla PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION i CUSTOM_IMAGE_VERITY_BLOCK_DEVICE w konfiguracji urządzenia dla produktu (tj. w device/ oem / project /device.mk ) muszą odpowiadać odpowiednim węzłom urządzeń blokowych określonych by-name w pliku fstab /devicetree wpisy. Przykład:
    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. Wpisy dostarczane poprzez nakładki drzewa urządzeń nie mogą się powtarzać we fragmentach pliku fstab . Na przykład, jeśli w drzewie urządzeń zostanie podany wpis dotyczący mount /vendor , plik fstab nie może powtarzać tego wpisu.
  4. Partycje wymagające verifyatboot nie mogą być montowane wcześniej (nie jest to obsługiwane).
  5. Tryb/stan zweryfikowanych partycji musi być określony w kernel_cmdline przy użyciu opcji androidboot.veritymode (istniejące wymaganie).

Wczesny montaż drzewa urządzeń, VBoot 1.0

W systemie Android 8.x i nowszych wersjach init analizuje drzewo urządzeń i tworzy wpisy fstab w celu zamontowania partycji na wczesnym etapie jej pierwszego etapu. Wpis fstab ma postać:

src mnt_point type mnt_flags fs_mgr_flags

Właściwości drzewa urządzeń są zdefiniowane tak, aby naśladować ten format:

  • Wpisy fstab muszą znajdować się w katalogu /firmware/android/fstab w drzewie urządzeń i muszą mieć zgodny ciąg znaków ustawiony na android,fstab .
  • Każdy węzeł w /firmware/android/fstab jest traktowany jako pojedynczy wpis fstab wczesnego podłączenia. Węzeł musi mieć zdefiniowane następujące właściwości:
    • dev musi wskazywać węzeł urządzenia reprezentujący by-name partycji
    • type musi być typem systemu plików (jak w plikach fstab )
    • mnt_flags musi być rozdzieloną przecinkami listą flag montowania (jak w plikach fstab )
    • fsmgr_flags musi być listą fs_mgr flags Androida (jak w plikach fstab )
  • Partycje A/B muszą mieć opcję slotselect fs_mgr .
  • Partycje z włączoną funkcją dm-verity muszą mieć opcję verify fs_mgr .

Przykład: /system i /vendor na N6P

Poniższy przykład pokazuje wczesny montaż drzewa urządzeń dla partycji system i vendor na Nexusie 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";
        };
      };
    };
  };
};

Przykład: /vendor na Pixelu

Poniższy przykład pokazuje wczesny montaż drzewa urządzeń dla /vendor na Pixelu (pamiętaj o dodaniu slotselect dla partycji podlegających 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";
        };
      };
    };
  };
};

Wczesny montaż partycji, VBoot 2.0

VBoot 2.0 to system Android Verified Boot (AVB) . Wymagania dotyczące wcześniejszego montowania partycji za pomocą VBoot 2.0 są następujące:

  1. Ścieżki węzłów urządzeń muszą używać by-name we wpisach fstab i Devicetree. Na przykład zamiast określać partycje za pomocą /dev/block/mmcblk0pX , upewnij się, że partycje mają nazwy, a węzeł urządzenia to /dev/block/…./by-name/{system,vendor,odm} .
  2. Zmienne systemowe kompilacji (takie jak PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION i CUSTOM_IMAGE_VERITY_BLOCK_DEVICE ) używane dla VBoot 1.0 NIE są wymagane dla VBoot 2.0. Zamiast tego należy zdefiniować zmienne kompilacji wprowadzone w VBoot 2.0 (w tym BOARD_AVB_ENABLE := true ). aby zapoznać się z pełną konfiguracją, zobacz Budowa integracji systemu dla AVB .
  3. Wpisy dostarczane poprzez nakładki drzewa urządzeń nie mogą się powtarzać we fragmentach pliku fstab . Na przykład, jeśli w drzewie urządzeń określisz wpis mount /vendor , plik fstab nie może powtarzać tego wpisu.
  4. VBoot 2.0 nie obsługuje verifyatboot , niezależnie od tego, czy wczesne montowanie jest włączone, czy nie.
  5. Tryb/stan prawdziwości zweryfikowanych partycji musi być określony w kernel_cmdline przy użyciu opcji androidboot.veritymode (istniejące wymaganie). Upewnij się, że uwzględniłeś następujące poprawki dla AVB:

Wczesny montaż drzewa urządzeń, VBoot 2.0

Konfiguracja w drzewie urządzeń dla VBoot 2.0 jest taka sama jak w VBoot 1.0 , z następującymi wyjątkami:

  • fsmgr_flag została zmieniona z verify na avb .
  • Wszystkie partycje z metadanymi AVB muszą znajdować się we wpisie VBMeta w drzewie urządzeń, nawet jeśli partycja nie jest montowana wcześnie (na przykład /boot ).

Przykład: /system i /vendor na N5X

Poniższy przykład przedstawia wczesne podłączenie drzewa urządzeń dla partycji system i vendor na Nexusie 5X. Pamiętaj, że:

  • /system jest montowany z AVB, a /vendor jest montowany bez weryfikacji integralności.
  • Ponieważ Nexus 5X nie ma partycji /vbmeta , więc vbmeta najwyższego poziomu znajduje się na końcu partycji /boot (więcej szczegółów znajdziesz na liście zmian AOSP ).
    / {
      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";
            };
          };
        };
      };
    };
    

Przykład: /vendor na Pixelu

Poniższy przykład pokazuje wczesną instalację /vendor na Pixelu. Pamiętaj, że:

  • We wpisie vbmeta określono więcej partycji, ponieważ te partycje są chronione przez AVB .
  • Wszystkie partycje AVB muszą być uwzględnione, nawet jeśli tylko /vendor jest wcześniej zamontowany.
  • Pamiętaj, aby dodać slotselect dla partycji podlegających 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";
            };
          };
        };
      };
    };