Microdroid là một hệ điều hành Android mini chạy trong pVM. Bạn không cần phải sử dụng Microdroid, bạn có thể khởi động máy ảo với bất kỳ hệ điều hành nào. Tuy nhiên, các trường hợp sử dụng chính cho pVM không chạy một hệ điều hành độc lập mà là cung cấp một môi trường thực thi riêng biệt để chạy một phần của ứng dụng với đảm bảo tính toàn vẹn và bảo mật mạnh hơn những gì Android có thể cung cấp.
Với các hệ điều hành truyền thống, việc cung cấp tính bảo mật và tính toàn vẹn mạnh mẽ đòi hỏi một khối lượng công việc hợp lý (thường bị trùng lặp) vì các hệ điều hành truyền thống không phù hợp với kiến trúc bao trùm của Android. Ví dụ: với kiến trúc Android tiêu chuẩn, các nhà phát triển cần triển khai phương tiện tải và thực thi an toàn một phần ứng dụng của họ trong pVM và tải trọng được xây dựng dựa trên glibc. Ứng dụng Android sử dụng Bionic, giao tiếp yêu cầu một giao thức tùy chỉnh qua vsock và gỡ lỗi bằng cách sử dụng adb là một thách thức.
Microdroid lấp đầy những khoảng trống này bằng cách cung cấp hình ảnh hệ điều hành có sẵn được thiết kế để yêu cầu ít nỗ lực nhất từ các nhà phát triển để giảm tải một phần ứng dụng của họ vào một pVM. Mã gốc được xây dựng dựa trên Bionic, giao tiếp diễn ra qua Binder và nó cho phép nhập APEX từ Android và hiển thị một tập hợp con của API Android, chẳng hạn như kho khóa cho các hoạt động mật mã với các khóa được phần cứng hỗ trợ. Nhìn chung, các nhà phát triển nên thấy Microdroid một môi trường quen thuộc với các công cụ mà họ đã quen thuộc trong hệ điều hành Android đầy đủ.
Đặc trưng
Microdroid là phiên bản rút gọn của Android với một số thành phần bổ sung dành riêng cho pVM. Microdroid hỗ trợ:
- Một tập hợp con các API NDK (tất cả các API để triển khai libc và Bionic của Android đều được cung cấp)
- Các tính năng gỡ lỗi, chẳng hạn như adb, logcat, Tombstone và gdb
- Khởi động đã xác minh và đã bật SELinux
- Tải và thực thi tệp nhị phân, cùng với các thư viện được chia sẻ, được nhúng trong APK
- RPC ràng buộc qua vsock và trao đổi tệp với kiểm tra tính toàn vẹn ngầm
- Đang tải các APEX
Microdroid không hỗ trợ:
Các API Android Java trong các gói
android.\*
SystemServer và Zygote
Đồ họa / Giao diện người dùng
HAL
Kiến trúc microdroid
Microdroid tương tự như Cuttlefish ở điểm cả hai đều có kiến trúc tương tự như Android tiêu chuẩn. Microdroid bao gồm các hình ảnh phân vùng sau được nhóm lại với nhau trong một hình ảnh đĩa tổng hợp:
-
bootloader
- Xác minh và khởi động hạt nhân. -
boot.img
- Chứa kernel và init ramdisk. -
vendor\_boot.img
- Chứa các mô-đun hạt nhân dành riêng cho máy ảo, chẳng hạn như virtio. -
super.img
- Bao gồm các phân vùng logic của hệ thống và nhà cung cấp. -
vbmeta.img
- Chứa siêu dữ liệu khởi động đã được xác minh.
Hình ảnh phân vùng được gửi trong Virtualization APEX và được VirtualizationService
đóng gói trong một hình ảnh đĩa tổng hợp. Ngoài hình ảnh đĩa tổng hợp hệ điều hành chính, VirtualizationService
chịu trách nhiệm tạo các phân vùng khác sau:
-
payload
- Một tập hợp các phân vùng được hỗ trợ bởi các APEX và APK của Android -
instance
bản - Một phân vùng được mã hóa để lưu trữ dữ liệu khởi động được xác minh theo từng trường hợp, chẳng hạn như muối của từng trường hợp, khóa công khai APEX đáng tin cậy và bộ đếm khôi phục
Trình tự khởi động
Trình tự khởi động Microdroid xảy ra sau khi khởi động Thiết bị . Khởi động thiết bị được thảo luận trong tài liệu Kiến trúc . Hình 1 cho thấy các bước diễn ra trong trình tự khởi động Microdroid:
Dưới đây là giải thích về các bước:
Bộ nạp khởi động được crossvm nạp vào bộ nhớ và pvmfw bắt đầu thực thi. Trước khi chuyển đến bộ nạp khởi động, pvmfw thực hiện hai tác vụ:
- Xác minh bộ nạp khởi động để kiểm tra xem nó có phải từ một nguồn đáng tin cậy (Google hoặc OEM) hay không.
- Đảm bảo rằng cùng một bộ nạp khởi động được sử dụng nhất quán trên nhiều khởi động của cùng một pVM thông qua việc sử dụng hình ảnh phiên bản. Cụ thể, pVM ban đầu được khởi động với một hình ảnh phiên bản trống. pvmfw lưu trữ danh tính của bộ nạp khởi động trong hình ảnh cá thể và mã hóa nó. Vì vậy, lần tiếp theo pVM được khởi động với cùng một hình ảnh phiên bản, pvmfw sẽ giải mã danh tính đã lưu từ hình ảnh cá thể đó và xác minh rằng đó là danh tính đã được lưu trước đó. Nếu danh tính khác nhau, pvmfw sẽ từ chối khởi động.
Sau đó, bộ nạp khởi động sẽ khởi động Microdroid.
Bộ nạp khởi động truy cập đĩa cá thể. Tương tự như pvmfw, bộ nạp khởi động có ổ đĩa cá thể chứa thông tin về hình ảnh phân vùng được sử dụng trong trường hợp này trong quá trình khởi động trước đó, bao gồm cả khóa công khai.
Bộ nạp khởi động xác minh vbmeta và các phân vùng được xâu chuỗi, chẳng hạn như
boot
vàsuper
, và nếu thành công, sẽ lấy ra các bí mật pVM ở giai đoạn tiếp theo. Sau đó, Microdroid sẽ kiểm soát kernel.Vì siêu phân vùng đã được bộ nạp khởi động xác minh (bước 3), hạt nhân sẽ gắn kết siêu phân vùng một cách vô điều kiện. Như với Android đầy đủ, siêu phân vùng bao gồm nhiều phân vùng logic được gắn trên dm-verity. Kiểm soát sau đó được chuyển cho quá trình
init
, quá trình này bắt đầu các dịch vụ gốc khác nhau. Tập lệnhinit.rc
tương tự như tập lệnh của Android đầy đủ nhưng phù hợp với nhu cầu của Microdroid.Quá trình
init
khởi động trình quản lý Microdroid, trình quản lý này truy cập vào hình ảnh cá thể. Dịch vụ trình quản lý Microdroid giải mã hình ảnh bằng cách sử dụng khóa được chuyển từ giai đoạn trước và đọc khóa công khai và bộ đếm khôi phục của APK ứng dụng khách và APEX mà pVM này tin cậy. Thông tin này được sử dụng sau đó bởizipfuse
vàapexd
khi họ gắn APK ứng dụng khách và các APEX được yêu cầu, tương ứng.Dịch vụ trình quản lý Microdroid bắt đầu
apexd
.apexd
gắn kết các APEX tại thư mục/apex/<name>
. Sự khác biệt duy nhất giữa cách Android và Microdroid mounta APEXes là trong Microdroid, các tệp APEX đến từ các thiết bị khối ảo (/dev/vdc1
,…), không phải từ các tệp thông thường (/system/apex/*.apex
).zipfuse
là hệ thống tệp FUSE của Microdroid.zipfuse
gắn kết APK ứng dụng khách, về cơ bản là tệp Zip dưới dạng hệ thống tệp. Bên dưới, tệp APK được pVM chuyển dưới dạng thiết bị khối ảo với dm-verity, giống như APEX. APK chứa tệp cấu hình với danh sách các APEX mà nhà phát triển ứng dụng đã yêu cầu cho phiên bản pVM này. Danh sách được sử dụng bởiapexd
khi kích hoạt các APEX.Luồng khởi động quay trở lại dịch vụ trình quản lý Microdroid. Dịch vụ trình quản lý sau đó giao tiếp với
VirtualizationService
của Android bằng Binder RPC để nó có thể báo cáo các sự kiện quan trọng như sự cố hoặc tắt máy và chấp nhận các yêu cầu như chấm dứt pVM. Dịch vụ trình quản lý đọc vị trí của tệp nhị phân chính từ tệp cấu hình của APK và thực thi nó.
Trao đổi tệp (AuthFS)
Các thành phần Android thường sử dụng tệp cho đầu vào, đầu ra và trạng thái và chuyển chúng dưới dạng bộ mô tả tệp (kiểu ParcelFileDescriptor
trong AIDL) với quyền truy cập được kiểm soát bởi nhân Android. AuthFS tạo điều kiện cho chức năng tương tự để trao đổi tệp giữa các điểm cuối phân tán lẫn nhau qua ranh giới pVM.
Về cơ bản, AuthFS là một hệ thống tệp từ xa có kiểm tra tính toàn vẹn minh bạch trên các hoạt động truy cập cá nhân, tương tự như fs-verity
. Việc kiểm tra cho phép giao diện người dùng, chẳng hạn như chương trình đọc tệp chạy trong pVM, phát hiện xem phần phụ trợ không đáng tin cậy, thường là Android, có can thiệp vào nội dung tệp hay không.
Để trao đổi tệp, phần phụ trợ ( fd\_server
) được bắt đầu với cấu hình từng tệp chỉ định xem nó dành cho đầu vào (chỉ đọc) hay đầu ra (đọc-ghi). Đối với đầu vào, giao diện người dùng thực thi rằng nội dung khớp với một hàm băm đã biết, trên đầu cây Merkle để xác minh khi truy cập. Đối với đầu ra, AuthFS nội bộ duy trì một cây băm của nội dung như được quan sát từ các hoạt động ghi và có thể thực thi tính toàn vẹn khi dữ liệu được đọc lại.
Việc vận chuyển cơ bản hiện dựa trên Binder RPC, tuy nhiên điều đó có thể thay đổi trong tương lai để tối ưu hóa hiệu suất.
Quản lý chính
pVM được cung cấp một khóa niêm phong ổn định phù hợp với dữ liệu liên tục được bảo vệ và khóa chứng thực phù hợp để tạo chữ ký được pVM tạo ra có thể xác minh được.
RPC chất kết dính
Phần lớn các giao diện của Android được thể hiện bằng AIDL , được xây dựng trên trình điều khiển hạt nhân Binder Linux. Để hỗ trợ giao diện giữa các pVM, giao thức Binder đã được viết lại để hoạt động trên các socket, vsock trong trường hợp của pVM. Hoạt động trên các ổ cắm cho phép sử dụng các giao diện AIDL hiện có của Android trong môi trường mới này.
Để thiết lập kết nối, một điểm cuối, chẳng hạn như tải trọng pVM, tạo một đối tượng RpcServer
, đăng ký một đối tượng gốc và bắt đầu lắng nghe các kết nối mới. Khách hàng có thể kết nối với máy chủ này bằng cách sử dụng một đối tượng RpcSession
, lấy đối tượng Binder
và sử dụng nó giống như một đối tượng Binder
được sử dụng với trình điều khiển Kernel Binder.