Google is committed to advancing racial equity for Black communities. See how.
Trang này được dịch bởi Cloud Translation API.
Switch to English

Sử dụng Binder IPC

Trang này mô tả những thay đổi đối với trình điều khiển chất kết dính trong Android 8, cung cấp thông tin chi tiết về cách sử dụng IPC chất kết dính và liệt kê chính sách SELinux bắt buộc.

Các thay đổi đối với trình điều khiển chất kết dính

Bắt đầu từ Android 8, khung Android và HAL hiện giao tiếp với nhau bằng chất kết dính. Khi giao tiếp này tăng đáng kể lưu lượng truy cập chất kết dính, Android 8 bao gồm một số cải tiến được thiết kế để giữ cho IPC kết dính nhanh chóng. Các nhà cung cấp SoC và OEM nên hợp nhất trực tiếp từ các nhánh liên quan của android-4.4, android-4.9 và cao hơn của dự án kernel / common .

Nhiều miền liên kết (ngữ cảnh)

Phổ biến-4.4 trở lên, bao gồm ngược dòng

Để phân chia rõ ràng lưu lượng kết dính giữa mã khung (độc lập với thiết bị) và mã của nhà cung cấp (dành riêng cho thiết bị), Android 8 đã giới thiệu khái niệm về ngữ cảnh liên kết . Mỗi ngữ cảnh kết dính có nút thiết bị riêng và trình quản lý ngữ cảnh (dịch vụ) riêng. Bạn chỉ có thể truy cập trình quản lý ngữ cảnh thông qua nút thiết bị mà nó thuộc về và khi chuyển một nút liên kết qua một ngữ cảnh nhất định, nó chỉ có thể truy cập từ cùng ngữ cảnh đó bằng một quy trình khác, do đó hoàn toàn cách ly các miền với nhau. Để biết chi tiết về cách sử dụng, hãy xem vndbindervndservicemanager .

Thu thập phân tán

Phổ biến-4.4 trở lên, bao gồm ngược dòng

Trong các bản phát hành trước của Android, mọi phần dữ liệu trong lệnh gọi liên kết được sao chép ba lần:

  • Một lần để tuần tự hóa nó thành một Parcel trong quá trình gọi
  • Khi ở trong trình điều khiển hạt nhân để sao chép Parcel vào quy trình đích
  • Một lần để hủy số hóa Parcel trong quy trình đích

Android 8 sử dụng tính năng tối ưu hóa thu thập phân tán để giảm số lượng bản sao từ 3 xuống 1. Thay vì tuần tự hóa dữ liệu trong một Parcel trước, dữ liệu vẫn ở trong cấu trúc và bố cục bộ nhớ ban đầu và trình điều khiển ngay lập tức sao chép nó vào tiến trình đích. Sau khi dữ liệu ở trong quá trình đích, cấu trúc và bố cục bộ nhớ giống nhau và dữ liệu có thể được đọc mà không cần bản sao khác.

Khóa hạt mịn

Phổ biến-4.4 trở lên, bao gồm ngược dòng

Trong các phiên bản Android trước, trình điều khiển chất kết dính đã sử dụng khóa toàn cầu để bảo vệ chống lại việc truy cập đồng thời vào các cấu trúc dữ liệu quan trọng. Mặc dù có sự tranh cãi tối thiểu về khóa, nhưng vấn đề chính là nếu một luồng có mức độ ưu tiên thấp nhận được khóa và sau đó được ưu tiên trước, nó có thể trì hoãn nghiêm trọng các luồng có mức độ ưu tiên cao hơn cần có được cùng một khóa. Điều này đã gây ra sự cố trong nền tảng.

Những nỗ lực ban đầu để giải quyết vấn đề này liên quan đến việc tắt quyền ưu tiên trong khi giữ khóa toàn cầu. Tuy nhiên, đây là một vụ hack hơn là một giải pháp thực sự, và cuối cùng đã bị từ chối bởi thượng nguồn và bị loại bỏ. Những nỗ lực tiếp theo tập trung vào việc khóa chi tiết hơn, một phiên bản đã chạy trên thiết bị Pixel từ tháng 1 năm 2017. Mặc dù phần lớn những thay đổi đó đã được công khai, nhưng những cải tiến đáng kể đã được thực hiện trong các phiên bản tiếp theo.

Sau khi xác định các vấn đề nhỏ trong việc triển khai khóa chi tiết, chúng tôi đã nghĩ ra một giải pháp cải tiến với kiến ​​trúc khóa khác và gửi các thay đổi trong tất cả các nhánh hạt nhân chung. Chúng tôi tiếp tục thử nghiệm việc triển khai này trên một số lượng lớn các thiết bị khác nhau; vì chúng tôi không biết về bất kỳ vấn đề nào còn tồn tại, đây là cách triển khai được khuyến nghị cho các thiết bị vận chuyển bằng Android 8.

