На этой странице описываются изменения в драйвере связывателя в Android 8, приводятся сведения об использовании IPC связывателя и перечислены необходимые политики SELinux.
Изменения в драйвере связующего
Начиная с Android 8, платформа Android и HAL теперь взаимодействуют друг с другом с помощью связывателя. Поскольку эта связь значительно увеличивает трафик связующих, Android 8 включает несколько улучшений, предназначенных для обеспечения быстрой IPC связующих. Поставщики SoC и OEM-производители должны объединяться непосредственно из соответствующих ветвей android-4.4, android-4.9 и выше проекта ядра/общего .
Несколько доменов связывания (контексты)
Common-4.4 и выше, включая апстримЧтобы четко разделить трафик связывателя между фреймворком (независимым от устройства) и вендорным (зависящим от устройства) кодом, в Android 8 была введена концепция контекста связывателя . Каждый контекст связывателя имеет свой собственный узел устройства и свой менеджер контекста (службы). Вы можете получить доступ к диспетчеру контекста только через узел устройства, которому он принадлежит, и при передаче узла привязки через определенный контекст он доступен из этого же контекста только другим процессом, таким образом, полностью изолируя домены друг от друга. Дополнительные сведения об использовании см. в разделе vndbinder и vndservicemanager .
Разбрасывать-собирать
Common-4.4 и выше, включая апстримВ предыдущих выпусках Android каждая часть данных в вызове связывателя копировалась три раза:
- Один раз, чтобы сериализовать его в
Parcel
в вызывающем процессе - Один раз в драйвере ядра скопировать
Parcel
в целевой процесс - Один раз, чтобы десериализовать
Parcel
в целевом процессе
Android 8 использует оптимизацию разброса-сбора , чтобы уменьшить количество копий с 3 до 1. Вместо того, чтобы сначала сериализовать данные в Parcel
, данные остаются в своей исходной структуре и расположении в памяти, и драйвер немедленно копирует их в целевой процесс. После того, как данные находятся в целевом процессе, структура и структура памяти остаются прежними, и данные можно прочитать, не требуя еще одной копии.
Мелкозернистая блокировка
Common-4.4 и выше, включая апстримВ предыдущих выпусках Android драйвер связывателя использовал глобальную блокировку для защиты от одновременного доступа к важным структурам данных. Хотя конкуренция за блокировку была минимальной, основная проблема заключалась в том, что если поток с низким приоритетом получил блокировку, а затем был вытеснен, это могло серьезно задержать потоки с более высоким приоритетом, которым необходимо было получить ту же блокировку. Это вызвало рывки в платформе.
Первоначальные попытки решить эту проблему включали отключение вытеснения при удерживании глобальной блокировки. Однако это был скорее взлом, чем настоящее решение, и в конечном итоге оно было отвергнуто апстримом и отброшено. Последующие попытки были направлены на то, чтобы сделать блокировку более детальной, версия которой работает на устройствах Pixel с января 2017 года. Хотя большинство этих изменений были обнародованы, в последующих версиях были внесены существенные улучшения.
После выявления небольших проблем в мелкомодульной реализации блокировки мы разработали улучшенное решение с другой архитектурой блокировки и отправили изменения во все распространенные ветки ядра. Мы продолжаем тестировать эту реализацию на большом количестве различных устройств; поскольку нам неизвестно о каких-либо нерешенных проблемах, это рекомендуемая реализация для устройств, поставляемых с Android 8.
Наследование приоритета в реальном времени
Common-4.4 и common-4.9 (скоро появится апстрим)Драйвер связывателя всегда поддерживал красивое наследование приоритетов. Поскольку все большее число процессов в Android запускается с приоритетом реального времени, в некоторых случаях теперь имеет смысл, если поток в реальном времени выполняет вызов связывателя, поток в процессе, который обрабатывает этот вызов, также выполняется с приоритетом в реальном времени. . Для поддержки этих вариантов использования Android 8 теперь реализует наследование приоритетов в реальном времени в драйвере связывателя.
В дополнение к наследованию приоритета на уровне транзакции, наследование приоритета узла позволяет узлу (объекту службы связывателя) указывать минимальный приоритет, при котором должны выполняться вызовы в этот узел. Предыдущие версии Android уже поддерживали наследование узлов с хорошими значениями, но в Android 8 добавлена поддержка наследования узлов политик планирования в реальном времени.
Изменения пользовательского пространства
Android 8 включает все изменения пользовательского пространства, необходимые для работы с текущим драйвером связывателя в общем ядре, за одним исключением: исходная реализация для отключения наследования приоритетов в реальном времени для /dev/binder
использовала ioctl . Последующая разработка переключила управление наследованием приоритетов на более детализированный метод, основанный на режиме связывания (а не на контексте). Таким образом, ioctl не находится в общей ветке Android, а вместо этого отправляется в наши общие ядра .
Результатом этого изменения является то, что наследование приоритета в реальном времени отключено по умолчанию для каждого узла. Группа производительности Android сочла полезным включить наследование приоритетов в реальном времени для всех узлов в домене hwbinder
. Чтобы добиться того же эффекта, выберите это изменение в пользовательском пространстве.
SHA для обычных ядер
Чтобы получить необходимые изменения в драйвере связывателя, выполните синхронизацию с соответствующим SHA:
- Общий-3.18
cc8b90c121de ANDROID: связующее: не проверяйте приоритетные разрешения при восстановлении. - Общий-4.4
76b376eac7a2 ANDROID: связующее: не проверять приоритетные разрешения при восстановлении. - Общий-4.9
ecd972d4f9b5 ANDROID: связующее: не проверять приоритетные разрешения при восстановлении.
Использование связующего IPC
Исторически сложилось так, что процессы поставщиков использовали для связи межпроцессное взаимодействие (IPC). В Android 8 узел устройства /dev/binder
становится эксклюзивным для процессов платформы, то есть процессы поставщиков больше не имеют к нему доступа. Процессы поставщиков могут получить доступ к /dev/hwbinder
, но должны преобразовать свои интерфейсы AIDL для использования HIDL. Для поставщиков, которые хотят продолжать использовать интерфейсы AIDL между процессами поставщиков, Android поддерживает связывание IPC, как описано ниже.
вндбиндер
Android 8 поддерживает новый домен связывания для использования службами поставщиков, доступ к которому осуществляется с помощью /dev/vndbinder
вместо /dev/binder
dev/binder . С добавлением /dev/vndbinder
Android теперь имеет следующие три домена IPC:
IPC-домен | Описание |
---|---|
/dev/binder | IPC между процессами платформы/приложения с интерфейсами AIDL |
/dev/hwbinder | IPC между процессами платформы/поставщика с интерфейсами HIDL IPC между процессами поставщиков с интерфейсами HIDL |
/dev/vndbinder | IPC между процессами поставщика/поставщика с интерфейсами AIDL |
Чтобы /dev/vndbinder
появился, убедитесь, что для элемента конфигурации ядра CONFIG_ANDROID_BINDER_DEVICES
установлено значение "binder,hwbinder,vndbinder"
(это значение по умолчанию в общих деревьях ядра Android).
Обычно процессы поставщика не открывают драйвер связывателя напрямую, а вместо этого связываются с библиотекой пользовательского пространства libbinder
, которая открывает драйвер связывателя. Добавление метода для ::android::ProcessState()
выбирает драйвер связывателя для libbinder
. Процессы поставщиков должны вызывать этот метод перед вызовом ProcessState,
IPCThreadState
или перед выполнением любых вызовов связывателя в целом. Чтобы использовать, поместите следующий вызов после main()
процесса поставщика (клиент и сервер):
ProcessState::initWithDriver("/dev/vndbinder");
vndservicemanager
Раньше службы связывания регистрировались в servicemanager
, откуда их могли получать другие процессы. В Android 8 servicemanager
теперь используется исключительно процессами фреймворка и приложения, а процессы поставщика больше не могут получить к нему доступ.
Однако сервисы поставщиков теперь могут использовать vndservicemanager
— новый экземпляр servicemanager
, который использует /dev/vndbinder
вместо /dev/binder
dev/binder и создан из тех же источников, что и framework servicemanager
. Процессам поставщика не нужно вносить изменения, чтобы общаться с vndservicemanager
; когда процесс поставщика открывает / dev/vndbinder
, поиск службы автоматически переходит к vndservicemanager
.
Двоичный файл vndservicemanager
включен в make-файлы устройств Android по умолчанию.
Политика SELinux
Процессам поставщика, которые хотят использовать функциональные возможности связывателя для связи друг с другом, необходимо следующее:
- Доступ к
/dev/vndbinder
. - Binder
{transfer, call}
подключается кvndservicemanager
. -
binder_call(A, B)
для любого домена поставщика A, который хочет вызвать домен поставщика B через интерфейс связывателя поставщика. - Разрешение на
{add, find}
службы вvndservicemanager
.
Чтобы выполнить требования 1 и 2, используйте vndbinder_use()
:
vndbinder_use(some_vendor_process_domain);
Чтобы выполнить требование 3, binder_call(A, B)
для процессов поставщика A и B, которым требуется взаимодействие через связующее, может оставаться на месте и не требует переименования.
Чтобы выполнить требование 4, вы должны внести изменения в способ обработки имен служб, меток служб и правил.
Дополнительные сведения о SELinux см. в разделе Linux с улучшенной безопасностью в Android . Дополнительные сведения о SELinux в Android 8.0 см. в разделе SELinux для Android 8.0 .
Имена сервисов
Раньше поставщики обрабатывали зарегистрированные имена служб в файле service_contexts
и добавляли соответствующие правила для доступа к этому файлу. Пример файла service_contexts
из 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
В Android 8 vndservicemanager
вместо этого загружает файл vndservice_contexts
. Службы поставщиков, переносимые на vndservicemanager
(и уже находящиеся в старом файле service_contexts
), должны быть добавлены в новый файл vndservice_contexts
.
Сервисные этикетки
Ранее метки служб, такие как u:object_r:atfwd_service:s0
, определялись в файле service.te
. Пример:
type atfwd_service, service_manager_type;
В Android 8 необходимо изменить тип на vndservice_manager_type
и перенести правило в файл vndservice.te
. Пример:
type atfwd_service, vndservice_manager_type;
Правила сервис-менеджера
Ранее правила предоставляли доменам доступ для добавления или поиска служб из servicemanager
. Пример:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;
В Android 8 такие правила могут оставаться в силе и использовать тот же класс. Пример:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;