Cette page décrit les modifications apportées au pilote de liaison dans Android 8, fournit des détails sur l'utilisation de l'IPC de liaison et la liste des règles SELinux requises.
Modifications apportées au pilote de liaison
À partir d'Android 8, le framework Android et les HAL communiquent à l'aide de la liaison. Alors que cette communication augmente considérablement le lien trafic, Android 8 inclut plusieurs améliorations conçues pour conserver l'IPC de liaison rapidement. Les fournisseurs de SoC et les OEM doivent fusionner directement avec les branches concernées de android-4.4, android-4.9 et versions ultérieures kernel/common.
Plusieurs domaines de liaison (contextes)
Common 4.4 et versions ultérieures, y compris en amontRépartir correctement le trafic de liaison entre le framework (indépendant de l'appareil) et code (spécifique à l'appareil), Android 8 a introduit le concept de liaison le contexte. Chaque contexte de liaison possède son propre nœud d'appareil et son propre contexte (service). Vous ne pouvez accéder au gestionnaire de contexte que via l'appareil auquel il appartient et, lors de la transmission d'un nœud de liaison via un certain contexte, elles ne sont accessibles à partir de ce même contexte que par un autre processus. isolant complètement les domaines les uns des autres. Pour en savoir plus sur l'utilisation, consultez vndbinder et vndservicemanager.
Collectionneur de nuage de points
Common 4.4 et versions ultérieures, y compris en amontDans les versions précédentes d'Android, chaque élément de données d'un appel de liaison était copié trois fois:
- Une fois pour la sérialiser
Parcel
pendant le processus d'appel. - Une fois dans le pilote du noyau pour copier
Parcel
sur la cible processus - Une fois pour désérialiser le
Parcel
dans le processus cible
Android 8 utilise
recueil-de-diffusion
optimisation pour faire passer le nombre de copies de 3 à 1. Au lieu de
si vous sérialisez d'abord les données dans un Parcel
, les données restent dans leur état d'origine
et la structure de la mémoire. Le pilote les copie immédiatement
processus. Une fois les données dans le processus cible, la structure et la mémoire
la mise en page est la même et les données peuvent être lues sans nécessiter de copie supplémentaire.
Verrouillage ultraprécis
Common 4.4 et versions ultérieures, y compris en amontDans les versions précédentes d'Android, le pilote de liaison utilisait un verrouillage global pour protéger contre les accès simultanés à des structures de données critiques. Bien qu'il y ait un minimum le principal problème était que, si un thread à faible priorité obtenait la serrure avant d'être préemptée, elle pouvait sérieusement retarder threads prioritaires qui doivent obtenir le même verrouillage. Cela a causé des à-coups dans Google Cloud.
Les premières tentatives de résolution de ce problème impliquaient de désactiver la préemption pendant en maintenant le verrou mondial. Cependant, il s'agissait plus d'un piratage qu'une véritable solution, et a finalement été rejetée en amont, puis rejetée. Tentatives suivantes mais nous nous sommes attachés à rendre le verrouillage plus précis, sur les appareils Pixel depuis janvier 2017. Même si la majorité de ces changements rendues publiques, des améliorations importantes ont été apportées dans les versions ultérieures.
Après avoir identifié les petits problèmes dans l'implémentation ultraprécise du verrouillage, conçu une solution améliorée avec une architecture de verrouillage différente, les modifications dans toutes les branches de noyau courantes. Nous poursuivons les tests sur un grand nombre d'appareils différents ; car nous n'avons pas connaissance problèmes non résolus, il s'agit de la mise en œuvre recommandée pour les appareils livrés avec Android 8.
Héritage des priorités en temps réel
Common-4.4 et common-4.9 (en amont bientôt disponible)Le pilote de liaison a toujours pris en charge l'héritage de priorité agréable. En tant que de plus en plus de processus dans Android s'exécutent de façon prioritaire en temps réel, dans certains il est désormais logique que si un thread en temps réel effectue un appel de liaison, dans le processus qui gère cet appel s'exécute également avec une priorité en temps réel. À prennent en charge ces cas d'utilisation, Android 8 implémente désormais l'héritage de priorité en temps réel dans le pilote de liaison.
Outre l'héritage de priorité au niveau des transactions, la priorité des nœuds héritage permet à un nœud (objet de service de liaison) de spécifier une valeur minimale à laquelle les appels vers ce nœud doivent être exécutés. Versions précédentes de Android prenait déjà en charge l'héritage de la priorité des nœuds avec des valeurs intéressantes, mais Android 8 prend en charge l'héritage des nœuds des règles de planification en temps réel.
Modifications de l'espace utilisateur
Android 8 inclut toutes les modifications de l'espace utilisateur requises pour fonctionner avec la version actuelle
le pilote de liaison dans le noyau commun, à une exception près: le pilote d'origine
pour désactiver l'héritage de priorité en temps réel
/dev/binder
a utilisé un
ioctl. Le développement suivant a modifié le contrôle de priorité
l'héritage à une méthode plus précise par mode de liaison (et non par
le contexte actuel). Ainsi, ioctl ne figure pas dans la branche commune d'Android, mais est plutôt
soumis dans nos noyaux communs.
L'effet de cette modification est que l'héritage de priorité en temps réel est désactivé par
pour chaque nœud. L'équipe Android chargée des performances l'a trouvé
utile d'activer l'héritage de priorité en temps réel pour tous les nœuds dans le
hwbinder
. Pour obtenir le même effet, choisissez
ce changement dans l'espace utilisateur.
SHA pour les noyaux courants
Pour obtenir les modifications nécessaires apportées au pilote de liaison, synchronisez avec le SHA approprié:
- Commun-3,18
cc8b90c121de ANDROID: binder: ne cochez pas les autorisations prioritaires lors de la restauration. - Commun-4,4
76b376eac7a2 ANDROID: binder: ne cochez pas les autorisations prioritaires lors de la restauration. - Commun-4,9
ecd972d4f9b5 ANDROID: binder: ne cochez pas les autorisations prioritaires lors de la restauration.
Utiliser l'IPC de liaison
Auparavant, les processus des fournisseurs utilisaient la communication inter-processus de liaison
(IPC) de communiquer. Sous Android 8, le nœud d'appareil /dev/binder
devient exclusif aux processus du framework, ce qui signifie que les processus des fournisseurs ne
y avoir accès. Les processus du fournisseur peuvent accéder à /dev/hwbinder
, mais
doivent convertir leurs interfaces AIDL pour utiliser HIDL. Pour les fournisseurs qui souhaitent continuer
à l'aide d'interfaces AIDL entre les processus des fournisseurs, Android prend en charge l'IPC de liaison en tant que
décrites ci-dessous. Dans Android 10, la version stable d'AIDL autorise tous
pour utiliser /dev/binder
tout en résolvant la stabilité
garantit que les problèmes HIDL et /dev/hwbinder
sont résolus. Pour savoir comment utiliser la version stable
AIDL, voir
AIDL pour les HAL
Vndbinder
Android 8 prend en charge un nouveau domaine de liaison destiné aux services des fournisseurs, accessible
avec /dev/vndbinder
au lieu de /dev/binder
. Avec l'attribut
ajout de /dev/vndbinder
, Android dispose désormais des trois
Domaines d'IPC:
Domaine IPC | Description |
---|---|
/dev/binder |
IPC entre les processus du framework/de l'application avec des interfaces AIDL |
/dev/hwbinder |
IPC entre les processus du framework/fournisseur avec des interfaces HIDL
IPC entre les processus des fournisseurs avec des interfaces HIDL |
/dev/vndbinder |
IPC entre les processus fournisseur/fournisseur avec des interfaces AIDL |
Pour que /dev/vndbinder
s'affiche, assurez-vous que la configuration du noyau
l'élément CONFIG_ANDROID_BINDER_DEVICES
est défini sur
"binder,hwbinder,vndbinder"
(il s'agit du paramètre par défaut
les arbres à noyau courants).
Normalement, les processus des fournisseurs n'ouvrent pas
directement le pilote de liaison et au lieu
vers la bibliothèque d'espace utilisateur libbinder
, qui ouvre
le pilote de liaison. Ajouter une méthode pour ::android::ProcessState()
sélectionne le pilote de liaison pour libbinder
. Les processus
fournisseurs doivent
appeler cette méthode avant d'appeler ProcessState,
.
IPCThreadState
, ou avant d'effectuer des appels de liaison en général. À
utilisez, passez l'appel suivant après l'main()
d'un processus fournisseur
(client et serveur):
ProcessState::initWithDriver("/dev/vndbinder");
vndservicemanager
Auparavant, les services de liaison étaient enregistrés avec servicemanager
,
où elles pourraient être récupérées par d'autres processus. Sous Android 8,
servicemanager
est désormais utilisé exclusivement par le framework et l'application
processus et ceux des fournisseurs
ne peuvent plus y accéder.
Toutefois, les services des fournisseurs peuvent désormais utiliser vndservicemanager
, une nouvelle
Une instance de servicemanager
qui utilise /dev/vndbinder
au lieu de /dev/binder
et qui est créé à partir des mêmes sources que
servicemanager
. Les processus des fournisseurs
n'ont pas besoin de faire
modifications pour communiquer avec vndservicemanager
; lorsqu'un processus
fournisseur s'ouvre
/dev/vndbinder
, les recherches de services renvoient automatiquement vers
vndservicemanager
Le binaire vndservicemanager
est inclus dans le fichier binaire par défaut d'Android
fichiers makefile de l'appareil.
Règles SELinux
Les processus du fournisseur qui souhaitent utiliser la fonctionnalité de liaison pour communiquer avec ont besoin des éléments suivants:
- Accès à
/dev/vndbinder
. - La liaison
{transfer, call}
s'accroche àvndservicemanager
binder_call(A, B)
pour tout domaine de fournisseur A souhaitant appeler dans le domaine du fournisseur B via l'interface de liaison du fournisseur.- Autorisation pour
{add, find}
services dansvndservicemanager
Pour répondre aux exigences 1 et 2, utilisez l'vndbinder_use()
.
:
vndbinder_use(some_vendor_process_domain);
Pour répondre à l'exigence 3, le binder_call(A, B)
du fournisseur
les processus A et B qui ont besoin de parler par-dessus le binder peuvent rester en place et n'a pas
à renommer.
Pour répondre à l'exigence 4, vous devez modifier la façon dont les noms des services, les étiquettes de service et les règles.
Pour plus d'informations sur SELinux, consultez le document Security-Enhanced Linux sur Android Pour plus d'informations sur SELinux dans Android 8.0, consultez SELinux pour Android 8.0.
Noms des services
Auparavant, le fournisseur traite les noms de services enregistrés
service_contexts
et ajouté les règles d'accès correspondantes
ce fichier. Exemple de fichier service_contexts
de
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
Sous Android 8, vndservicemanager
charge
vndservice_contexts
. Services des fournisseurs migrant vers
vndservicemanager
(et qui figurent déjà dans l'ancienne version
service_contexts
) doit être ajouté au nouveau
vndservice_contexts
.
Étiquettes de service
Auparavant, les étiquettes de service telles que u:object_r:atfwd_service:s0
ont été définies dans un fichier service.te
. Exemple :
type atfwd_service, service_manager_type;
Sous Android 8, vous devez remplacer le type par
vndservice_manager_type
, puis déplacez la règle vers
vndservice.te
. Exemple :
type atfwd_service, vndservice_manager_type;
règles Servicemanager
Auparavant, les règles accordaient aux domaines un accès permettant d'ajouter ou de rechercher des services
servicemanager
Exemple :
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;
Dans Android 8, ces règles peuvent rester en place et utiliser la même classe. Exemple :
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;