Kế thừa ưu tiên thời gian thực

Common-4.4 và common-4.9 (sắp có ngược dòng)

Trình điều khiển chất kết dính luôn hỗ trợ kế thừa ưu tiên tốt đẹp. Khi ngày càng có nhiều quy trình trong Android chạy ở mức ưu tiên thời gian thực, trong một số trường hợp, giờ đây có nghĩa là nếu một chuỗi thời gian thực thực hiện một cuộc gọi liên kết, thì chuỗi trong quá trình xử lý cuộc gọi đó cũng chạy ở mức ưu tiên thời gian thực . Để hỗ trợ các trường hợp sử dụng này, Android 8 hiện triển khai kế thừa ưu tiên theo thời gian thực trong trình điều khiển chất kết dính.

Ngoài kế thừa mức độ ưu tiên giao dịch, kế thừa mức độ ưu tiên nút cho phép một nút (đối tượng dịch vụ chất kết dính) chỉ định mức ưu tiên tối thiểu mà tại đó các lệnh gọi vào nút này sẽ được thực hiện. Các phiên bản trước của Android đã hỗ trợ kế thừa quyền ưu tiên nút với các giá trị tốt, nhưng Android 8 bổ sung hỗ trợ kế thừa nút chính sách lập lịch thời gian thực.

Thay đổi không gian người dùng

Android 8 bao gồm tất cả các thay đổi không gian người dùng cần thiết để hoạt động với trình điều khiển chất kết dính hiện tại trong nhân chung với một ngoại lệ: Việc triển khai gốc để vô hiệu hóa kế thừa ưu tiên theo thời gian thực cho /dev/binder sử dụng ioctl . Sự phát triển tiếp theo đã chuyển quyền kiểm soát quyền thừa kế ưu tiên sang một phương pháp chi tiết hơn là theo chế độ kết dính (chứ không phải theo ngữ cảnh). Do đó, ioctl không nằm trong nhánh chung của Android và thay vào đó được gửi trong các hạt nhân chung của chúng ta .

Ảnh hưởng của thay đổi này là việc kế thừa mức độ ưu tiên theo thời gian thực bị vô hiệu hóa theo mặc định cho mọi nút. Nhóm hiệu suất của Android đã nhận thấy rằng việc bật kế thừa ưu tiên theo thời gian thực cho tất cả các nút trong miền hwbinder . Để đạt được hiệu quả tương tự, hãy chọn thay đổi này trong không gian người dùng.

SHA cho các hạt nhân chung

Để có được những thay đổi cần thiết đối với trình điều khiển chất kết dính, hãy đồng bộ hóa với SHA thích hợp:

  • Common-3,18
    cc8b90c121de ANDROID: binder: không kiểm tra quyền ban đầu khi khôi phục.
  • Chung-4,4
    76b376eac7a2 ANDROID: binder: không kiểm tra các quyền ban đầu khi khôi phục.
  • Chung-4,9
    ecd972d4f9b5 ANDROID: binder: không kiểm tra các quyền ban đầu khi khôi phục.

Sử dụng chất kết dính IPC

Trong lịch sử, các quy trình của nhà cung cấp đã sử dụng giao tiếp liên quá trình kết dính (IPC) để giao tiếp. Trong Android 8, nút thiết bị /dev/binder trở thành độc quyền cho các quy trình khung, nghĩa là các quy trình của nhà cung cấp không còn quyền truy cập vào nó nữa. Các quy trình của nhà cung cấp có thể truy cập /dev/hwbinder , nhưng phải chuyển đổi giao diện AIDL của họ để sử dụng HIDL. Đối với các nhà cung cấp muốn tiếp tục sử dụng giao diện AIDL giữa các quy trình của nhà cung cấp, Android hỗ trợ IPC liên kết như được mô tả bên dưới.

vndbinder

Android 8 hỗ trợ miền liên kết mới để các dịch vụ của nhà cung cấp sử dụng, được truy cập bằng /dev/vndbinder thay vì /dev/binder . Với việc bổ sung /dev/vndbinder , Android hiện có ba miền IPC sau:

Tên miền IPC Sự miêu tả
/dev/binder IPC giữa các quy trình khung / ứng dụng với giao diện AIDL
/dev/hwbinder IPC giữa các quy trình khung / nhà cung cấp với giao diện HIDL
IPC giữa các quy trình của nhà cung cấp với giao diện HIDL
/dev/vndbinder IPC giữa các quy trình của nhà cung cấp / nhà cung cấp với Giao diện AIDL

