Wdróż partycje dynamiczne

partycjonowanie dynamiczne jest implementowane za pomocą narzędzia dm-linear device-mapper. w jądrze Linuksa. Partycja super zawiera metadane z listą nazw i zakresów blokowych każdej partycji dynamicznej w ciągu super. Na etapie init pierwszego etapu metadane są analizowane i weryfikowane, a urządzenia wirtualne blokujące są tworzone, reprezentować każdą partycję dynamiczną.

Przy zastosowaniu OTA partycje dynamiczne są tworzone automatycznie, a także usunąć jego rozmiar lub usunąć go w razie potrzeby. W przypadku urządzeń A/B są dostępne dwie kopie a zmiany są stosowane tylko do kopii reprezentującej docelowym boksie.

Partycje dynamiczne są zaimplementowane w przestrzeni użytkownika, więc wymagane są partycje w programie rozruchowym nie może być dynamiczny. Na przykład: boot, Elementy dtbo i vbmeta są odczytywane przez program rozruchowy, więc musi pozostać partycjami fizycznymi.

Każda partycja dynamiczna może należeć do grupy aktualizacji. Te grupy ograniczają maksymalną ilość miejsca, jaką mogą wykorzystywać partycje w danej grupie. Na przykład pola system i vendor mogą należeć do grupę, która ogranicza łączny rozmiar elementów system oraz vendor

Wdróż partycje dynamiczne na nowych urządzeniach

Z tej sekcji dowiesz się, jak wdrożyć partycje dynamiczne na nowych urządzeniach na urządzeniach z Androidem 10 i nowszym. Aby zaktualizować dostępnych na urządzeniach. Więcej informacji można znaleźć w sekcji Uaktualnianie Androida urządzenia.

Zmiany partycji

W przypadku urządzeń z Androidem 10 utwórz partycji o nazwie super. super partycja obsługuje wewnętrznie przedziały A/B, dzięki czemu urządzenia A/B nie muszą oddzielne partycje super_a i super_b. Wszystkie partycje AOSP tylko do odczytu, które nie są używane przez program rozruchowy, muszą musi być dynamiczny i musi zostać usunięty z tabeli partycji GUID (GPT). Partycje specyficzne dla dostawców nie muszą być dynamiczne i można je umieścić w GPT.

Aby oszacować rozmiar pola super, dodaj do niego rozmiary usuwania partycji z GPT. W przypadku urządzeń A/B parametr powinna zawierać rozmiary obu boksów. Rysunek 1 pokazuje przykładową tabelę partycji przed i po konwersji na dynamiczną partycji.

Układ tabeli partycjonowania
Rysunek 1. Nowy układ fizycznej tabeli partycji, gdy konwersja na partycje dynamiczne
.

Obsługiwane partycje dynamiczne:

  • System
  • Dostawca
  • Produkt
  • Systemowe
  • ODM

W przypadku urządzeń z Androidem 10 parametr opcja wiersza poleceń jądra androidboot.super_partition musi być pusta, aby polecenie sysprop Pole ro.boot.super_partition jest puste.

Wyrównanie partycji

Moduł mapowania urządzeń może działać mniej wydajnie, jeśli Partycja super nie jest prawidłowo wyrównana. Partycja super MUSI być wyrównana do minimalnej wartości wejścia-wyjścia rozmiar żądania zależy od warstwy blokowania. Domyślnie atrybut systemu kompilacji (za pomocą lpmake, który generuje super). Przyjmuje się, że dopasowanie o wielkości 1 MiB w przypadku każdej partycji dynamicznej. Dostawcy powinni jednak upewnij się, że partycja super jest prawidłowo wyrównana.

Aby określić minimalny rozmiar żądania urządzenia blokowego, sprawdzam sysfs. Na przykład:

# ls -l /dev/block/by-name/super
lrwxrwxrwx 1 root root 16 1970-04-05 01:41 /dev/block/by-name/super -> /dev/block/sda17
# cat /sys/block/sda/queue/minimum_io_size
786432

Wyrównanie partycji super możesz sprawdzić w w podobny sposób:

# cat /sys/block/sda/sda17/alignment_offset

Przesunięcie wyrównania MUSI wynosić 0.

