Binder IPC'yi kullanma

Bu sayfada Android 8'deki ciltleyici sürücüsünde yapılan değişiklikler açıklanmakta, ciltleyici IPC kullanımına ilişkin ayrıntılar sağlanmakta ve gerekli SELinux politikası listelenmektedir.

Ciltleyici sürücüsündeki değişiklikler

Android 8'den başlayarak, Android çerçevesi ve HAL'ler artık bağlayıcı kullanarak birbirleriyle iletişim kuruyor. Bu iletişim ciltleyici trafiğini önemli ölçüde artırdığından Android 8, ciltleyici IPC'sini hızlı tutmak için tasarlanmış çeşitli iyileştirmeler içerir. SoC satıcıları ve OEM'ler , çekirdek/ortak projenin Android-4.4, Android-4.9 ve üzeri ilgili dallarından doğrudan birleşmelidir.

Çoklu bağlayıcı etki alanları (bağlamlar)

Yukarı akış dahil Common-4.4 ve üzeri

Ciltleyici trafiğini çerçeve (cihazdan bağımsız) ve satıcı (cihaza özel) kodu arasında temiz bir şekilde bölmek için Android 8, ciltleyici bağlamı kavramını tanıttı. Her ciltleyici bağlamının kendi aygıt düğümü ve kendi bağlam (hizmet) yöneticisi vardır. Bağlam yöneticisine yalnızca ait olduğu aygıt düğümü aracılığıyla erişebilirsiniz ve bir bağlayıcı düğümü belirli bir bağlamdan geçirirken aynı bağlamdan yalnızca başka bir işlem tarafından erişilebilir, böylece etki alanları birbirinden tamamen yalıtılır. Kullanımla ilgili ayrıntılar için vndbinder ve vndservicemanager'a bakın.

Dağılım-toplama

Yukarı akış dahil Common-4.4 ve üzeri

Android'in önceki sürümlerinde, ciltleyici çağrısındaki her veri parçası üç kez kopyalanıyordu:

  • Arama sürecinde onu bir Parcel serileştirmek için bir kez
  • Parcel hedef işleme kopyalamak için çekirdek sürücüsüne girdikten sonra
  • Hedef süreçte Parcel kaldırmak için bir kez

Android 8, kopya sayısını 3'ten 1'e düşürmek için dağılım toplama optimizasyonunu kullanır. Önce bir Parcel verileri serileştirmek yerine, veriler orijinal yapısında ve bellek düzeninde kalır ve sürücü bunu hemen hedef işleme kopyalar. Veriler hedef işleme alındıktan sonra yapı ve bellek düzeni aynı olur ve veriler başka bir kopyaya ihtiyaç duymadan okunabilir.

İnce taneli kilitleme

Yukarı akış dahil Common-4.4 ve üzeri

Önceki Android sürümlerinde ciltleyici sürücüsü, kritik veri yapılarına eşzamanlı erişime karşı koruma sağlamak için genel bir kilit kullanıyordu. Kilit için minimum düzeyde çekişme olsa da asıl sorun, düşük öncelikli bir iş parçacığının kilidi ele geçirmesi ve ardından engellenmesi durumunda, aynı kilidi elde etmesi gereken yüksek öncelikli iş parçacıklarının ciddi şekilde geciktirilmesiydi. Bu da platformda sarsıntıya neden oldu.

Bu sorunu çözmeye yönelik ilk girişimler, genel kilidi tutarken önlemeyi devre dışı bırakmayı içeriyordu. Ancak bu, gerçek bir çözümden çok bir hack'ti ve sonunda yukarı akış tarafından reddedildi ve bir kenara atıldı. Daha sonraki girişimler, bir sürümü Ocak 2017'den bu yana Pixel cihazlarda çalışan kilitlemeyi daha ayrıntılı hale getirmeye odaklandı. Bu değişikliklerin çoğu halka açıklanırken, sonraki sürümlerde önemli iyileştirmeler yapıldı.

Ayrıntılı kilitleme uygulamasındaki küçük sorunları belirledikten sonra, farklı bir kilitleme mimarisine sahip gelişmiş bir çözüm tasarladık ve değişiklikleri tüm ortak çekirdek dallarında sunduk. Bu uygulamayı çok sayıda farklı cihazda test etmeye devam ediyoruz; Herhangi bir çözülmemiş sorundan haberimiz olmadığından, Android 8 ile gönderilen cihazlar için önerilen uygulama budur.

Gerçek zamanlı öncelikli miras

Common-4.4 ve common-4.9 (yukarı akış yakında)