Để /dev/vndbinder xuất hiện, hãy đảm bảo mục cấu hình hạt nhân CONFIG_ANDROID_BINDER_DEVICES được đặt thành "binder,hwbinder,vndbinder" (đây là mặc định trong cây nhân phổ biến của Android).

Thông thường, các quy trình của nhà cung cấp không mở trực tiếp trình điều khiển chất kết dính và thay vào đó liên kết với thư viện không gian người dùng libbinder , thư viện mở trình điều khiển chất kết dính. Thêm một phương thức cho ::android::ProcessState() chọn trình điều khiển chất kết dính cho libbinder . Các quy trình của nhà cung cấp nên gọi phương thức này trước khi gọi vào ProcessState, IPCThreadState hoặc trước khi thực hiện bất kỳ lệnh gọi liên kết nào nói chung. Để sử dụng, hãy đặt lệnh gọi sau sau lệnh main() của quy trình nhà cung cấp (máy khách và máy chủ):

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

vndservicemanager

Trước đây, các dịch vụ chất kết dính đã được đăng ký với servicemanager , nơi chúng có thể được truy xuất bởi các quy trình khác. Trong Android 8, servicemanager hiện được sử dụng riêng bởi các quy trình ứng dụng và khuôn khổ, đồng thời các quy trình của nhà cung cấp không còn có thể truy cập vào nó nữa.

Tuy nhiên, các dịch vụ của nhà cung cấp hiện có thể sử dụng vndservicemanager , một phiên bản mới của servicemanager sử dụng /dev/vndbinder thay vì /dev/binder và được xây dựng từ các nguồn giống như framework servicemanager . Quy trình của nhà cung cấp không cần thực hiện thay đổi để nói chuyện với vndservicemanager ; khi một quy trình của nhà cung cấp mở / dev/vndbinder , các tra cứu dịch vụ sẽ tự động chuyển đến vndservicemanager .

Hệ nhị phân vndservicemanager được bao gồm trong cấu hình thiết bị mặc định của Android.

Chính sách SELinux

Các quy trình của nhà cung cấp muốn sử dụng chức năng kết dính để giao tiếp với nhau cần những điều sau:

  1. Truy cập vào /dev/vndbinder .
  2. Binder {transfer, call} móc vào vndservicemanager .
  3. binder_call(A, B) cho bất kỳ miền nhà cung cấp A nào muốn gọi vào miền nhà cung cấp B qua giao diện liên kết nhà cung cấp.
  4. Quyền đối với các dịch vụ {add, find} trong vndservicemanager .

Để đáp ứng các yêu cầu 1 và 2, hãy sử dụng vndbinder_use() :

vndbinder_use(some_vendor_process_domain);

Để đáp ứng yêu cầu 3, binder_call(A, B) cho các quy trình của nhà cung cấp A và B cần trao đổi về chất kết dính có thể ở nguyên vị trí và không cần đổi tên.

Để đáp ứng yêu cầu 4, bạn phải thực hiện các thay đổi trong cách xử lý tên dịch vụ, nhãn dịch vụ và quy tắc.

Để biết chi tiết về SELinux, hãy xem Linux được tăng cường bảo mật trong Android . Để biết chi tiết về SELinux trong Android 8.0, hãy xem SELinux dành cho Android 8.0 .

Tên dịch vụ

Trước đây, nhà cung cấp xử lý các tên dịch vụ đã đăng ký trong tệp service_contexts và thêm các quy tắc tương ứng để truy cập tệp đó. Tệp service_contexts từ 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

Trong Android 8, vndservicemanager tải tệp vndservice_contexts . Các dịch vụ của nhà cung cấp di chuyển sang vndservicemanager (và đã có trong tệp service_contexts cũ) phải được thêm vào tệp vndservice_contexts mới.

Nhãn dịch vụ

Trước đây, các nhãn dịch vụ như u:object_r:atfwd_service:s0 được định nghĩa trong tệp service.te . Thí dụ:

type atfwd_service,      service_manager_type;

Trong Android 8, bạn phải thay đổi loại thành vndservice_manager_type và di chuyển quy tắc vào tệp vndservice.te . Thí dụ:

type atfwd_service,      vndservice_manager_type;

Quy tắc của người quản lý dịch vụ

Trước đây, các quy tắc đã cấp cho miền quyền truy cập để thêm hoặc tìm dịch vụ từ servicemanager dịch vụ. Thí dụ:

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

Trong Android 8, các quy tắc như vậy có thể được giữ nguyên và sử dụng cùng một lớp. Thí dụ:

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