Zmiany w konfiguracji urządzenia

Aby włączyć dynamiczne partycjonowanie, dodaj tę flagę do device.mk:

PRODUCT_USE_DYNAMIC_PARTITIONS := true

Zmiany w konfiguracji tablicy

Musisz ustawić rozmiar partycji super:

BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

Na urządzeniach A/B system kompilacji zgłasza błąd, jeśli łączny rozmiar obrazów partycji dynamicznych stanowi więcej niż połowa obrazu (super) wielkości partycji.

Listę partycji dynamicznych możesz skonfigurować w ten sposób. Dla: urządzeń za pomocą grup aktualizacji, wymień te grupy w Zmienna BOARD_SUPER_PARTITION_GROUPS. Nazwa każdej grupy następnie ma BOARD_group_SIZE i BOARD_group_PARTITION_LIST. W przypadku urządzeń A/B maksymalny rozmiar grupy powinien obejmować tylko jedną boks, bo nazwy grup są dodawane wewnętrznie do przedziałów.

Oto przykładowe urządzenie, które umieszcza wszystkie partycje w grupie pod tytułem example_dynamic_partitions:

BOARD_SUPER_PARTITION_GROUPS := example_dynamic_partitions
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_SIZE := 6442450944
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor product

Oto przykładowe urządzenie, które umieszcza usługi systemowe i usługi w grupie group_foo, vendor, product, i odm w group_bar:

BOARD_SUPER_PARTITION_GROUPS := group_foo group_bar
BOARD_GROUP_FOO_SIZE := 4831838208
BOARD_GROUP_FOO_PARTITION_LIST := system product_services
BOARD_GROUP_BAR_SIZE := 1610612736
BOARD_GROUP_BAR_PARTITION_LIST := vendor product odm
.
  • W przypadku urządzeń do uruchamiania wirtualnych A/B musi osiągnąć suma maksymalnych rozmiarów wszystkich grup. może wynosić maksymalnie:
    BOARD_SUPER_PARTITION_SIZE – narzut
    Przeczytaj artykuł Implementowanie wirtualnych testów A/B.
  • W przypadku urządzeń do uruchamiania A/B suma maksymalnych rozmiarów wszystkich grup musi będzie:
    BOARD_SUPER_PARTITION_SIZE / 2 – narzut
  • W przypadku urządzeń innych niż A/B i zmodernizowanych urządzeń A/B sumę maksymalnej rozmiary wszystkich grup muszą wynosić:
    BOARD_SUPER_PARTITION_SIZE – narzut
  • suma rozmiarów obrazów na każdej partycji w momencie kompilacji. w grupie aktualizacji nie może przekraczać maksymalnego rozmiaru grupy.
  • Narzut jest wymagany w obliczeniach, aby uwzględnić metadane, wyrównania itd. Rozsądny narzut to 4 MiB, ale może wybrać większy narzut w razie potrzeby urządzenia.

Dopasuj rozmiar partycji dynamicznych

Przed partycjami dynamicznymi ich rozmiary były nadmiernie przydzielane do aby zapewnić wystarczającą ilość miejsca na przyszłe aktualizacje. Rozmiar rzeczywisty i na większości partycji tylko do odczytu było dostępnych miejsca w systemie plików. W partycjach dynamicznych ta ilość wolnego miejsca jest jest bezużyteczna i może być używana do tworzenia partycji podczas aktualizacji OTA. Istotne jest, aby partycje nie traciły miejsca, przydzielone do minimalnego możliwego rozmiaru.

W przypadku obrazów ext4 tylko do odczytu system kompilacji automatycznie przydziela minimalny rozmiar, jeśli nie określono zakodowanego na stałe rozmiaru partycji. do obrazu system plików kompiluje tak, jak najwięcej niewykorzystanego miejsca. Dzięki temu urządzenie nie zostanie zmarnowane która może być używana na potrzeby OTA.

Obrazy ext4 można dodatkowo kompresować przez włączenie block- i do deduplikacji poziomu. Aby włączyć tę funkcję, użyj tej konfiguracji:

BOARD_EXT4_SHARE_DUP_BLOCKS := true

