Partycjonowanie dynamiczne jest realizowane za pomocą modułu dm-linear device-mapper w jądrze systemu Linux. Partycja super
zawiera metadane z listą nazw i zakresów bloków każdej partycji dynamicznej w super
. W pierwszej fazie init
te metadane są analizowane i weryfikowane, a wirtualne urządzenia blokowe są tworzone w celu reprezentowania każdej partycji dynamicznej.
Podczas stosowania aktualizacji OTA partycje dynamiczne są automatycznie tworzone, zmieniane lub usuwane w zależności od potrzeb. W przypadku urządzeń A/B istnieją 2 kopie metadanych, a zmiany są stosowane tylko do kopii reprezentującej docelowe miejsce.
Partycje dynamiczne są implementowane w przestrzeni użytkownika, więc partycje potrzebne do bootloadera nie mogą być dynamiczne. Na przykład boot
, dtbo
i vbmeta
są odczytywane przez program rozruchowy, więc muszą pozostać partycjami fizycznymi.
Każda partycja dynamiczna może należeć do grupy aktualizacji. Te grupy ograniczają maksymalną ilość miejsca, jaką mogą zajmować partycje w danej grupie.
Na przykład pola system
i vendor
mogą należeć do grupy, która ogranicza łączny rozmiar pól system
i vendor
.
Wdrażanie partycji dynamicznych na nowych urządzeniach
W tej sekcji znajdziesz szczegółowe informacje o wdrażaniu partycji dynamicznych na nowych urządzeniach z Androidem 10 lub nowszym. Aby zaktualizować istniejące urządzenia, przeczytaj artykuł Uaktualnianie urządzeń z Androidem.
Zmiany w partycjach
W przypadku urządzeń wprowadzanych na rynek z Androidem 10 utwórz partycję o nazwie super
. Partycja super
obsługuje wewnętrznie gniazda A/B, więc urządzenia A/B nie potrzebują
osobnych partycji super_a
i super_b
.
Wszystkie partycje AOSP tylko do odczytu, które nie są używane przez program rozruchowy, MUSZĄ być dynamiczne i MUSZĄ zostać usunięte z tabeli partycji GUID (GPT).
Partycje specyficzne dla dostawcy nie muszą być dynamiczne i mogą być umieszczane w GPT.
Aby oszacować rozmiar super
, dodaj rozmiary partycji usuwanych z GPT. W przypadku urządzeń A/B powinna ona zawierać rozmiar obu slotów. Ilustracja 1 przedstawia przykładową tabelę partycji przed przekształceniem w partycje dynamiczne i po nim.

