Dieses Dokument enthält eine Anleitung für Partner zur Verbesserung der Startzeiten für bestimmte Android-Geräten Die Startzeit ist ein wichtiger Bestandteil der Systemleistung, Nutzer müssen warten, bis der Bootvorgang abgeschlossen ist, bevor sie das Gerät verwenden können. Für Geräte z. B. in Autos, bei denen der Kaltstart häufiger erfolgt, ein schneller Start Zeit ist entscheidend. Niemand möchte nur Dutzende von Sekunden warten, um einen Navigationsziel).
Dank Android 8.0 und mehreren Verbesserungen lassen sich die Startzeiten verkürzen. für eine Reihe von Komponenten. In der folgenden Tabelle sind diese Leistungen zusammengefasst. (gemessen an Google Pixel- und Pixel XL-Geräten)
Komponente | Verbesserung |
---|---|
Bootloader |
|
Gerätekernel |
|
E/A-Abstimmung |
|
init.*.rc |
|
Startanimation |
|
SELinux-Richtlinie | 0,2 Sek.von genfscon eingespart |
Bootloader optimieren
So optimieren Sie den Bootloader für kürzere Startzeiten:
- Für die Protokollierung:
<ph type="x-smartling-placeholder">
- </ph>
- Deaktivieren Sie das Schreiben von Protokollen in UART, da dies mit vielen Logging. (Auf Google Pixel-Geräten verlangsamt es den Bootloader um 1, 5 Sek.).
- Protokollieren Sie nur Fehlersituationen und legen Sie eventuell andere Informationen im Arbeitsspeicher fest mit einem separaten Mechanismus abzurufen.
- Erwägen Sie für die Kernel-Dekomprimierung die Verwendung von LZ4 für moderne Hardware. statt GZIP (Beispiel patch). Beachten Sie, dass Kernelkomprimierungsoptionen können unterschiedliche Lade- und Dekomprimierungszeiten. Einige Optionen sind möglicherweise besser geeignet als andere für Ihre bestimmte Hardware nutzen.
- Unnötige Wartezeiten auf Entprellung/Sondermodus prüfen und minimieren .
- Übergeben Sie die im Bootloader-Startzeit als cmdline an den Kernel.
- CPU-Takt und Parallelisierung prüfen (Unterstützung von Mehrkernen erforderlich) für das Laden des Kernels und die Initialisierung von E/A.
E/A-Effizienz optimieren
Die Verbesserung der E/A-Effizienz ist entscheidend, um die Startzeit zu verkürzen und das Lesen von Alles, was nicht notwendig ist, sollte erst nach dem Booten aufgeschoben werden (auf einem Google Pixel, etwa 1,2 GB Daten beim Booten gelesen werden.)
Dateisystem abstimmen
Der Linux-Kernel-Lesevorgang tritt ein, wenn eine Datei vom Anfang an oder werden sequenziell gelesen, was eine Feinabstimmung des E/A-Planers erfordert. Parameter speziell für das Booten (die eine andere Arbeitslast hat) als normale Apps).
Geräte, die nahtlose (A/B-)Updates unterstützen, profitieren stark vom Dateisystem. Feinabstimmung beim ersten Start (z.B. 20 Sekunden auf Google Pixel). Ein Beispiel: Wir haben die folgenden Parameter für das Google Pixel:
on late-fs # boot time fs tune # boot time fs tune write /sys/block/sda/queue/iostats 0 write /sys/block/sda/queue/scheduler cfq write /sys/block/sda/queue/iosched/slice_idle 0 write /sys/block/sda/queue/read_ahead_kb 2048 write /sys/block/sda/queue/nr_requests 256 write /sys/block/dm-0/queue/read_ahead_kb 2048 write /sys/block/dm-1/queue/read_ahead_kb 2048 on property:sys.boot_completed=1 # end boot time fs tune write /sys/block/sda/queue/read_ahead_kb 512 ...
Sonstiges
- Aktivieren Sie die dm-verity-Hash-Prefetch-Größe mit der Kernel-Konfiguration DM_VERITY_HASH_PREFETCH_MIN_SIZE (Standardgröße ist 128).
- Für eine bessere Stabilität des Dateisystems und eine geringere erzwungene Prüfung, Verwenden Sie bei jedem Start das neue Tool der ext4-Generation, indem Sie TARGET_USES_MKE2FS in BoardConfig.mk.
E/A analysieren
Um E/A-Aktivitäten während des Bootvorgangs zu verstehen, verwenden Sie ftrace-Kernel-Daten, die auch von systrace):
trace_event=block,ext4 in BOARD_KERNEL_CMDLINE
Nehmen Sie die folgenden Änderungen am Kernel vor, um den Dateizugriff für jede Datei aufzuschlüsseln (nur Entwicklungs-Kernel; nicht in Produktions-Kerneln verwenden):
diff --git a/fs/open.c b/fs/open.c index 1651f35..a808093 100644 --- a/fs/open.c +++ b/fs/open.c @@ -981,6 +981,25 @@ } EXPORT_SYMBOL(file_open_root); +static void _trace_do_sys_open(struct file *filp, int flags, int mode, long fd) +{ + char *buf; + char *fname; + + buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + return; + fname = d_path(&filp-<f_path, buf, PAGE_SIZE); + + if (IS_ERR(fname)) + goto out; + + trace_printk("%s: open(\"%s\", %d, %d) fd = %ld, inode = %ld\n", + current-<comm, fname, flags, mode, fd, filp-<f_inode-<i_ino); +out: + kfree(buf); +} + long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) { struct open_flags op; @@ -1003,6 +1022,7 @@ } else { fsnotify_open(f); fd_install(fd, f); + _trace_do_sys_open(f, flags, mode, fd);
Verwenden Sie die folgenden Skripts, um die Startleistung zu analysieren.
system/extras/boottime_tools/bootanalyze/bootanalyze.py
Misst die Startzeit anhand einer Aufschlüsselung wichtiger Schritte im Startvorgang.system/extras/boottime_tools/io_analysis/check_file_read.py boot_trace
Stellt Zugriffsinformationen zu jeder Datei bereit.system/extras/boottime_tools/io_analysis/check_io_trace_all.py boot_trace
Gibt eine Aufschlüsselung auf Systemebene an.
init.*.rc optimieren
Init ist die Brücke vom Kernel bis zur Festlegung des Frameworks. -Geräte verbringen in der Regel einige Sekunden in verschiedenen Init-Phasen.
Aufgaben parallel ausführen
Die aktuelle Android-Init-Instanz ist mehr oder weniger ein einzelner Thread-Prozess, dennoch einige Aufgaben parallel ausführen können.
- Führen Sie langsame Befehle in einem Shell-Skriptdienst aus und fügen Sie diese später durch
auf eine bestimmte Property warten. Android 8.0 unterstützt diesen Anwendungsfall mit einer neuen
wait_for_property
-Befehl. - Identifizieren Sie langsame Vorgänge in Init. Das System protokolliert den init-Befehl.
exec/wait_for_prop oder einer Aktion, die lange dauert (unter Android 8.0
dauert es länger als 50 ms). Hier einige Beispiele:
init: Command 'wait_for_coldboot_done' action=wait_for_coldboot_done returned 0 took 585.012ms
Ein Blick auf dieses Protokoll kann auf Verbesserungsmöglichkeiten hinweisen.
- Starten Sie frühzeitig Dienste und aktivieren Sie Peripheriegeräte im kritischen Pfad. Für Bei einigen SOCs müssen beispielsweise sicherheitsrelevante Dienste gestartet werden, SurfaceFlinger. Überprüfen Sie das Systemprotokoll, wenn ServiceManager die Meldung "wait for Dienst“ – ist normalerweise ein Zeichen dafür, dass ein abhängiger Dienst gestartet werden muss. .
- Entfernen Sie alle nicht verwendeten Dienste und Befehle in init.*.rc. Nichts verwendet in „Init im frühen Stadium“ sollte auf den Bootvorgang zurückgestellt werden.
Hinweis:Der Property-Dienst ist Teil des Initialisierungsprozesses. Das Aufrufen von
setproperty
beim Booten kann zu einer langen Verzögerung führen, wenn die Initialisierung in
integrierte Befehle.
Planer-Feinabstimmung verwenden
Verwenden Sie die Planerabstimmung für den frühen Start. Beispiel von einem Google Pixel:
on init # boottime stune write /dev/stune/schedtune.prefer_idle 1 write /dev/stune/schedtune.boost 100 on property:sys.boot_completed=1 # reset stune write /dev/stune/schedtune.prefer_idle 0 write /dev/stune/schedtune.boost 0 # or just disable EAS during boot on init write /sys/kernel/debug/sched_features NO_ENERGY_AWARE on property:sys.boot_completed=1 write /sys/kernel/debug/sched_features ENERGY_AWARE
Einige Dienste benötigen möglicherweise eine Prioritätserhöhung während des Startvorgangs. Beispiel:
init.zygote64.rc: service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server class main priority -20 user root ...
Zygote frühzeitig starten
Geräte mit dateibasierter Verschlüsselung können Zygote früher bei „zygote-start“ starten Trigger (standardmäßig wird Zygote in der Klasse "main" gestartet, die viel später zygote-start. Stellen Sie dabei sicher, dass Zygote auf allen CPUs (wie eine falsche CPUset-Einstellung kann dazu führen, dass Zygote auf bestimmten CPUs ausgeführt wird.
Energiesparmodus deaktivieren
Beim Starten des Geräts Energiespareinstellung für Komponenten wie UFS und/oder CPU kann deaktiviert werden.
Achtung:Der Energiesparmodus sollte in für mehr Effizienz.
on init # Disable UFS powersaving write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 0 write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 0 write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 0 write /sys/module/lpm_levels/parameters/sleep_disabled Y on property:sys.boot_completed=1 # Enable UFS powersaving write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 1 write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 1 write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 1 write /sys/module/lpm_levels/parameters/sleep_disabled N on charger # Enable UFS powersaving write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 1 write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 1 write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 1 write /sys/class/typec/port0/port_type sink write /sys/module/lpm_levels/parameters/sleep_disabled N
Nicht kritische Initialisierung aufschieben
Nicht kritische Initialisierung wie ZRAM kann auf boot_complete
verschoben werden.
on property:sys.boot_completed=1 # Enable ZRAM on boot_complete swapon_all /vendor/etc/fstab.${ro.hardware}
Startanimation optimieren
Beachten Sie die folgenden Tipps, um die Startanimation zu optimieren.
Vorzeitigen Start konfigurieren
Unter Android 8.0 kann die Startanimation frühzeitig gestartet werden, bevor Nutzerdaten bereitgestellt werden. -Partition an. Aber selbst bei Verwendung der neuen ext4-Toolchain in Android 8.0, fsck wird aus Sicherheitsgründen weiterhin regelmäßig ausgelöst, was zu einer Verzögerung bei und den Bootanimation-Dienst starten.
Damit die Bootanimation frühzeitig gestartet wird, teilen Sie die fstab-Bereitstellung in zwei Phasen auf:
- In der frühen Phase stellen Sie nur die Partitionen bereit, z. B.
system/
undvendor/
), die nicht ausgeführt werden müssen überprüft und startet dann Bootanimationsdienste und ihre Abhängigkeiten (z. B. Servicemanager und Surfaceflinger). - Stellen Sie in der zweiten Phase Partitionen (z. B.
data/
) bereit, die Tests ausführen.
Die Startanimation wird viel schneller (und in konstanter Zeit) gestartet, unabhängig von fsck aus.
Reinigung beenden
Nach Empfang des Exit-Signals spielt die Bootanimation den letzten Teil, die Länge die die Startzeit verlangsamen können. Ein System, das schnell startet, braucht keine lange Animationen, die vorgenommene Verbesserungen verdecken könnten. Wir empfehlen, sodass sowohl die Wiederholungsschleife als auch das Finale kurz sind.
SELinux optimieren
Mit den folgenden Tipps können Sie SELinux für kürzere Startzeiten optimieren.
- Verwenden Sie saubere reguläre Ausdrücke (Regex). Falsch formatierte Regex
kann zu viel Aufwand führen, wenn die SELinux-Richtlinie für
sys/devices
infile_contexts
. Beispiel: Der reguläre Ausdruck/sys/devices/.*abc.*(/.*)?
erzwingt versehentlich einen Scan aller/sys/devices
Unterverzeichnisse, die „abc“ enthalten, sodass Übereinstimmungen möglich sind für/sys/devices/abc
und/sys/devices/xyz/abc
. Wenn Sie diesen regulären Ausdruck auf/sys/devices/[^/]*abc[^/]*(/.*)?
ändern, eine Übereinstimmung nur für/sys/devices/abc
aktivieren. - Verschieben Sie die Labels zu genfscon. Diese bestehende SELinux-Funktion übergibt Dateizuordnungspräfixe an den Kernel in dem SELinux-Binärprogramm, bei dem der Kernel sie auf vom Kernel generierte Dateisystemen. Dadurch werden auch vom Kernel erstellte Dateien mit falschem Label behoben, Race-Bedingungen zwischen Userspace-Prozessen, die versuchen, auf diese Dateien vor der Umbenennung.
Tools und Methoden
Verwenden Sie die folgenden Tools, um Daten für Optimierungsziele zu erfassen.
Bootchart
Bootchart bietet eine Aufschlüsselung der CPU- und E/A-Last aller Prozesse für das gesamte System. System. Sie müssen das System-Image nicht neu erstellen und können vor der Verwendung von Systrace überprüfen.
So aktivieren Sie Bootchart:
adb shell 'touch /data/bootchart/enabled'
adb reboot
Rufen Sie nach dem Start das Boot-Diagramm ab:
$ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh
Wenn Sie fertig sind, löschen Sie /data/bootchart/enabled
, damit keine Daten erhoben werden
die Daten jedes Mal abrufen.
bootchart.png
nicht vorhanden ist, tun Sie
Folgendes:
<ph type="x-smartling-placeholder">- </ph>
- Führen Sie die folgenden Befehle aus:
sudo apt install python-is-python3
cd ~/Documents
git clone https://github.com/xrmx/bootchart.git
cd bootchart/pybootchartgui
mv main.py.in main.py
-
$ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh
aktualisieren um auf die lokale Kopie vonpybootchartgui
zu verweisen (Adresse:~/Documents/bootchart/pybootchartgui.py
)
Logo: Systrace
Systrace ermöglicht das Erfassen von Kernel- und Android-Traces während des Starts. Die Visualisierung von Systrace kann bei der Analyse eines bestimmten Problems während Systemstart hoch. Um jedoch die durchschnittliche oder die kumulierte Zahl während der ist es einfacher, den Kernel-Trace direkt zu überprüfen.
So aktivieren Sie Systrace beim Start:
- In
frameworks/native/cmds/atrace/atrace.rc
Folgendes ändern:write /sys/kernel/debug/tracing/tracing_on 0 write /sys/kernel/tracing/tracing_on 0
Sie haben folgende Optionen:
# write /sys/kernel/debug/tracing/tracing_on 0 # write /sys/kernel/tracing/tracing_on 0
- Fügen Sie in der Datei
device.mk
die folgende Zeile hinzu:PRODUCT_PROPERTY_OVERRIDES += debug.atrace.tags.enableflags=802922 PRODUCT_PROPERTY_OVERRIDES += persist.traced.enable=0
- Fügen Sie in der Datei
BoardConfig.mk
des Geräts Folgendes hinzu:BOARD_KERNEL_CMDLINE := ... trace_buf_size=64M trace_event=sched_wakeup,sched_switch,sched_blocked_reason,sched_cpu_hotplug
- Fügen Sie in der gerätespezifischen Datei
init.rc
Folgendes hinzu:on property:sys.boot_completed=1 // This stops tracing on boot complete write /d/tracing/tracing_on 0 write /d/tracing/events/ext4/enable 0 write /d/tracing/events/f2fs/enable 0 write /d/tracing/events/block/enable 0
-
Rufen Sie nach dem Start den Trace ab:
adb root && adb shell atrace --async_stop -z -c -o /data/local/tmp/boot_trace
adb pull /data/local/tmp/boot_trace
$ANDROID_BUILD_TOP/external/chromium-trace/systrace.py --from-file=boot_trace
Dadurch wird das Tracing aktiviert (standardmäßig deaktiviert).
Für detaillierte E/A-Analysen können Sie auch block und ext4 und f2fs hinzufügen.