Jeśli automatyczne przydzielanie minimalnego rozmiaru partycji jest niepożądane, rozmiar partycji można kontrolować na 2 sposoby. Jako minimalnej ilości wolnego miejsca z BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE, lub określić BOARD_partitionIMAGE_PARTITION_SIZE, aby wymusić dynamicznych partycji do określonego rozmiaru. Żadna z tych opcji zalecane, o ile nie jest to konieczne.

Na przykład:

BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800

Powoduje to, że w systemie plików w product.img zostanie 50 MiB nieużywanego miejsca.

Zmiany systemu jako roota

Na urządzeniach z Androidem 10 nie można: użyj systemu jako roota.

Urządzenia z partycjami dynamicznymi (niezależnie od tego, czy są uruchamiane z systemem, czy zmodernizowane) dynamicznych partycji) nie może używać ustawienia systemowego jako roota. Jądro Linuksa nie może zinterpretuje partycję super, więc nie będzie można jej podłączyć. system. Urządzenie system zostało podłączone przez: pierwszego etapu init, który znajduje się w dysku pamięci RAM.

Nie ustawiaj pola BOARD_BUILD_SYSTEM_ROOT_IMAGE. W Android 10, Flaga BOARD_BUILD_SYSTEM_ROOT_IMAGE jest używana tylko do: pozwalają rozróżniać, czy system jest montowany przez jądro czy przez na pierwszym etapie init w ramdyzku.

Ustawianie wartości true z BOARD_BUILD_SYSTEM_ROOT_IMAGE powoduje błąd kompilacji, gdy PRODUCT_USE_DYNAMIC_PARTITIONS to także true.

Gdy BOARD_USES_RECOVERY_AS_BOOT ma wartość Prawda, para klucz-wartość jest utworzony jako Boot.img, który zawiera plik odzyskiwania i „ramdisk”. Wcześniej program rozruchowy używał jądra skip_initramfs wiersza poleceń, aby zdecydować, w którym trybie chcesz się uruchomić. Dla: na urządzeniach z Androidem 10, program rozruchowy NIE MOŻE przejść pomyślnie skip_initramfs do wiersza poleceń jądra. Zamiast tego program rozruchowy powinno przejść androidboot.force_normal_boot=1, aby pominąć przywracanie i uruchomić normalnego Androida. Urządzenia wprowadzone na rynek z Androidem 12 lub nowszego, musi używać polecenia rozruchowego do przekazywania androidboot.force_normal_boot=1.

Zmiany konfiguracji AVB

W przypadku korzystania z systemu Android Weryfikacja podczas uruchamiania 2.0, jeśli urządzenie nie korzysta z partycji łańcuchowej deskryptory, nie musisz niczego zmieniać. Jeśli używasz sieci łańcuchowej partycje, a jedna ze zweryfikowanych partycji jest dynamiczna, konieczne są zmiany.

Oto przykładowa konfiguracja urządzenia, które łączy się w sieci vbmeta dla: system i Partycje: vendor.

BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048
BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1

BOARD_AVB_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_VENDOR_ALGORITHM := SHA256_RSA2048
BOARD_AVB_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_VENDOR_ROLLBACK_INDEX_LOCATION := 1

W przypadku tej konfiguracji program rozruchowy oczekuje odnalezienia instancji vbmeta stopkę na końcu system i vendor partycje. Ponieważ te partycje nie są już widoczne dla programu rozruchowego (znajdują się w folderze super), dwa niezbędne są zmiany.

  • Dodaj vbmeta_system i vbmeta_vendor do tabeli partycji urządzenia. W przypadku urządzeń A/B dodaj vbmeta_system_a, vbmeta_system_b, vbmeta_vendor_a i vbmeta_vendor_b. Jeśli po dodaniu co najmniej jednej z tych partycji powinny mieć taki sam rozmiar. jako partycji vbmeta.
  • Zmień nazwy flag konfiguracji, dodając VBMETA_ i określ partycje, do których rozciąga się łańcuch:
    BOARD_AVB_VBMETA_SYSTEM := system
    BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1
    
    BOARD_AVB_VBMETA_VENDOR := vendor
    BOARD_AVB_VBMETA_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_VENDOR_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION := 1
    

