На этой странице описаны изменения в драйвере связывания в Android 8, приведены подробные сведения об использовании IPC связывания и перечислены необходимые политики SELinux.
Изменения в драйвере связующего
Начиная с Android 8, фреймворк Android и HAL теперь взаимодействуют друг с другом с помощью связывателя. Поскольку это взаимодействие резко увеличивает трафик связывателей, Android 8 включает в себя несколько улучшений, предназначенных для быстрой работы Binder IPC. SoC поставщиков и производители должны объединить непосредственно из соответствующих ветвей андроид-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: binder: не проверять приоритетные разрешения при восстановлении. - Обычный-4.4
76b376eac7a2 ANDROID: binder: не проверять приоритетные разрешения при восстановлении. - Обычный-4.9
ecd972d4f9b5 ANDROID: binder: не проверять приоритетные разрешения при восстановлении.
Использование связующего IPC
Исторически сложилось так, что в процессах поставщиков для связи использовалось межпроцессное взаимодействие связывателей (IPC). В Android 8, /dev/binder
узел устройства становится исключительно для каркасных процессов, означая процессы поставщиков больше не имеют доступа к нему. Процессы Продавец может получить доступ к /dev/hwbinder
, но необходимо преобразовать их AIDL интерфейсы для использования HIDL. Для поставщиков, которые хотят продолжать использовать интерфейсы AIDL между процессами поставщиков, Android поддерживает связывание IPC, как описано ниже.
vndbinder
Android 8 поддерживает новый домен Связующее для использования услуг поставщика, доступ , используя /dev/vndbinder
вместо /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
и который строится из тех же источников, рамочный servicemanager
. Процессы поставщиков не нужно вносить изменения в разговоре с vndservicemanager
; при открытии процесса поставщика / dev/vndbinder
, сервис поиски автоматически переходит в vndservicemanager
.
vndservicemanager
двоичный входят в Makefiles устройства по умолчанию Android.
Политика SELinux
Процессам поставщика, которые хотят использовать функциональные возможности связывания для взаимодействия друг с другом, необходимо следующее:
- Доступ к
/dev/vndbinder
. - Связующее
{transfer, call}
крючки вvndservicemanager
. -
binder_call(A, B)
для любого поставщика домена А , который хочет , чтобы позвонить в домен поставщика B через интерфейс поставщика связующего. - Разрешение на
{add, find}
услуг вvndservicemanager
.
Для выполнения требований 1 и 2, используйте vndbinder_use()
макрос:
vndbinder_use(some_vendor_process_domain);
Для того, чтобы выполнить требование 3, binder_call(A, B)
для поставщика процессов А и В , что нужно обсудить связующее вещество может оставаться на месте, и не нуждается переименования.
Чтобы выполнить требование 4, вы должны внести изменения в способ обработки имен служб, меток служб и правил.
Более подробную информацию о SELinux см Security-Enhanced Linux в Android . Более подробную информацию о SELinux в Android 8.0 см SELinux для Android 8.0 .
Названия сервисов
Ранее процессы поставщика зарегистрированных имен службы в service_contexts
файле и добавлены соответствующие правила для доступа к этому файлу. Example 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
Ранее, правила предоставляются домены доступа , чтобы добавить или найти услуги от 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;