Obsługiwane partycje dynamiczne to:
- System
- Dostawca
- Produkt
- System Ext
- ODM
W przypadku urządzeń wprowadzanych na rynek z Androidem 10 opcja wiersza poleceń jądra androidboot.super_partition
musi być pusta, aby polecenie sysprop ro.boot.super_partition
było puste.
Wyrównanie partycji
Moduł device-mapper może działać mniej wydajnie, jeśli partycja super
nie jest prawidłowo wyrównana. Partycja super
MUSI być wyrównana do minimalnego rozmiaru żądania wejścia/wyjścia określonego przez warstwę blokową. Domyślnie system kompilacji (za pomocą lpmake
, który generuje obraz partycji super
) zakłada, że wyrównanie 1 MiB jest wystarczające dla każdej partycji dynamicznej. Dostawcy powinni jednak zadbać o prawidłowe wyrównanie partycji super
.
Minimalny rozmiar żądania urządzenia blokowego możesz określić, sprawdzając 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 podobny sposób:
# cat /sys/block/sda/sda17/alignment_offset
Przesunięcie wyrównania MUSI wynosić 0.
Zmiany konfiguracji urządzenia
Aby włączyć dynamiczne partycjonowanie, dodaj w obiekcie device.mk
tę flagę:
PRODUCT_USE_DYNAMIC_PARTITIONS := true
Zmiany konfiguracji tablicy
Musisz ustawić rozmiar partycji super
:
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>
W przypadku urządzeń A/B system kompilacji zgłasza błąd, jeśli łączny rozmiar obrazów partycji dynamicznych jest większy niż połowa rozmiaru partycji super
.
Listę partycji dynamicznych możesz skonfigurować w ten sposób: W przypadku urządzeń korzystających z grup aktualizacji wymień grupy w zmiennej BOARD_SUPER_PARTITION_GROUPS
. Każda nazwa grupy ma zmienne BOARD_group_SIZE
i BOARD_group_PARTITION_LIST
.
W przypadku urządzeń A/B maksymalny rozmiar grupy powinien obejmować tylko 1 miejsce, ponieważ nazwy grup mają wewnętrznie dodawany sufiks miejsca.
Oto przykład urządzenia, które umieszcza wszystkie partycje w grupie o nazwie 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ład urządzenia, które umieszcza usługi systemowe i usługi Google w group_foo
, a 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ń z wirtualnym testem A/B suma maksymalnych rozmiarów wszystkich grup musi być mniejsza lub równa:
BOARD_SUPER_PARTITION_SIZE
– narzut
Więcej informacji znajdziesz w artykule Wdrażanie wirtualnego testu A/B. -
W przypadku urządzeń z wdrożeniem A/B suma maksymalnych rozmiarów wszystkich grup musi wynosić:
BOARD_SUPER_PARTITION_SIZE
/ 2 – narzut -
W przypadku urządzeń bez A/B i urządzeń A/B po modernizacji suma maksymalnych rozmiarów wszystkich grup musi wynosić:
BOARD_SUPER_PARTITION_SIZE
– narzut - Podczas kompilacji suma rozmiarów obrazów każdej partycji w grupie aktualizacji nie może przekraczać maksymalnego rozmiaru grupy.
- Narzut jest wymagany w obliczeniach, aby uwzględnić metadane, dopasowania itp. Rozsądny narzut to 4 MiB, ale w razie potrzeby możesz wybrać większy.
Określanie rozmiaru partycji dynamicznych
Przed wprowadzeniem partycji dynamicznych rozmiary partycji były zawyżane, aby zapewnić wystarczającą ilość miejsca na przyszłe aktualizacje. Rzeczywisty rozmiar został przyjęty w takiej postaci, w jakiej był, a większość partycji tylko do odczytu miała pewną ilość wolnego miejsca w systemie plików. W przypadku partycji dynamicznych to wolne miejsce jest bezużyteczne i może być wykorzystane do powiększania partycji podczas aktualizacji OTA. Konieczne jest zapewnienie, że partycje nie marnują miejsca i mają minimalny możliwy rozmiar.
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. System kompilacji dopasowuje obraz tak, aby system plików miał jak najmniej niewykorzystanego miejsca. Dzięki temu urządzenie nie marnuje miejsca, które można wykorzystać na aktualizacje OTA.
Dodatkowo obrazy ext4 można dalej kompresować, włączając deduplikację na poziomie bloku. Aby to włączyć, 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. Możesz określić minimalną ilość wolnego miejsca za pomocą parametru BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE
lub użyć parametru BOARD_partitionIMAGE_PARTITION_SIZE
, aby wymusić określony rozmiar partycji dynamicznych. Żadna z tych opcji nie jest zalecana, jeśli nie jest niezbędna.
Na przykład:
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
Wymusza to, aby system plików w product.img
miał 50 MiB wolnego miejsca.
Zmiany w systemie jako katalogu głównym
Urządzenia wprowadzane na rynek z Androidem 10 nie mogą korzystać z systemu jako roota.
Urządzenia z partycjami dynamicznymi (niezależnie od tego, czy są one dostępne od początku, czy zostały dodane później) nie mogą używać systemu jako katalogu głównego. Jądro Linuksa nie może interpretować partycji super
, więc nie może jej zamontować.system
system
jest teraz zamontowany przez init
pierwszego etapu, który znajduje się w ramdysku.
Nie ustawiaj BOARD_BUILD_SYSTEM_ROOT_IMAGE
. W Androidzie 10 flaga BOARD_BUILD_SYSTEM_ROOT_IMAGE
służy tylko do rozróżniania, czy system jest montowany przez jądro, czy przez init
pierwszego etapu w ramdysku.
Ustawienie wartości BOARD_BUILD_SYSTEM_ROOT_IMAGE
na true
powoduje błąd kompilacji, gdy PRODUCT_USE_DYNAMIC_PARTITIONS
ma również wartość true
.
Gdy wartość BOARD_USES_RECOVERY_AS_BOOT
jest ustawiona na „true”, obraz przywracania jest tworzony jako boot.img i zawiera dysk RAM przywracania. Wcześniej program rozruchowy używał parametru wiersza poleceń jądra skip_initramfs
, aby określić, w którym trybie ma się uruchomić. W przypadku urządzeń z Androidem 10 program rozruchowy NIE MOŻE przekazywać skip_initramfs
do wiersza poleceń jądra. Zamiast tego program rozruchowy powinien przekazać wartość androidboot.force_normal_boot=1
, aby pominąć przywracanie i uruchomić normalną wersję Androida. Urządzenia z Androidem 12 lub nowszym muszą używać bootconfig do przekazywania androidboot.force_normal_boot=1
.
Zmiany konfiguracji AVB
Jeśli używasz weryfikacji podczas uruchamiania w Androidzie w wersji 2.0, a urządzenie nie korzysta z połączonych deskryptorów partycji, nie musisz wprowadzać żadnych zmian. Jeśli jednak używasz połączonych partycji, a jedna z nich jest dynamiczna, konieczne są zmiany.
Oto przykładowa konfiguracja urządzenia, które łączy vbmeta
z partycjami system
i 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 tej konfiguracji program rozruchowy oczekuje znalezienia stopki vbmeta na końcu partycji system
i vendor
. Ponieważ te partycje nie są już widoczne dla programu rozruchowego (znajdują się w super
), konieczne są 2 zmiany.
-
Dodaj partycje
vbmeta_system
ivbmeta_vendor
do tabeli partycji urządzenia. W przypadku urządzeń A/B dodajvbmeta_system_a
,vbmeta_system_b
,vbmeta_vendor_a
ivbmeta_vendor_b
. Jeśli dodajesz co najmniej 1 z tych partycji, powinny one mieć taki sam rozmiar jak partycjavbmeta
. -
Zmień nazwy flag konfiguracji, dodając
VBMETA_
, i określ, na które partycje ma się rozciągać łączenie: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 używać jednej z tych partycji, obu lub żadnej z nich. Zmiany są potrzebne tylko w przypadku łączenia z partycją logiczną.
Zmiany w programie rozruchowym AVB
Jeśli program rozruchowy ma wbudowaną bibliotekę libavb, uwzględnij te poprawki:
- 818cf56740775446285466eda984acedd4baeac0 – „libavb: Only query partition GUIDs when the cmdline needs them.”
- 5abd6bc2578968d24406d834471adfd995a0c2e9 – „Zezwól na brak partycji systemowej”
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 – „Fix AvbSlotVerifyData->cmdline might be NULL”
Jeśli używasz połączonych partycji, dodaj dodatkową poprawkę:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 – „libavb: Support vbmeta blobs in beginning of partition.”
Zmiany w wierszu poleceń jądra
Do wiersza poleceń jądra należy dodać nowy parametr androidboot.boot_devices
. Jest używany przez init
do włączania /dev/block/by-name
linków symbolicznych. Powinien to być komponent ścieżki urządzenia do bazowego dowiązania symbolicznego o nazwie utworzonego przez ueventd
, czyli /dev/block/platform/device-path/by-name/partition-name
.
Urządzenia z Androidem 12 lub nowszym muszą używać bootconfig, aby przekazywać androidboot.boot_devices
do init
.
Jeśli na przykład symlink do superpartycji według nazwy to
/dev/block/platform/soc/100000.ufshc/by-name/super
,
możesz dodać parametr wiersza poleceń w pliku BoardConfig.mk w ten sposób:
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc
zmiany w pliku fstab,
Drzewo urządzeń i nakładki drzewa urządzeń nie mogą zawierać wpisów fstab. Użyj pliku fstab, który będzie częścią dysku RAM.
W przypadku partycji logicznych należy wprowadzić zmiany w pliku fstab:
-
Pole flagi fs_mgr musi zawierać flagę
logical
i flagęfirst_stage_mount
wprowadzoną w Androidzie 10, która wskazuje, że partycja ma być zamontowana w pierwszym etapie. -
Partycja może określać
avb=vbmeta partition name
jako flagęfs_mgr
, a następnie określona partycjavbmeta
jest inicjowana przez pierwszy etapinit
przed próbą zamontowania jakichkolwiek urządzeń. -
Pole
dev
musi zawierać nazwę partycji.
Poniższe wpisy fstab ustawiają system, dostawcę i produkt jako partycje logiczne zgodnie z powyższymi 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 dysku RAM pierwszego etapu.
Zmiany w SELinux
Urządzenie blokowe superpartycji musi być oznaczone etykietą super_block_device
. Jeśli na przykład symlink do superpartycji według nazwy to
/dev/block/platform/soc/100000.ufshc/by-name/super
,
dodaj do pliku file_contexts
ten wiersz:
/dev/block/platform/soc/10000\.ufshc/by-name/super u:object_r:super_block_device:s0
fastbootd
Bootloader (ani żadne narzędzie do flashowania spoza przestrzeni użytkownika) nie obsługuje partycji dynamicznych, więc nie może ich flashować. Aby rozwiązać ten problem, urządzenia muszą korzystać z implementacji protokołu fastboot w przestrzeni użytkownika, zwanej fastbootd.
Więcej informacji o wdrażaniu fastbootd znajdziesz w artykule Przenoszenie fastboot do przestrzeni użytkownika.
adb remount
W przypadku deweloperów korzystających z kompilacji eng lub userdebug adb remount
jest niezwykle przydatne do szybkiego iterowania. Partycje dynamiczne stanowią problem dla adb remount
, ponieważ w każdym systemie plików nie ma już wolnego miejsca. Aby rozwiązać ten problem, urządzenia mogą włączyć overlayfs. Dopóki w superpartycji jest wolne miejsce, adb remount
automatycznie tworzy tymczasową partycję dynamiczną i używa overlayfs do zapisywania danych. Partycja tymczasowa ma nazwę scratch
, więc nie używaj tej nazwy w przypadku innych partycji.
Więcej informacji o tym, jak włączyć overlayfs, znajdziesz w pliku README overlayfs w AOSP.
Uaktualnianie urządzeń z Androidem
Jeśli uaktualnisz urządzenie do Androida 10 i chcesz uwzględnić w aktualizacji OTA obsługę partycji dynamicznych, nie musisz zmieniać wbudowanej tabeli partycji. Wymaga to dodatkowej konfiguracji.
Zmiany konfiguracji urządzenia
Aby dopasować partycjonowanie dynamiczne, dodaj te flagi w device.mk
:
PRODUCT_USE_DYNAMIC_PARTITIONS := true PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true
Zmiany 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. Jest to lista nazw istniejących partycji fizycznych na urządzeniu. - Ustaw
BOARD_SUPER_PARTITION_partition_DEVICE_SIZE
na rozmiary poszczególnych urządzeń blokowych wBOARD_SUPER_PARTITION_BLOCK_DEVICES
. Jest to lista rozmiarów istniejących partycji fizycznych na urządzeniu. Zwykle jest toBOARD_partitionIMAGE_PARTITION_SIZE
w konfiguracjach istniejących tablic. - Usuń istniejące
BOARD_partitionIMAGE_PARTITION_SIZE
ze wszystkich partycji wBOARD_SUPER_PARTITION_BLOCK_DEVICES
. - Ustaw wartość
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 przechowywane są metadane partycji dynamicznej. Musi to być jedna z tych wartości:BOARD_SUPER_PARTITION_BLOCK_DEVICES
. Zwykle jest to ustawione nasystem
. - Ustaw odpowiednio
BOARD_SUPER_PARTITION_GROUPS
,BOARD_group_SIZE
iBOARD_group_PARTITION_LIST
. Szczegółowe informacje znajdziesz w sekcji Zmiany w konfiguracji tablic na nowych urządzeniach.
Jeśli na przykład urządzenie ma już partycje systemową i dostawcy, a podczas aktualizacji chcesz przekonwertować je na partycje dynamiczne i dodać nową partycję produktu, ustaw tę konfigurację płyty:
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 blokowe superpartycji muszą być oznaczone atrybutem super_block_device_type
. Jeśli na przykład urządzenie ma już partycje system
i vendor
, chcesz ich używać jako urządzeń blokowych do przechowywania zakresów partycji dynamicznych, a ich dowiązania symboliczne według nazwy 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 pliku device.te
ten wiersz:
typeattribute system_block_device super_block_device_type;
Inne konfiguracje znajdziesz w artykule Wdrażanie partycji dynamicznych na nowych urządzeniach.
Więcej informacji o aktualizacjach typu retrofit znajdziesz w artykule OTA na urządzeniach A/B bez partycji dynamicznych.
Obrazy fabryczne
W przypadku urządzenia, które obsługuje partycje dynamiczne, unikaj używania narzędzia fastboot w przestrzeni użytkownika do flashowania obrazów fabrycznych, ponieważ uruchamianie w przestrzeni użytkownika jest wolniejsze niż inne metody flashowania.
Aby rozwiązać ten problem, make dist
tworzy teraz dodatkowy super.img
obraz, który można przesłać bezpośrednio do partycji super. Automatycznie łączy zawartość partycji logicznych, co oznacza, że zawiera system.img
, vendor.img
itd. oraz metadane partycji super
. Ten obraz można wgrać bezpośrednio do partycji super
bez dodatkowych narzędzi i bez użycia fastbootd. Po kompilacji plik super.img
zostanie umieszczony w folderze ${ANDROID_PRODUCT_OUT}
.
W przypadku urządzeń A/B, które są wprowadzane na rynek z partycjami dynamicznymi, super.img
zawiera obrazy w gnieździe A. Po bezpośrednim wgraniu obrazu super oznacz gniazdo A jako rozruchowe przed ponownym uruchomieniem urządzenia.
W przypadku urządzeń modernizowanych make dist
tworzy zestaw super_*.img
obrazów, które można wgrać bezpośrednio do odpowiednich partycji fizycznych. Na przykład make dist
tworzy super_system.img
i super_vendor.img
, gdy BOARD_SUPER_PARTITION_BLOCK_DEVICES
jest dostawcą systemu. Te obrazy są umieszczane w folderze OTA w lokalizacji target_files.zip
.
Dostrajanie urządzenia pamięciowego mapowania urządzeń
Partycjonowanie dynamiczne obsługuje wiele niedeterministycznych obiektów mapowania urządzeń. Nie wszystkie mogą zostać utworzone zgodnie z oczekiwaniami, dlatego musisz śledzić wszystkie punkty montowania i aktualizować właściwości Androida wszystkich powiązanych partycji za pomocą ich urządzeń pamięci masowej.
Mechanizm w init
śledzi punkty montowania i asynchronicznie aktualizuje właściwości Androida. Nie możemy zagwarantować, że ten proces zakończy się w określonym czasie, więc musisz zapewnić wystarczająco dużo czasu na reakcję wszystkich on property
wyzwalaczy. Właściwości to dev.mnt.blk.<partition>
, gdzie <partition>
to np. root
, system
, data
lub vendor
. Każda właściwość jest powiązana z nazwą podstawowego urządzenia pamięci masowej, jak pokazano w tych przykładach:
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
umożliwia rozszerzanie właściwości Androida w ramach reguł, a urządzenia pamięci masowej mogą być dostrajane przez platformę w razie potrzeby za pomocą takich poleceń:
write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128 write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128
Gdy w drugim etapie init
rozpocznie się przetwarzanie polecenia, epoll loop
stanie się aktywny, a wartości zaczną się aktualizować. Jednak ponieważ wyzwalacze usługi nie są aktywne do późnego init
, nie można ich używać na początkowych etapach uruchamiania do obsługi root
, system
ani vendor
. Możesz oczekiwać, że domyślna wartość jądra read_ahead_kb
będzie wystarczająca, dopóki skrypty init.rc
nie będą mogły jej zastąpić w early-fs
(gdy uruchomią się różne demony i usługi). Dlatego Google zaleca używanie funkcji on property
w połączeniu z właściwością kontrolowaną przez init.rc
, np. sys.read_ahead_kb
, aby zarządzać czasem trwania operacji i zapobiegać sytuacjom wyścigu, jak w tych przykładach:
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}