Urządzenie może korzystać z jednej, obu lub żadnej z tych partycji. Zmiany są potrzebne tylko w przypadku tworzenia łańcuchów z partycją logiczną.

Zmiany programu rozruchowego AVB

Jeśli w programie rozruchowym umieszczona jest libavb, dołącz te poprawki:

Jeśli używasz partycji łańcuchowych, dołącz dodatkową poprawkę:

  • 49936b4c0109411fdd38bd4ba3a32a01c40439a9 – „libavb: obsługuj bloby vbmeta na początku partycjonowania”.

Zmiany w wierszu poleceń jądra

Musisz dodać nowy parametr androidboot.boot_devices do wiersza poleceń jądra. init używa jej do: włączyć dowiązania symboliczne /dev/block/by-name. Powinien to być komponent ścieżki urządzenia do bazowego dowiązania symbolicznego „nazwa” utworzonego przez ueventd, czyli /dev/block/platform/device-path/by-name/partition-name Urządzenia z Androidem 12 lub nowszym muszą używać programu rozruchowego, aby przekazać androidboot.boot_devices do init.

Na przykład: /dev/block/platform/soc/100000.ufshc/by-name/super, możesz dodać parametr wiersza poleceń w pliku BoardConfig.mk jako następujące:

BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
Możesz dodać parametr startconfig w pliku BoardConfig.mk w ten sposób:
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc

zmiany we fstab

Drzewo urządzeń i nakładki drzewa urządzeń nie mogą zawierać parametru fstab wpisów. Użyj pliku fstab, który będzie częścią dysku ramdisk.

W przypadku partycji logicznych należy wprowadzić zmiany w pliku fstab:

  • Pole flag fs_mgr musi zawierać flagę logical i flagi first_stage_mount, wprowadzonej w Androida 10, który wskazuje, że partycja ma być zamontowany na pierwszym etapie.
  • Partycja może określić avb=vbmeta partition name jako flagę fs_mgr, a następnie określoną wartość vbmeta partycja jest inicjowana w pierwszym etapie init przed którzy próbują podłączyć urządzenia.
  • Pole dev musi zawierać nazwę partycji.

Poniższe wpisy fstab ustawiają system, dostawcę i usługę jako logiczne na partycjach zgodnie z tymi regułami.

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

Skopiuj plik fstab do folderu ramdisk pierwszego etapu.

Zmiany w SELinux

Urządzenie z blokiem superpartycji musi być oznaczone etykietą super_block_device Na przykład: /dev/block/platform/soc/100000.ufshc/by-name/super, dodaj do file_contexts ten wiersz:

/dev/block/platform/soc/10000\.ufshc/by-name/super   u:object_r:super_block_device:s0

szybki rozruch

Program rozruchowy (lub inne narzędzie do Flasha spoza przestrzeni użytkownika) nie rozpoznaje dynamicznych partycjach, przez co nie można ich Flashować. Aby rozwiązać ten problem, musi korzystać z implementacji protokołu szybkiego rozruchu w przestrzeni użytkownika nazywanej oraz szybki rozruch.

Więcej informacji o wdrażaniu szybkiego rozruchu znajdziesz w artykule o przenoszeniu Szybkiego rozruchu do przestrzeni użytkownika.

adb remount

W przypadku deweloperów korzystających z kompilacji angielskich i userdebug adb remount jest bardzo przydatny przy szybkich iteracjach. Partycje dynamiczne mają pozycję adb remount, bo nie ma już bezpłatnych usług w każdym systemie plików. Aby rozwiązać ten problem, na urządzeniach można włączyć opcję nakładki. Dopóki w superpartycji jest wolne miejsce, adb remount automatycznie tworzy tymczasową dynamiczną kreację partycjonowanie, przy czym do zapisu używa funkcji Overlayfs. Partycja tymczasowa to o nazwie scratch, nie używaj więc tej nazwy dla innych partycji.

Aby dowiedzieć się, jak włączyć nakładki, przeczytaj artykuł o nakładkach README w AOSP.

Uaktualnij urządzenia z Androidem

Jeśli uaktualnisz urządzenie do Androida 10, Jeśli chcesz włączyć obsługę partycji dynamicznych w OTA, nie musisz zmienić wbudowaną tabelę partycji. Dodatkowa konfiguracja

