Auf dieser Seite werden die Änderungen am Binder-Treiber in Android 8 beschrieben, Details zur Verwendung von Binder IPC und listet die erforderlichen SELinux-Richtlinien auf.
Änderungen am Binder-Treiber
Ab Android 8 kommunizieren das Android-Framework und HALs nun mit miteinander unter Verwendung von Binder. Da durch diese Kommunikation die Bindung enthält Android 8 mehrere Verbesserungen, die das Binder-IPC aufrecht erhalten sollen. schnell. SoC-Anbieter und OEMs sollten direkt aus den relevanten Android-4.4, Android-4.9 und höher der kernel/common-Projekt zugeordnet.
Mehrere Binder-Domains (Kontexte)
Common 4.4 und höher, einschließlich UpstreamUm den Binder-Traffic zwischen Framework (geräteunabhängig) und Anbietercode (gerätespezifischer) wurde mit Android 8 das Konzept eines Bindeunternehmens eingeführt. Kontext. Jeder Binder-Kontext hat seinen eigenen Geräteknoten und seinen eigenen Kontext (Dienst-)Manager. Du kannst nur über das Gerät auf den Kontextmanager zugreifen Knoten, zu dem er gehört, und wenn ein Binder-Knoten über einen bestimmten Kontext ist, ist sie aus diesem Kontext nur über einen anderen Prozess zugänglich. um die Domains vollständig voneinander zu isolieren. Einzelheiten zur Verwendung finden Sie unter vndbinder und vndservicemanager.
Streudiagramm
Common 4.4 und höher, einschließlich UpstreamIn früheren Android-Versionen wurden alle Daten in einem Binder-Aufruf kopiert. dreimal:
- Sobald es in eine
Parcel
im Anrufprozess - Kopieren Sie im Kernel-Treiber das
Parcel
in das Ziel, Prozess - Einmal, um
Parcel
im Zielprozess neu zu konfigurieren
Android 8 nutzt
Streudiagramm
, um die Anzahl der Kopien von 3 auf 1 zu reduzieren. Anstelle von
Wenn Daten zuerst in einem Parcel
serialisiert werden, bleiben die Daten in ihrem ursprünglichen Zustand.
und der Treiber kopiert sie sofort in die Ziel-
. Sobald sich die Daten im Zielprozess befinden,
ist das gleiche Layout und die Daten können ohne weitere Kopie gelesen werden.
Detailliertes Sperren
Common 4.4 und höher, einschließlich UpstreamIn früheren Android-Releases verwendete der Binder-Treiber eine globale Sperre, um gleichzeitigen Zugriff auf kritische Datenstrukturen. Obwohl es nur minimale Konflikt um die Sperre, bestand das Hauptproblem darin, das Schloss überbrachte und dann wieder aufgehoben wurde, Threads mit höherer Priorität, die dieselbe Sperre benötigen. Dies führte zu einer Verzögerung im Plattform.
Die ersten Versuche zur Lösung dieses Problems bestand darin, das vorzeitige Beenden zu deaktivieren, während mit der globalen Sperre. Dabei handelte es sich jedoch eher um einen Hack als um eine echte Lösung, und schließlich von vorgelagerten Kanälen abgelehnt und verworfen. Nachfolgende Versuche konzentrierter sich darauf, die Sperre differenzierter zu gestalten. Diese Version wurde bereits auf Pixel-Geräten seit Januar 2017. Während die meisten dieser Änderungen veröffentlicht wurden, wurden in den nachfolgenden Versionen wesentliche Verbesserungen vorgenommen.
Nachdem wir kleine Probleme bei der detaillierten Sperrimplementierung identifiziert haben, eine verbesserte Lösung mit einer anderen Sperrarchitektur entwickelt und Änderungen in allen gängigen Kernel-Zweigen. Wir testen dies weiter Implementierung auf einer großen Anzahl verschiedener Geräte, da wir uns keinerlei immer noch behobene Probleme behoben haben, ist dies die empfohlene Implementierung für den Versand von Geräten mit Android 8.
Prioritätsübernahme in Echtzeit
Common-4.4 und Common-4.9 (Upstream demnächst verfügbar)Der Binder-Treiber hat schon immer eine positive Prioritätsübernahme unterstützt. Als zunehmende Anzahl von Prozessen in Android mit Echtzeitpriorität, in einigen jetzt ist es sinnvoll, dass bei einem Echtzeit-Thread ein Binder-Aufruf erfolgt, Thread in dem Prozess, der diesen Aufruf verarbeitet, auch mit Echtzeitpriorität ausgeführt wird. Bis diese Anwendungsfälle unterstützen, implementiert Android 8 jetzt die Prioritätsübernahme in Echtzeit. im Binder-Treiber ein.
Zusätzlich zur Prioritätsübernahme auf Transaktionsebene wird die Knotenpriorität Übernahme ermöglicht einem Knoten (Binder-Dienstobjekt) die Angabe eines Minimums Priorität, mit der Aufrufe an diesen Knoten ausgeführt werden sollen. Vorherige Versionen von Android unterstützt bereits die Übernahme der Knotenpriorität mit schönen Werten, aber Android 8 unterstützt die Knotenübernahme von Richtlinien für die Echtzeitplanung.
Änderungen im Userspace
Android 8 umfasst alle Änderungen am Nutzerbereich, die für die aktuelle
binder-Treiber im gemeinsamen Kernel mit einer Ausnahme:
-Implementierung zum Deaktivieren der Echtzeit-Prioritätsübernahme für
/dev/binder
hat einen
ioctl angeben. Bei späteren Entwicklungen wurde die Prioritätssteuerung geändert.
Übernahme auf eine detailliertere Methode, die pro Bindermodus (und nicht pro
Kontext). Daher ist „ioctl“ nicht im gemeinsamen Branch von Android enthalten, sondern ist stattdessen
in unseren gemeinsamen Kerneln gesendet.
Durch diese Änderung wird die
Prioritätsübernahme in Echtzeit durch
Standardeinstellung für jeden Knoten. Das Android Performance-Team hat es gefunden
eine Echtzeit-Prioritätsübernahme für alle Knoten im
hwbinder
-Domain. Um diesen Effekt zu erzielen,
dieser Änderung im Userspace.
SHAs für gängige Kernel
Um die erforderlichen Änderungen am Binder-Treiber zu erhalten, führen Sie eine Synchronisierung mit dem entsprechenden SHA-Wert durch:
- Common-3,18
cc8b90c121de ANDROID: binder: prio-Berechtigungen bei Wiederherstellung nicht überprüfen. - Common-4,4
76b376eac7a2 ANDROID: binder: prio-Berechtigungen bei Wiederherstellung nicht überprüfen. - Common-4,9
ecd972d4f9b5 ANDROID: binder: „prio-Berechtigungen“ bei der Wiederherstellung nicht prüfen.
Mit Binder IPC arbeiten
In der Vergangenheit wurde bei den Prozessen von Zulieferunternehmen Binder-Interprozesskommunikation eingesetzt
(IPC) verwendet. In Android 8: Der Geräteknoten /dev/binder
wird ausschließlich in Framework-Prozessen eingebunden, was bedeutet, dass Zulieferunternehmen keine
darauf zugreifen können. Anbieterprozesse können auf /dev/hwbinder
zugreifen, aber
müssen ihre AIDL-Schnittstellen zur Verwendung von HIDL konvertieren. Für Anbieter, die mit der
mit AIDL-Schnittstellen zwischen Anbieterprozessen unterstützt Android Binder IPC als
beschrieben. Unter Android 10 ermöglicht die stabile AIDL alle
Prozesse, um /dev/binder
zu verwenden und gleichzeitig Stabilität zu gewährleisten
sorgt dafür, dass HIDL und /dev/hwbinder
gelöst werden. So verwendest du die stabile Version
AIDL, siehe
AIDL für HALs
vndbinder
Android 8 unterstützt eine neue Binder-Domain, auf die Anbieterdienste zugreifen können
mit /dev/vndbinder
statt /dev/binder
. Mit der
/dev/vndbinder
hinzugefügt wurde, hat Android jetzt die folgenden drei
IPC-Domains:
IPC-Domain | Beschreibung |
---|---|
/dev/binder |
IPC zwischen Framework-/App-Prozessen mit AIDL-Schnittstellen |
/dev/hwbinder |
IPC zwischen Framework-/Anbieterprozessen mit HIDL-Schnittstellen
IPC zwischen Anbieterprozessen mit HIDL-Schnittstellen |
/dev/vndbinder |
IPC zwischen Anbieter-/Anbieterprozessen mit AIDL Interfaces |
Prüfen Sie die Kernel-Konfiguration, damit /dev/vndbinder
angezeigt wird
Element CONFIG_ANDROID_BINDER_DEVICES
ist festgelegt auf
"binder,hwbinder,vndbinder"
(Dies ist die Standardeinstellung im
gewöhnliche Kernbäume).
Normalerweise öffnen die Prozesse des Zulieferunternehmens den Binder-Treiber nicht direkt, sondern
für die Userspace-Bibliothek „libbinder
“, die die
binder-Treiber. Methode für ::android::ProcessState()
hinzufügen
wählt den Binder-Treiber für libbinder
aus. Die Prozesse von Zulieferunternehmen sollten
Rufen Sie diese Methode auf, bevor Sie ProcessState,
aufrufen.
IPCThreadState
oder vor allgemeinen Binder-Aufrufen. Bis
verwenden: Platzieren Sie den folgenden Aufruf nach dem main()
eines Anbieterprozesses.
(Client und Server):
ProcessState::initWithDriver("/dev/vndbinder");
vndservicemanager
Zuvor waren Binder-Dienste bei servicemanager
registriert.
wo sie von anderen Prozessen abgerufen werden können. In Android 8
servicemanager
wird jetzt ausschließlich vom Framework und der App verwendet
nicht mehr auf sie zugreifen.
Anbieterdienste können jetzt jedoch vndservicemanager
verwenden, eine neue
Instanz von servicemanager
, die /dev/vndbinder
verwendet
anstelle von /dev/binder
, und die aus denselben Quellen wie
Framework servicemanager
. Die Prozesse von Zulieferunternehmen müssen
für die Kommunikation mit vndservicemanager
ändern; wenn ein Prozess des Zulieferunternehmens
/dev/vndbinder
, Dienstsuchen werden automatisch an
vndservicemanager
Das Binärprogramm vndservicemanager
ist in der Standardeinstellung von Android enthalten
Makefiles auf dem Gerät.
SELinux-Richtlinie
Anbieterprozesse, die über die Binder-Funktion kommunizieren möchten miteinander kommunizieren müssen:
- Zugriff auf
/dev/vndbinder
. - Ordner "
{transfer, call}
" wird angehakt invndservicemanager
. binder_call(A, B)
für jede Anbieterdomain A, die einen Aufruf an über die Anbieter-Binder-Schnittstelle in die Domain B des Anbieters ein.- Berechtigung:
{add, find}
Dienste invndservicemanager
.
Verwenden Sie die vndbinder_use()
, um die Anforderungen 1 und 2 zu erfüllen.
Makro:
vndbinder_use(some_vendor_process_domain);
Um Anforderung 3 zu erfüllen, muss die binder_call(A, B)
für den Anbieter festgelegt werden.
die Prozesse A und B, die über Binder kommunizieren müssen, an Ort und Stelle bleiben können
müssen umbenannt werden.
Um Anforderung 4 zu erfüllen, müssen Sie Änderungen an Dienstnamen, Dienst-Labels und -Regeln verarbeitet werden.
Details zu SELinux finden Sie unter Verstärkte Sicherheit Linux für Android Details zu SELinux unter Android 8.0 finden Sie unter SELinux für Android 8.0.
Dienstnamen
Zuvor verarbeitete der Anbieter registrierte Dienstnamen in einem
service_contexts
Datei und entsprechende Regeln für den Zugriff hinzugefügt
für diese Datei. Beispieldatei service_contexts
aus
device/google/marlin/sepolicy
:
AtCmdFwd u:object_r:atfwd_service:s0 cneservice u:object_r:cne_service:s0 qti.ims.connectionmanagerservice u:object_r:imscm_service:s0 rcs u:object_r:radio_service:s0 uce u:object_r:uce_service:s0 vendor.qcom.PeripheralManager u:object_r:per_mgr_service:s0
In Android 8 lädt vndservicemanager
vndservice_contexts
-Datei. Anbieterdienste werden migriert auf
vndservicemanager
(und die sich bereits in der alten
service_contexts
-Datei) sollte dem neuen
vndservice_contexts
-Datei.
Dienstlabels
Bisher wurden Dienstlabels wie u:object_r:atfwd_service:s0
in einer service.te
-Datei definiert wurden. Beispiel:
type atfwd_service, service_manager_type;
In Android 8 müssen Sie den Typ in
vndservice_manager_type
und verschieben Sie die Regel in den
vndservice.te
-Datei. Beispiel:
type atfwd_service, vndservice_manager_type;
Service Manager-Regeln
Bisher haben Regeln Domains Zugriff gewährt, um Dienste hinzuzufügen oder zu suchen
servicemanager
Beispiel:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;
In Android 8 können solche Regeln bestehen bleiben und dieselbe Klasse verwenden. Beispiel:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;