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 binder
Mulai Android 8, framework Android dan HAL kini saling berkomunikasi menggunakan binder. Karena komunikasi ini secara drastis meningkatkan traffic binder, Android 8 menyertakan beberapa peningkatan yang dirancang untuk menjaga IPC binder tetap cepat. Vendor SoC dan OEM harus bergabung langsung dari cabang android-4.4, android-4.9, dan yang lebih tinggi dari project kernel/common yang relevan.
Beberapa domain (konteks) binder
Common-4.4 dan yang lebih baru, termasuk upstreamUntuk memisahkan traffic binder dengan rapi antara kode framework (tidak bergantung pada perangkat) dan vendor (khusus perangkat), Android 8 memperkenalkan konsep konteks binder. Setiap konteks binder memiliki node perangkat dan pengelola konteks (layanan)-nya sendiri. Anda hanya dapat mengakses pengelola konteks melalui node perangkat tempatnya berada dan, saat meneruskan node binder melalui konteks tertentu, node tersebut hanya dapat diakses dari konteks yang sama oleh proses lain, sehingga secara total mengisolasi domain satu sama lain. Untuk mengetahui detail penggunaan, lihat vndbinder dan vndservicemanager.
Scatter-gather
Common-4.4 dan yang lebih baru, termasuk upstreamDalam rilis Android sebelumnya, setiap bagian data dalam panggilan binder disalin tiga kali:
- Satu kali untuk melakukan serialisasi ke dalam
Parcel
dalam proses panggilan - Setelah berada di driver kernel untuk menyalin
Parcel
ke proses target - Sekali untuk membatalkan serialisasi
Parcel
dalam proses target
Android 8 menggunakan
pengoptimalan scatter-gather untuk mengurangi jumlah salinan dari 3 menjadi 1. Daripada
melakukan serialisasi data di Parcel
terlebih dahulu, data tetap berada dalam struktur
dan tata letak memori aslinya, dan driver segera menyalinnya ke proses
target. Setelah data berada dalam proses target, struktur dan tata letak
memori akan sama dan data dapat dibaca tanpa memerlukan salinan lain.
Penguncian terperinci
Common-4.4 dan yang lebih baru, termasuk upstreamDalam rilis Android sebelumnya, driver binder menggunakan kunci global untuk melindungi dari akses serentak ke struktur data penting. Meskipun ada pertentangan minimal untuk kunci, masalah utamanya adalah jika thread prioritas rendah mendapatkan kunci, lalu didahului, hal ini dapat menunda thread prioritas lebih tinggi yang perlu mendapatkan kunci yang sama. Hal ini menyebabkan jank di platform.
Upaya awal untuk mengatasi masalah ini melibatkan penonaktifan prioritas sementara memegang kunci global. Namun, ini lebih merupakan hack daripada solusi yang sebenarnya, dan pada akhirnya ditolak oleh upstream dan dihapus. Upaya berikutnya berfokus pada pembuatan penguncian yang lebih terperinci, yang versinya telah berjalan di perangkat Pixel sejak Januari 2017. Meskipun sebagian besar perubahan tersebut dipublikasikan, peningkatan yang signifikan dilakukan pada versi berikutnya.
Setelah mengidentifikasi masalah kecil dalam penerapan penguncian terperinci, kami menyusun solusi yang lebih baik dengan arsitektur penguncian yang berbeda dan mengirimkan perubahan di semua cabang kernel umum. Kami terus menguji penerapan ini di sejumlah besar perangkat yang berbeda; karena kami tidak mengetahui masalah yang belum terselesaikan, ini adalah penerapan yang direkomendasikan untuk perangkat yang dikirimkan dengan Android 8.
Pewarisan prioritas real-time
Common-4.4 dan common-4.9 (upstream segera hadir)Driver binder selalu mendukung pewarisan prioritas yang baik. Karena jumlah proses yang semakin meningkat di Android berjalan dengan prioritas real-time, dalam beberapa kasus, sekarang sudah masuk akal jika thread real-time melakukan panggilan binder, thread dalam proses yang menangani panggilan tersebut juga berjalan dengan prioritas real-time. Untuk mendukung kasus penggunaan ini, Android 8 kini menerapkan pewarisan prioritas real-time di driver binder.
Selain pewarisan prioritas tingkat transaksi, pewarisan prioritas node memungkinkan node (objek layanan binder) menentukan prioritas minimum saat panggilan ke node ini harus dieksekusi. Versi Android sebelumnya sudah mendukung pewarisan prioritas node dengan nilai yang bagus, tetapi Android 8 menambahkan dukungan untuk pewarisan node kebijakan penjadwalan real-time.
Perubahan ruang pengguna
Android 8 menyertakan semua perubahan ruang pengguna yang diperlukan untuk berfungsi dengan driver
binder saat ini di kernel umum dengan satu pengecualian: Implementasi
asli untuk menonaktifkan pewarisan prioritas real-time untuk
/dev/binder
menggunakan
ioctl. Pengembangan berikutnya mengalihkan kontrol pewarisan
prioritas ke metode yang lebih terperinci, yaitu per mode binder (dan bukan per
konteks). Dengan demikian, ioctl tidak berada di cabang umum Android, tetapi
dikirimkan dalam kernel umum kami.
Efek dari perubahan ini adalah bahwa pewarisan prioritas real-time dinonaktifkan secara default untuk setiap node. Tim performa Android telah menemukan
manfaat untuk mengaktifkan pewarisan prioritas real-time untuk semua node di
domain hwbinder
. Untuk mendapatkan efek yang sama, pilih
perubahan ini di ruang pengguna.
SHA untuk kernel umum
Untuk mendapatkan perubahan yang diperlukan pada driver binder, sinkronkan ke SHA yang sesuai:
- Common-3.18
cc8b90c121de ANDROID: binder: don't check prio permissions on restore. - Common-4.4
76b376eac7a2 ANDROID: binder: don't check prio permissions on restore. - Common-4.9
ecd972d4f9b5 ANDROID: binder: don't check prio permissions on restore.
Bekerja dengan IPC binder
Secara historis, proses vendor telah menggunakan komunikasi antarproses
(IPC) binder untuk berkomunikasi. Di Android 8, node perangkat /dev/binder
menjadi eksklusif untuk proses framework, yang berarti proses vendor tidak lagi
memiliki akses ke node tersebut. Proses vendor dapat mengakses /dev/hwbinder
, tetapi
harus mengonversi antarmuka AIDL mereka untuk menggunakan HIDL. Untuk vendor yang ingin terus
menggunakan antarmuka AIDL di antara proses vendor, Android mendukung IPC binder seperti
yang dijelaskan di bawah. Di Android 10, AIDL Stabil memungkinkan semua
proses menggunakan /dev/binder
sekaligus menyelesaikan jaminan
stabilitas HIDL dan /dev/hwbinder
yang diselesaikan. Untuk mengetahui cara menggunakan AIDL
Stabil, lihat
AIDL untuk HAL.
vndbinder
Android 8 mendukung domain binder baru untuk digunakan oleh layanan vendor, yang diakses
menggunakan /dev/vndbinder
, bukan /dev/binder
. Dengan
penambahan /dev/vndbinder
, Android kini memiliki tiga
domain IPC berikut:
Domain IPC | Deskripsi |
---|---|
/dev/binder |
IPC antara proses framework/aplikasi dengan antarmuka AIDL |
/dev/hwbinder |
IPC 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 item konfigurasi kernel
CONFIG_ANDROID_BINDER_DEVICES
disetel ke
"binder,hwbinder,vndbinder"
(ini adalah setelan default di
hierarki kernel umum Android).
Biasanya, proses vendor tidak membuka driver binder secara langsung, tetapi
melakukan penautan ke library ruang pengguna libbinder
, yang membuka
driver binder. Menambahkan metode untuk ::android::ProcessState()
akan memilih driver binder 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()
proses vendor
(klien dan server):
ProcessState::initWithDriver("/dev/vndbinder");
vndservicemanager
Sebelumnya, layanan binder didaftarkan dengan servicemanager
,
tempat layanan tersebut dapat diambil oleh proses lain. Di Android 8,
servicemanager
kini digunakan secara eksklusif oleh proses framework dan
aplikasi, dan proses vendor tidak dapat lagi mengaksesnya.
Namun, layanan vendor kini dapat menggunakan vndservicemanager
, instance
servicemanager
baru yang menggunakan /dev/vndbinder
bukan /dev/binder
dan dibuat dari sumber yang sama dengan
framework servicemanager
. Proses vendor tidak perlu melakukan
perubahan untuk berkomunikasi dengan vndservicemanager
; saat proses vendor membuka
/dev/vndbinder
, pencarian layanan akan otomatis membuka
vndservicemanager
.
Biner vndservicemanager
disertakan dalam makefile
perangkat default Android.
Kebijakan SELinux
Proses vendor yang ingin menggunakan fungsi binder untuk berkomunikasi satu sama lain memerlukan hal berikut:
- Akses ke
/dev/vndbinder
. - Binder
{transfer, call}
mengaitkan kevndservicemanager
. binder_call(A, B)
untuk setiap domain vendor A yang ingin memanggil domain vendor B melalui antarmuka binder vendor.- Izin ke layanan
{add, find}
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 berkomunikasi melalui binder dapat tetap ada, dan tidak
perlu diganti namanya.
Untuk memenuhi persyaratan 4, Anda harus melakukan perubahan pada cara nama layanan, label layanan, dan aturan ditangani.
Untuk mengetahui detail tentang SELinux, lihat Security-Enhanced Linux di Android. Untuk mengetahui 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 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
file vndservice_contexts
. Layanan vendor yang dimigrasikan ke
vndservicemanager
(dan yang sudah ada dalam file
service_contexts
lama) harus ditambahkan ke file
vndservice_contexts
baru.
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 jenisnya menjadi
vndservice_manager_type
dan memindahkan 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;