Zmiany w konfiguracji urządzenia

Aby zmodernizować partycjonowanie dynamiczne, dodaj te flagi w device.mk:

PRODUCT_USE_DYNAMIC_PARTITIONS := true
PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true

Zmiany w konfiguracji tablicy

Musisz ustawić te zmienne tablicy:

  • Ustaw BOARD_SUPER_PARTITION_BLOCK_DEVICES na listę używanych urządzeń blokowych do przechowywania zakresów partycji dynamicznych. To jest lista nazw istniejących fizycznych partycji na urządzeniu.
  • W polu BOARD_SUPER_PARTITION_partition_DEVICE_SIZE ustaw rozmiary odpowiednio na każde urządzenie blokowe w regionie BOARD_SUPER_PARTITION_BLOCK_DEVICES. Jest to lista rozmiarów istniejących partycji fizycznych na urządzeniu. Zwykle jest to BOARD_partitionIMAGE_PARTITION_SIZE na istniejącej tablicy konfiguracji.
  • Cofnij ustawienie istniejącego BOARD_partitionIMAGE_PARTITION_SIZE dla wszystkich partycji w regionie BOARD_SUPER_PARTITION_BLOCK_DEVICES.
  • Ustaw BOARD_SUPER_PARTITION_SIZE na sumę BOARD_SUPER_PARTITION_partition_DEVICE_SIZE
  • Ustaw BOARD_SUPER_PARTITION_METADATA_DEVICE na urządzenie blokowe, w którym są przechowywane metadane partycji dynamicznej. Musi to być jedna z tych wartości: BOARD_SUPER_PARTITION_BLOCK_DEVICES Zwykle jest to system
  • Ustaw BOARD_SUPER_PARTITION_GROUPS, BOARD_group_SIZE i BOARD_group_PARTITION_LIST. Zobacz Zmiany konfiguracji tablicy na nowych urządzeniach .

Jeśli na przykład urządzenie ma już partycje systemowe oraz partycje dostawcy i chcesz przekonwertować dane do partycji dynamicznych i dodać nową partycję produktu podczas aktualizacji, ustaw tę konfigurację tablicy:

BOARD_SUPER_PARTITION_BLOCK_DEVICES := system vendor
BOARD_SUPER_PARTITION_METADATA_DEVICE := system

# Rename BOARD_SYSTEMIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE.
BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE := <size-in-bytes>

# Rename BOARD_VENDORIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE := <size-in-bytes>

# This is BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE + BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

# Configuration for dynamic partitions. For example:
BOARD_SUPER_PARTITION_GROUPS := group_foo
BOARD_GROUP_FOO_SIZE := <size-in-bytes>
BOARD_GROUP_FOO_PARTITION_LIST := system vendor product

Zmiany w SELinux

Urządzenia z blokami superpartycji muszą być oznaczone atrybutem super_block_device_type Jeśli na przykład urządzenie ma już system i vendor, chcesz ich używać jako blokad urządzeń do przechowywania zakresów partycji dynamicznych, a ich dowiązania symboliczne według nazw są oznaczone jako system_block_device:

/dev/block/platform/soc/10000\.ufshc/by-name/system   u:object_r:system_block_device:s0
/dev/block/platform/soc/10000\.ufshc/by-name/vendor   u:object_r:system_block_device:s0

Następnie dodaj do device.te ten wiersz:

typeattribute system_block_device super_block_device_type;

Inne konfiguracje znajdziesz w sekcji Implementowanie dynamicznych partycji na nowych urządzeniach.

Więcej informacji o aktualizacjach modernizacji znajdziesz w artykule OTA dla urządzeń A/B bez kreacji dynamicznych Partycje.

Obrazy fabryczne

W przypadku urządzenia uruchamianego na urządzeniu z obsługą partycji dynamicznych unikaj używania fastboot w przestrzeni użytkownika do flashowania obrazów fabrycznych. Uruchamianie w przestrzeni użytkownika wolniej niż w przypadku innych metod.