Ciltleyici sürücüsü her zaman güzel öncelikli kalıtımı desteklemiştir. Android'de giderek artan sayıda işlem gerçek zamanlı öncelikte çalıştığından, bazı durumlarda, gerçek zamanlı bir iş parçacığının bir ciltleyici çağrısı yapması durumunda, bu çağrıyı işleyen işlemdeki iş parçacığının da gerçek zamanlı öncelikte çalışması artık anlamlı hale geliyor . Bu kullanım örneklerini desteklemek için Android 8 artık ciltleyici sürücüsünde gerçek zamanlı öncelik devralmayı uyguluyor.

İşlem düzeyinde öncelik devralımına ek olarak, düğüm önceliği devralma , bir düğümün (bağlayıcı hizmet nesnesi), bu düğüme yapılan çağrıların yürütülmesi gereken minimum önceliği belirlemesine olanak tanır. Android'in önceki sürümleri, güzel değerlerle düğüm önceliği devralmayı zaten destekliyordu, ancak Android 8, gerçek zamanlı planlama politikaları düğüm mirası için destek ekliyor.

Kullanıcı alanı değişiklikleri

Android 8, ortak çekirdekteki geçerli ciltleyici sürücüsüyle çalışmak için gereken tüm kullanıcı alanı değişikliklerini bir istisna dışında içerir: /dev/binder için gerçek zamanlı öncelik devralmayı devre dışı bırakan orijinal uygulama, bir ioctl kullanıyordu. Daha sonraki geliştirmeler, öncelikli mirasın kontrolünü, ciltleme modu başına (bağlam başına değil) daha ayrıntılı bir yönteme dönüştürdü. Bu nedenle, ioctl Android ortak dalında değildir ve bunun yerine ortak çekirdeklerimizde gönderilir .

Bu değişikliğin etkisi, gerçek zamanlı öncelik devralmanın her düğüm için varsayılan olarak devre dışı bırakılmasıdır. Android performans ekibi, hwbinder alanındaki tüm düğümler için gerçek zamanlı öncelik devralmayı etkinleştirmenin faydalı olduğunu buldu. Aynı etkiyi elde etmek için kullanıcı alanındaki bu değişikliği özenle seçin.

Ortak çekirdekler için SHA'lar

Ciltleyici sürücüsünde gerekli değişiklikleri elde etmek için uygun SHA ile eşitleyin:

  • Ortak-3.18
    cc8b90c121de ANDROID: bağlayıcı: geri yükleme sırasında öncelik izinlerini kontrol etmeyin.
  • Ortak-4.4
    76b376eac7a2 ANDROID: bağlayıcı: geri yükleme sırasında öncelik izinlerini kontrol etmeyin.
  • Ortak-4.9
    ecd972d4f9b5 ANDROID: bağlayıcı: geri yükleme sırasında öncelik izinlerini kontrol etmeyin.

Bağlayıcı IPC'yi kullanma

Geçmişte, satıcı süreçleri iletişim kurmak için bağlayıcı süreçler arası iletişimi (IPC) kullanmıştır. Android 8'de, /dev/binder aygıt düğümü çerçeve işlemlerine özel hale gelir; bu, satıcı süreçlerinin artık ona erişemeyeceği anlamına gelir. Satıcı işlemleri /dev/hwbinder erişebilir, ancak AIDL arayüzlerini HIDL kullanacak şekilde dönüştürmeleri gerekir. Satıcı işlemleri arasında AIDL arayüzlerini kullanmaya devam etmek isteyen satıcılar için Android, aşağıda açıklandığı gibi bağlayıcı IPC'yi destekler. Android 10'da Stabil AIDL, tüm işlemlerin /dev/binder kullanmasına izin verirken aynı zamanda HIDL ve /dev/hwbinder çözümlerinin kararlılığını garanti eder. Stabil AIDL'nin nasıl kullanılacağı hakkında bilgi için bkz. HAL'ler için AIDL .

vndbinder

Android 8, satıcı hizmetleri tarafından kullanılmak üzere, /dev/ /dev/binder yerine /dev /dev/vndbinder kullanılarak erişilen yeni bir bağlayıcı etki alanını destekler. /dev/vndbinder eklenmesiyle Android artık aşağıdaki üç IPC alanına sahiptir:

IPC Alanı Tanım
/dev/binder AIDL arayüzleriyle çerçeve/uygulama işlemleri arasındaki IPC
/dev/hwbinder HIDL arayüzleriyle çerçeve/satıcı işlemleri arasındaki IPC
HIDL arayüzleriyle satıcı işlemleri arasında IPC
/dev/vndbinder AIDL Arayüzleriyle satıcı/satıcı işlemleri arasındaki IPC

