Halaman ini menjelaskan perubahan pada driver binder di Android 8, memberikan detail tentang penggunaan IPC binder, dan mencantumkan kebijakan SELinux yang diperlukan.
Perubahan pada driver pengikat
Mulai Android 8, kerangka kerja Android dan HAL sekarang berkomunikasi satu sama lain menggunakan pengikat. Karena komunikasi ini secara dramatis meningkatkan lalu lintas pengikat, Android 8 menyertakan beberapa peningkatan yang dirancang untuk menjaga agar pengikat IPC tetap cepat. Vendor SoC dan OEM harus bergabung langsung dari cabang yang relevan dari android-4.4, android-4.9, dan yang lebih tinggi dari kernel/proyek umum .
Beberapa domain pengikat (konteks)
Common-4.4 dan lebih tinggi, termasuk upstreamUntuk memisahkan lalu lintas pengikat dengan rapi antara kode kerangka kerja (tidak tergantung perangkat) dan vendor (khusus perangkat), Android 8 memperkenalkan konsep konteks pengikat . Setiap konteks pengikat memiliki simpul perangkatnya sendiri dan pengelola konteks (layanan) sendiri. Anda dapat mengakses manajer konteks hanya melalui simpul perangkat yang dimilikinya dan, ketika melewati simpul pengikat melalui konteks tertentu, itu dapat diakses dari konteks yang sama hanya dengan proses lain, sehingga sepenuhnya mengisolasi domain dari satu sama lain. Untuk detail tentang penggunaan, lihat vndbinder dan vndservicemanager .
Sebar-kumpul
Common-4.4 dan lebih tinggi, termasuk upstreamDalam rilis Android sebelumnya, setiap bagian data dalam panggilan pengikat disalin tiga kali:
- Sekali untuk membuat serial menjadi
Parcel
dalam proses panggilan - Setelah di driver kernel untuk menyalin
Parcel
ke proses target - Sekali untuk membatalkan serial
Parcel
dalam proses target
Android 8 menggunakan pengoptimalan scatter-gather untuk mengurangi jumlah salinan dari 3 menjadi 1. Alih-alih membuat serial data dalam Parcel
terlebih dahulu, data tetap berada dalam struktur aslinya dan tata letak memori dan driver segera menyalinnya ke proses target. Setelah data dalam proses target, struktur dan tata letak memori sama dan data dapat dibaca tanpa memerlukan salinan lagi.
Penguncian berbutir halus
Common-4.4 dan lebih tinggi, termasuk upstreamDalam rilis Android sebelumnya, driver pengikat menggunakan kunci global untuk melindungi dari akses bersamaan ke struktur data penting. Meskipun ada sedikit perselisihan untuk kunci, masalah utamanya adalah jika utas berprioritas rendah memperoleh kunci dan kemudian didahulukan, itu dapat secara serius menunda utas dengan prioritas lebih tinggi yang perlu mendapatkan kunci yang sama. Hal ini menyebabkan jank di platform.
Upaya awal untuk menyelesaikan masalah ini melibatkan penonaktifan preemption sambil menahan kunci global. Namun, ini lebih merupakan peretasan daripada solusi sejati, dan akhirnya ditolak oleh hulu dan dibuang. Upaya selanjutnya berfokus pada membuat penguncian lebih halus, versi yang telah berjalan pada perangkat Pixel sejak Januari 2017. Meskipun sebagian besar perubahan tersebut dipublikasikan, peningkatan substansial dilakukan pada versi berikutnya.
Setelah mengidentifikasi masalah kecil dalam implementasi penguncian berbutir halus, kami merancang solusi yang ditingkatkan dengan arsitektur penguncian yang berbeda dan mengirimkan perubahan di semua cabang kernel umum. Kami terus menguji implementasi ini pada sejumlah besar perangkat yang berbeda; karena kami tidak mengetahui adanya masalah yang belum terselesaikan, ini adalah implementasi yang disarankan untuk pengiriman perangkat dengan Android 8.
Warisan prioritas waktu nyata
Common-4.4 dan common-4.9 (upstream segera hadir)Pengandar pengikat selalu mendukung pewarisan prioritas yang bagus. Karena semakin banyak proses di Android yang berjalan pada prioritas waktu nyata, dalam beberapa kasus sekarang masuk akal bahwa jika utas waktu nyata membuat panggilan pengikat, utas dalam proses yang menangani panggilan itu juga berjalan pada prioritas waktu nyata . Untuk mendukung kasus penggunaan ini, Android 8 sekarang mengimplementasikan pewarisan prioritas waktu nyata di driver pengikat.
Selain pewarisan prioritas tingkat transaksi, pewarisan prioritas simpul memungkinkan sebuah simpul (objek layanan pengikat) untuk menentukan prioritas minimum di mana panggilan ke simpul ini harus dijalankan. Versi Android sebelumnya telah mendukung pewarisan prioritas simpul dengan nilai yang bagus, tetapi Android 8 menambahkan dukungan untuk pewarisan simpul kebijakan penjadwalan waktu nyata.
Perubahan ruang pengguna
Android 8 menyertakan semua perubahan ruang pengguna yang diperlukan untuk bekerja dengan driver pengikat saat ini di kernel umum dengan satu pengecualian: Implementasi asli untuk menonaktifkan pewarisan prioritas waktu nyata untuk /dev/binder
menggunakan ioctl . Pengembangan selanjutnya mengalihkan kontrol dari pewarisan prioritas ke metode yang lebih halus yaitu per mode pengikat (dan bukan per konteks). Jadi, ioctl tidak ada di cabang umum Android dan malah dikirimkan di kernel umum kami .
Efek dari perubahan ini adalah pewarisan prioritas waktu nyata dinonaktifkan secara default untuk setiap node. Tim kinerja Android merasa bermanfaat untuk mengaktifkan pewarisan prioritas waktu nyata untuk semua node dalam domain hwbinder
. Untuk mencapai efek yang sama, pilih perubahan ini di ruang pengguna.
SHA untuk kernel umum
Untuk mendapatkan perubahan yang diperlukan pada driver pengikat, sinkronkan ke SHA yang sesuai:
- Umum-3.18
cc8b90c121de ANDROID: pengikat: jangan periksa izin sebelumnya saat memulihkan. - Umum-4.4
76b376eac7a2 ANDROID: pengikat: jangan periksa izin sebelumnya saat memulihkan. - Umum-4.9
ecd972d4f9b5 ANDROID: pengikat: jangan periksa izin sebelumnya saat memulihkan.
Menggunakan pengikat IPC
Secara historis, proses vendor telah menggunakan binder interprocess communication (IPC) untuk berkomunikasi. Di Android 8, simpul perangkat /dev/binder
menjadi eksklusif untuk proses kerangka kerja, artinya proses vendor tidak lagi memiliki akses ke sana. Proses vendor dapat mengakses /dev/hwbinder
, tetapi harus mengonversi antarmuka AIDL mereka untuk menggunakan HIDL. Untuk vendor yang ingin terus menggunakan antarmuka AIDL antar proses vendor, Android mendukung binder IPC seperti yang dijelaskan di bawah ini.
vndbinder
Android 8 mendukung domain pengikat baru untuk digunakan oleh layanan vendor, diakses menggunakan /dev/vndbinder
alih-alih /dev/binder
. Dengan tambahan /dev/vndbinder
, Android sekarang memiliki tiga domain IPC berikut:
Domain IPC | Keterangan |
---|---|
/dev/binder | IPC antara kerangka kerja/proses aplikasi dengan antarmuka AIDL |
/dev/hwbinder | IPC antara proses kerangka kerja/vendor dengan antarmuka HIDL IPC antara proses vendor dengan antarmuka HIDL |
/dev/vndbinder | IPC antara proses vendor/vendor dengan Antarmuka AIDL |
Agar /dev/vndbinder
muncul, pastikan item konfigurasi kernel CONFIG_ANDROID_BINDER_DEVICES
diatur ke "binder,hwbinder,vndbinder"
(ini adalah default di pohon kernel umum Android).
Biasanya, proses vendor tidak membuka driver pengikat secara langsung dan malah menautkan ke perpustakaan ruang pengguna libbinder
, yang membuka driver pengikat. Menambahkan metode untuk ::android::ProcessState()
memilih driver pengikat untuk libbinder
. Proses vendor harus memanggil metode ini sebelum memanggil ProcessState,
IPCThreadState
, atau sebelum melakukan panggilan binder secara umum. Untuk menggunakannya, tempatkan panggilan berikut setelah main()
dari proses vendor (klien dan server):
ProcessState::initWithDriver("/dev/vndbinder");
manajer layanan
Sebelumnya, layanan pengikat terdaftar dengan servicemanager
, di mana mereka dapat diambil oleh proses lain. Di Android 8, servicemanager
sekarang digunakan secara eksklusif oleh kerangka kerja dan proses aplikasi dan proses vendor tidak dapat lagi mengaksesnya.
Namun, layanan vendor sekarang dapat menggunakan vndservicemanager
, instance baru dari servicemanager
yang menggunakan /dev/vndbinder
alih-alih /dev/binder
dan yang dibangun dari sumber yang sama dengan framework servicemanager
. Proses vendor tidak perlu melakukan perubahan untuk berbicara dengan vndservicemanager
; ketika proses vendor terbuka / dev/vndbinder
, pencarian layanan secara otomatis masuk ke vndservicemanager
.
Biner vndservicemanager
disertakan dalam makefile perangkat default Android.
kebijakan SELinux
Proses vendor yang ingin menggunakan fungsionalitas pengikat untuk berkomunikasi satu sama lain memerlukan hal berikut:
- Akses ke
/dev/vndbinder
. - Binder
{transfer, call}
terhubung kevndservicemanager
. -
binder_call(A, B)
untuk setiap domain vendor A yang ingin dipanggil ke domain vendor B melalui antarmuka binder vendor. - Izin untuk
{add, find}
layanan divndservicemanager
.
Untuk memenuhi persyaratan 1 dan 2, gunakan makro vndbinder_use()
:
vndbinder_use(some_vendor_process_domain);
Untuk memenuhi persyaratan 3, binder_call(A, B)
untuk proses vendor A dan B yang perlu membicarakan binder dapat tetap di tempatnya, dan tidak perlu diganti namanya.
Untuk memenuhi persyaratan 4, Anda harus membuat perubahan dalam cara penanganan nama layanan, label layanan, dan aturan.
Untuk detail tentang SELinux, lihat Linux yang Ditingkatkan Keamanan di Android . Untuk detail tentang SELinux di Android 8.0, lihat SELinux untuk Android 8.0 .
Nama layanan
Sebelumnya, vendor memproses nama layanan terdaftar dalam file service_contexts
dan menambahkan aturan terkait untuk mengakses file tersebut. Contoh file service_contexts
dari 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
Di Android 8, vndservicemanager
memuat file vndservice_contexts
sebagai gantinya. Layanan vendor yang bermigrasi ke vndservicemanager
(dan yang sudah ada di file service_contexts
lama) harus ditambahkan ke file vndservice_contexts
yang baru.
Label layanan
Sebelumnya, label layanan seperti u:object_r:atfwd_service:s0
didefinisikan dalam file service.te
. Contoh:
type atfwd_service, service_manager_type;
Di Android 8, Anda harus mengubah tipe menjadi vndservice_manager_type
dan memindahkan aturan ke file vndservice.te
. Contoh:
type atfwd_service, vndservice_manager_type;
Aturan manajer layanan
Sebelumnya, aturan memberikan domain akses untuk menambah atau menemukan layanan dari servicemanager
. Contoh:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;
Di Android 8, aturan tersebut dapat tetap berlaku dan menggunakan kelas yang sama. Contoh:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;