Halaman ini menjelaskan perubahan pada driver binder di Android 8, menyediakan detail tentang penggunaan binder IPC, dan mencantumkan kebijakan SELinux yang diperlukan.
Perubahan pada driver binder
Mulai Android 8, framework Android dan HAL sekarang berkomunikasi dengan satu sama lain menggunakan binder. Karena komunikasi ini secara dramatis meningkatkan binder Android 8 menyertakan beberapa peningkatan yang dirancang untuk mempertahankan IPC binder dengan cepat. Vendor SoC dan OEM harus bergabung langsung dari cabang yang relevan dari android-4.4, android-4.9, dan yang lebih tinggi pada kernel/common Google Cloud.
Beberapa domain binder (konteks)
Common-4.4 dan yang lebih tinggi, termasuk upstreamUntuk memisahkan traffic binder dengan rapi antara framework (tidak bergantung pada perangkat) dan kode vendor (khusus perangkat), Android 8 memperkenalkan konsep binder konteks tambahan. Setiap konteks binder memiliki node perangkat dan konteksnya sendiri pengelola (layanan). Anda hanya dapat mengakses pengelola konteks melalui perangkat yang dimilikinya dan, saat meneruskan simpul binder melalui jalur konteks tersebut, hanya dapat diakses dari konteks yang sama oleh proses lain, sehingga benar-benar mengisolasi domain dari satu sama lain. Untuk detail tentang penggunaan, lihat vndbinder dan vndservicemanager.
Sebar mengumpulkan
Common-4.4 dan yang lebih tinggi, termasuk upstreamDalam rilis Android sebelumnya, setiap bagian data dalam panggilan binder disalin tiga kali:
- Sekali untuk diserialisasi ke dalam
Parcel
dalam proses panggilan - Setelah berada di driver kernel untuk menyalin
Parcel
ke target proses - Sekali untuk membatalkan serialisasi
Parcel
dalam proses target
Android 8 menggunakan
sebar-kumpul
pengoptimalan untuk mengurangi jumlah salinan dari 3 menjadi 1. Daripada fokus pada
membuat serialisasi data di Parcel
terlebih dahulu, data tetap dalam aslinya
struktur dan tata letak memori, dan {i>driver<i} segera menyalinnya ke target
{i>checkout<i}. Setelah data berada dalam proses target, struktur dan memori
tetap sama dan data dapat dibaca
tanpa memerlukan salinan lainnya.
Penguncian terperinci
Common-4.4 dan yang lebih tinggi, termasuk upstreamDi rilis Android sebelumnya, driver binder menggunakan kunci global untuk melindungi terhadap akses serentak ke struktur data kritis. Meskipun ada sedikit pertentangan untuk kunci, masalah utamanya adalah bahwa jika thread prioritas rendah mendapatkan kunci tersebut dan kemudian diantisipasi, hal itu dapat menyebabkan penundaan yang serius thread dengan prioritas lebih tinggi yang perlu mendapatkan kunci yang sama. Hal ini menyebabkan jank pada terkelola sepenuhnya.
Upaya awal untuk mengatasi masalah ini melibatkan penonaktifan {i>preemption<i} saat memegang kunci global. Namun, ini lebih berupa peretasan daripada solusi yang sebenarnya, dan akhirnya ditolak oleh upstream dan dihapus. Percobaan berikutnya berfokus untuk membuat penguncian lebih perinci, versi yang telah berjalan di perangkat Pixel sejak Januari 2017. Meskipun sebagian besar perubahan tersebut dipublikasikan, peningkatan substansial dilakukan dalam versi berikutnya.
Setelah mengidentifikasi masalah kecil dalam implementasi penguncian yang terperinci, kami merancang solusi yang lebih baik dengan arsitektur penguncian yang berbeda dan mengirimkan perubahan di semua cabang {i>kernel<i} yang umum. Kami terus menguji hal ini implementasi pada sejumlah besar perangkat yang berbeda; karena kami tidak mengetahui masalah yang belum terselesaikan, ini adalah penerapan yang direkomendasikan untuk pengiriman perangkat dengan Android 8.
Pewarisan prioritas real-time
Common-4.4 dan common-4.9 (segera hadir)Driver binder selalu mendukung pewarisan prioritas yang bagus. Sebagai seorang peningkatan jumlah proses di Android yang berjalan pada prioritas real-time, dalam beberapa sekarang masuk akal jika thread {i>real-time<i} melakukan panggilan binder, thread dalam proses yang menangani panggilan itu juga berjalan pada prioritas real-time. Kepada mendukung kasus penggunaan ini, Android 8 kini mengimplementasikan pewarisan prioritas real-time di driver binder.
Selain pewarisan prioritas tingkat transaksi, prioritas node pewarisan memungkinkan node (objek layanan binder) menentukan nilai minimum prioritas yang mengharuskan panggilan ke node ini harus dijalankan. Versi sebelumnya dari Android sudah mendukung pewarisan prioritas node dengan nilai yang bagus, tetapi Android 8 menambahkan dukungan untuk pewarisan node kebijakan penjadwalan secara real-time.
Perubahan ruang pengguna
Android 8 menyertakan semua perubahan userspace yang diperlukan untuk bekerja dengan
{i>binder driver<i} di {i>kernel<i} umum dengan satu pengecualian: Versi asli
implementasi untuk menonaktifkan pewarisan prioritas real-time bagi
/dev/binder
menggunakan
ioctl. Pengembangan berikutnya mengalihkan kontrol prioritas
pewarisan ke metode yang lebih halus yaitu
per mode binder (dan bukan per
konteks tertentu). Jadi, ioctl tidak berada di cabang umum Android dan
dikirimkan di kernel umum.
Efek perubahan ini adalah pewarisan prioritas real-time dinonaktifkan oleh
default untuk setiap node. Tim performa Android telah menemukannya
bermanfaat untuk mengaktifkan pewarisan prioritas real-time untuk semua node dalam
hwbinder
. Untuk mendapatkan efek yang sama, pilih satu
perubahan ini di userspace.
SHA untuk kernel umum
Untuk mendapatkan perubahan yang diperlukan pada driver binder, sinkronkan ke SHA yang sesuai:
- Umum-3.18
cc8b90c121de ANDROID: binder: don't check prio permissions on Restore. - Umum-4,4
76b376eac7a2 ANDROID: binder: don't check prio permissions on Restore. - Umum-4,9
ecd972d4f9b5 ANDROID: binder: don't check prio permissions on Restore.
Menggunakan binder IPC
Secara historis, proses vendor telah
menggunakan komunikasi antarproses {i>binder<i}
(IPC) untuk berkomunikasi. Di Android 8, node perangkat /dev/binder
menjadi eksklusif untuk proses kerangka kerja, yang berarti 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 melanjutkan
menggunakan antarmuka AIDL di antara proses vendor, Android mendukung binder IPC sebagai
yang dijelaskan di bawah. Di Android 10, AIDL Stabil memungkinkan semua
proses untuk menggunakan /dev/binder
sekaligus mengatasi masalah stabilitas
menjamin HIDL dan /dev/hwbinder
terpecahkan. Untuk cara menggunakan Stabil
AIDL, lihat
AIDL untuk HAL.
Vndbinder
Android 8 mendukung domain binder baru untuk digunakan oleh layanan vendor, yang dapat diakses
menggunakan /dev/vndbinder
, bukan /dev/binder
. Dengan
setelah /dev/vndbinder
, Android kini memiliki tiga
Domain IPC:
Domain IPC | Deskripsi |
---|---|
/dev/binder |
IPC antara proses framework/aplikasi dengan antarmuka AIDL |
/dev/hwbinder |
IPC di antara proses framework/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 konfigurasi kernel
item CONFIG_ANDROID_BINDER_DEVICES
ditetapkan ke
"binder,hwbinder,vndbinder"
(ini adalah setelan default di
pohon {i>kernel<i} yang umum).
Biasanya, proses vendor tidak membuka
{i>driver<i} binder secara langsung dan sebagai gantinya
terhadap library userspace libbinder
, yang akan membuka
{i>binder driver<i}. Menambahkan metode untuk ::android::ProcessState()
memilih driver binder untuk libbinder
. Proses vendor harus
panggil metode ini sebelum memanggil ProcessState,
IPCThreadState
, atau sebelum melakukan panggilan binder secara umum. Kepada
digunakan, lakukan panggilan berikut setelah main()
dari proses vendor
(klien dan server):
ProcessState::initWithDriver("/dev/vndbinder");
{i>vndservicemanager<i}
Sebelumnya, layanan binder
didaftarkan ke servicemanager
,
di mana mereka dapat
diambil oleh proses lain. Di Android 8,
servicemanager
kini digunakan secara eksklusif oleh framework dan aplikasi
proses dan proses vendor
tidak dapat lagi mengaksesnya.
Namun, layanan vendor kini dapat menggunakan vndservicemanager
,
instance servicemanager
yang menggunakan /dev/vndbinder
bukan /dev/binder
dan yang dibuat dari sumber yang sama dengan
framework servicemanager
. Proses vendor tidak perlu membuat
perubahan untuk berkomunikasi dengan vndservicemanager
; saat proses vendor membuka
/dev/vndbinder
, pencarian layanan akan otomatis membuka
vndservicemanager
.
Biner vndservicemanager
disertakan dalam default Android
makefile perangkat.
Kebijakan SELinux
Proses vendor yang ingin menggunakan fungsi {i>binder<i} untuk berkomunikasi dengan satu sama lain membutuhkan hal berikut:
- Akses ke
/dev/vndbinder
. - Hubungkan hook
{transfer, call}
ke dalamvndservicemanager
. binder_call(A, B)
untuk domain vendor A apa pun yang ingin dipanggil ke domain vendor B melalui antarmuka pengikat vendor.- Izin untuk
{add, find}
layanan divndservicemanager
.
Untuk memenuhi persyaratan 1 dan 2, gunakan vndbinder_use()
makro:
vndbinder_use(some_vendor_process_domain);
Untuk memenuhi persyaratan 3, binder_call(A, B)
untuk vendor
proses A dan B yang memerlukan penanganan {i>binder<i}
dapat tetap berada di tempatnya, dan tidak
perlu diganti namanya.
Untuk memenuhi persyaratan 4, Anda harus membuat perubahan cara nama layanan, label layanan, dan aturan ditangani.
Untuk mengetahui detail tentang SELinux, lihat Peningkatan Keamanan Linux di Android. Untuk detail tentang SELinux di Android 8.0, lihat SELinux untuk Android 8.0.
Nama layanan
Sebelumnya, vendor memproses nama layanan
yang terdaftar di
service_contexts
file dan menambahkan aturan yang sesuai 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
vndservice_contexts
. Layanan vendor yang
bermigrasi ke
vndservicemanager
(dan yang sudah ada di versi lama
service_contexts
file) harus ditambahkan ke file baru
File vndservice_contexts
.
Label layanan
Sebelumnya, label layanan seperti u:object_r:atfwd_service:s0
ditentukan dalam file service.te
. Contoh:
type atfwd_service, service_manager_type;
Di Android 8, Anda harus mengubah jenis menjadi
vndservice_manager_type
dan pindahkan aturan ke
File vndservice.te
. Contoh:
type atfwd_service, vndservice_manager_type;
aturan servicemanager
Sebelumnya, aturan memberikan akses ke domain untuk menambahkan 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 class yang sama. Contoh:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;