/dev/vndbinder görünmesi için, CONFIG_ANDROID_BINDER_DEVICES çekirdek yapılandırma öğesinin "binder,hwbinder,vndbinder" olarak ayarlandığından emin olun (bu, Android'in ortak çekirdek ağaçlarında varsayılandır).

Normalde, satıcı işlemleri ciltleyici sürücüsünü doğrudan açmaz ve bunun yerine ciltleyici sürücüsünü açan libbinder kullanıcı alanı kitaplığına bağlanır. ::android::ProcessState() için bir yöntem eklemek, libbinder için ciltleyici sürücüsünü seçer. Satıcı işlemleri, ProcessState, IPCThreadState çağırmadan veya genel olarak herhangi bir bağlayıcı çağrı yapmadan önce bu yöntemi çağırmalıdır. Kullanmak için, bir satıcı işleminin (istemci ve sunucu) main() işlevinden sonra aşağıdaki çağrıyı yapın:

ProcessState::initWithDriver("/dev/vndbinder");

vndservicemanager

Daha önce ciltleyici hizmetleri, diğer işlemler tarafından alınabilecekleri servicemanager kaydediliyordu. Android 8'de servicemanager artık yalnızca çerçeve ve uygulama süreçleri tarafından kullanılıyor ve satıcı süreçleri artık ona erişemiyor.

Ancak satıcı hizmetleri artık /dev /dev/binder /dev/vndbinder kullanan ve çerçeve servicemanager ile aynı kaynaklardan oluşturulan yeni bir servicemanager örneği olan vndservicemanager kullanabilir. Satıcı süreçlerinin vndservicemanager ile konuşmak için değişiklik yapmasına gerek yoktur; bir satıcı işlemi / dev/vndbinder açıldığında, hizmet aramaları otomatik olarak vndservicemanager gider.

vndservicemanager ikili dosyası, Android'in varsayılan cihaz makefile dosyalarına dahil edilmiştir.

SELinux politikası

Birbirleriyle iletişim kurmak için ciltleyici işlevselliğini kullanmak isteyen satıcı işlemlerinin aşağıdakilere ihtiyacı vardır:

  1. /dev/vndbinder erişim.
  2. Bağlayıcı {transfer, call} vndservicemanager bağlanır.
  3. Satıcı bağlayıcı arayüzü üzerinden satıcı etki alanı B'ye çağrı yapmak isteyen herhangi bir satıcı etki alanı A için binder_call(A, B) .
  4. vndservicemanager {add, find} hizmetlerine izin.

1. ve 2. gereksinimleri karşılamak için vndbinder_use() makrosunu kullanın:

vndbinder_use(some_vendor_process_domain);

Gereksinim 3'ü karşılamak için, bağlayıcı üzerinden konuşması gereken A ve B satıcı işlemlerine yönelik binder_call(A, B) yerinde kalabilir ve yeniden adlandırılmasına gerek yoktur.

Gereksinim 4'ü karşılamak için hizmet adlarının, hizmet etiketlerinin ve kuralların işlenme biçiminde değişiklik yapmanız gerekir.

SELinux ile ilgili ayrıntılar için bkz. Android'de Güvenliği Geliştirilmiş Linux . Android 8.0'daki SELinux'a ilişkin ayrıntılar için bkz. Android 8.0 için SELinux .

Hizmet adları

Daha önce satıcı, kayıtlı hizmet adlarını bir service_contexts dosyasında işliyor ve bu dosyaya erişim için ilgili kuralları ekliyordu. device/google/marlin/sepolicy örnek service_contexts dosyası:

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'de vndservicemanager bunun yerine vndservice_contexts dosyasını yükler. vndservicemanager taşınan (ve zaten eski service_contexts dosyasında bulunan) satıcı hizmetleri yeni vndservice_contexts dosyasına eklenmelidir.

Servis etiketleri

Daha önce u:object_r:atfwd_service:s0 gibi hizmet etiketleri bir service.te dosyasında tanımlanıyordu. Örnek:

type atfwd_service,      service_manager_type;

Android 8'de türü vndservice_manager_type olarak değiştirmeli ve kuralı vndservice.te dosyasına taşımalısınız. Örnek:

type atfwd_service,      vndservice_manager_type;

Servis yöneticisi kuralları

Daha önce kurallar, etki alanlarına servicemanager hizmet ekleme veya bulma erişimi veriyordu. Örnek:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;

Android 8'de bu tür kurallar yerinde kalabilir ve aynı sınıfı kullanabilir. Örnek:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;