Aby rozwiązać ten problem, make dist tworzy teraz super.img obraz, który można wyświetlić bezpośrednio w partycji danych. Automatycznie grupuje zawartość operatorów logicznych partycje, co oznacza, że zawiera system.img, vendor.img i tak dalej, oprócz super metadanych partycji. Ten obraz może zostać wyświetlony bezpośrednio w super partycja bez dodatkowych narzędzi ani bez użycia dodatkowych narzędzi oraz szybki rozruch. Po utworzeniu komponentu super.img jest umieszczony w ${ANDROID_PRODUCT_OUT}

W przypadku urządzeń A/B uruchamianych z partycjami dynamicznymi: super.img zawiera obrazy w boksie A. Po przeprowadzeniu aktualizacji bezpośrednio superobraz, oznacz gniazdo A jako dostępne do rozruchu. urządzenia.

W przypadku modernizacji urządzeń make dist tworzy zestaw super_*.img obrazów, które można wyświetlać bezpośrednio na odpowiednie partycje fizyczne. Na przykład: make dist kompilacje super_system.img i super_vendor.img gdy BOARD_SUPER_PARTITION_BLOCK_DEVICES to system dostawcy. Te zdjęcia znajdują się w folderze OTA w target_files.zip

Dostrajanie urządzenia pamięci masowej dla narzędzia do mapowania urządzeń

Partycjonowanie dynamiczne obsługuje wiele niedeterministycznych mechanizmów mapowania urządzeń obiektów. Mogą one nie występować zgodnie z oczekiwaniami, dlatego musisz śledzić i aktualizować właściwości Androida wszystkich powiązanych partycji za pomocą parametru z ich bazowych urządzeń pamięci masowej.

Mechanizm w elemencie init śledzi montowania i asynchronicznie aktualizuje właściwości Androida. Czas potrzebny na to sprawdzenie nie jest gwarantowany aby mieściła się w konkretnym okresie, więc musisz dać im wystarczająco dużo czasu dla wszystkich on property reguły reakcji. Właściwości są dev.mnt.blk.<partition>, gdzie Wartość w kolumnie <partition> wynosi root, system, data lub vendor. Każda usługa jest powiązana z parametrem nazwa podstawowego urządzenia pamięci masowej, na przykład w tym przykładzie:

taimen:/ % getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [sda]
[dev.mnt.blk.firmware]: [sde]
[dev.mnt.blk.metadata]: [sde]
[dev.mnt.blk.persist]: [sda]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.vendor]: [dm-1]

blueline:/ $ getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [dm-4]
[dev.mnt.blk.metadata]: [sda]
[dev.mnt.blk.mnt.scratch]: [sda]
[dev.mnt.blk.mnt.vendor.persist]: [sdf]
[dev.mnt.blk.product]: [dm-2]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.system_ext]: [dm-3]
[dev.mnt.blk.vendor]: [dm-1]
[dev.mnt.blk.vendor.firmware_mnt]: [sda]

Język init.rc pozwala na rozszerzono w ramach reguł, a urządzenia pamięci masowej można dostroić przez platformę. w razie potrzeby za pomocą poleceń takich jak:

write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128
write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128

Po rozpoczęciu przetwarzania poleceń na drugim etapie init, Wartość epoll loop stanie się aktywna, a wartości zaczną się aktualizować. Pamiętaj jednak: ponieważ reguły powiązane z usługą są nieaktywne do późna init, nie można użyć na początkowym etapie uruchamiania do obsługi root, system lub vendor. Możesz się spodziewać, że read_ahead_kb jądra systemu będzie wystarczająca do momentu Skrypty init.rc mogą zostać zastąpione w early-fs (gdy po uruchomieniu różnych demonów i infrastruktur). Dlatego Google zaleca używasz funkcji on property w połączeniu z parametrem usługę kontrolowane przez usługę init.rc, np. sys.read_ahead_kb, odpowiednio dostosować czas operacji i zapobiec warunkom wyścigu, Przykłady:

on property:dev.mnt.blk.root=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.system=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.vendor=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.vendor}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.product=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system_ext}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.oem=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.oem}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.data=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on early-fs:
    setprop sys.read_ahead_kb ${ro.read_ahead_kb.boot:-2048}

on property:sys.boot_completed=1
   setprop sys.read_ahead_kb ${ro.read_ahead_kb.bootcomplete:-128}