Microdroid הוא מערכת הפעלה מיני-Android שפועלת ב-pVM. לא חייבים להשתמש ב-Microdroid, אפשר להפעיל מכונה וירטואלית עם כל מערכת הפעלה. עם זאת, תרחישי השימוש העיקריים ב-pVM הם לא הפעלת מערכת הפעלה עצמאית, אלא הצעת סביבת ביצוע מבודדת להפעלת חלק מאפליקציה עם הבטחות חזקות יותר של סודיות ושלמות מאלה שאפשר לקבל ב-Android.
במערכות הפעלה מסורתיות, כדי לספק סודיות ויושרה חזקות נדרשת כמות לא מבוטלת של עבודה (שלעתים קרובות משוכפלת), כי מערכות הפעלה מסורתיות לא מתאימות לארכיטקטורה הכוללת של Android. לדוגמה, בארכיטקטורת Android רגילה, מפתחים צריכים להטמיע אמצעי לטעינה ולהפעלה מאובטחת של חלק מהאפליקציה שלהם ב-pVM, והמטען הייעודי (payload) בנוי על glibc. אפליקציית Android משתמשת ב-Bionic, התקשורת דורשת פרוטוקול מותאם אישית דרך vsock, והניפוי באגים באמצעות adb הוא מורכב.
Microdroid ממלא את הפערים האלה באמצעות תמונת מערכת הפעלה מוכנה מראש, שנועדה לדרוש מהמפתחים את המאמץ המינימלי כדי להעביר חלק מהאפליקציה שלהם ל-pVM. הקוד המקורי בנוי על Bionic, התקשורת מתבצעת באמצעות Binder, והוא מאפשר ייבוא של קובצי APEX ממערכת Android המארחת וחושף קבוצת משנה של Android API, כמו keystore לפעולות הצפנה עם מפתחות שמגובים בחומרה. באופן כללי, מפתחים יגלו ש-Microdroid היא סביבה מוכרת עם הכלים שהם רגילים אליהם במערכת ההפעלה המלאה של Android.
תכונות
Microdroid היא גרסה מצומצמת של Android עם כמה רכיבים נוספים שספציפיים ל-pVM. Microdroid תומך ב:
- קבוצת משנה של ממשקי NDK API (כל ממשקי ה-API להטמעה של libc ו-Bionic ב-Android מסופקים)
- תכונות לניפוי באגים, כמו adb, logcat, tombstone ו-gdb
- אתחול מאומת ו-SELinux
- טעינה והפעלה של קובץ בינארי, יחד עם ספריות משותפות שמוטמעות ב-APK
- Binder RPC over vsock והחלפת קבצים עם בדיקות תקינות משתמעות
- טעינה של קובצי APEX
Microdroid לא תומך ב:
ממשקי Android Java API בחבילות
android.\*
SystemServer ו-Zygote
גרפיקה/ממשק משתמש
HALs
ארכיטקטורת Microdroid
Microdroid דומה ל-Cuttlefish בכך שלשניהם יש ארכיטקטורה שדומה ל-Android רגיל. Microdroid מורכב מתמונות המחיצות הבאות שמקובצות יחד בתמונת דיסק מורכבת:
-
bootloader
– מאמת ומפעיל את הליבה. -
boot.img
– מכיל את הליבה ואת init ramdisk. -
vendor_boot.img
– מכיל מודולים של ליבת מערכת ספציפיים למכונה וירטואלית, כמו virtio. -
super.img
– מורכב ממחיצות לוגיות של המערכת והספק. -
vbmeta.img
– מכיל מטא-נתונים של אתחול מאומת.
תמונות המחיצות נשלחות ב-Virtualization APEX וארוזות בתמונת דיסק מורכבת על ידי VirtualizationService
. בנוסף לתמונת הדיסק המורכבת של מערכת ההפעלה הראשית, VirtualizationService
אחראי ליצירת המחיצות האחרות האלה:
-
payload
– קבוצה של מחיצות שמגובות על ידי קובצי APEX ו-APK של Android -
instance
– מחיצה מוצפנת לשמירת נתוני אתחול מאומתים לכל מופע, כמו מלח לכל מופע, מפתחות ציבוריים מהימנים של APEX ומונים של חזרה לגרסה קודמת
רצף האתחול
רצף ההפעלה של Microdroid מתרחש אחרי הפעלת המכשיר. הפעלה של מכשיר מוסברת בקטע pVM Firmware במסמך Architecture. באיור 1 מוצגים השלבים שמתרחשים במהלך רצף האתחול של Microdroid:
הסבר על השלבים:
תוכנת האתחול נטענת לזיכרון על ידי crosvm ו-pvmfw מתחיל לפעול. לפני שמגיעים לטוען האתחול, pvmfw מבצע שתי משימות:
- מאמת את תוכנת האתחול כדי לבדוק אם היא ממקור מהימן (Google או יצרן ציוד מקורי).
- השימוש בתמונת המופע מבטיח שייעשה שימוש באותו bootloader באופן עקבי בכמה אתחולים של אותו pVM. באופן ספציפי, מכונת ה-pVM מופעלת בהתחלה עם תמונה ריקה של מופע. pvmfw מאחסן את הזהות של טוען האתחול בתמונה של המופע ומצפין אותה. לכן, בפעם הבאה שמפעילים את ה-pVM עם אותה תמונת מופע, pvmfw מפענח את הזהות שנשמרה מתמונת המופע ומוודא שהיא זהה לזהות שנשמרה קודם. אם הזהויות שונות, pvmfw מסרב לאתחל.
תוכנת האתחול מפעילה את Microdroid.
תוכנת האתחול ניגשת לדיסק של המכונה. בדומה ל-pvmfw, לטוען האתחול יש כונן דיסק של מופע עם מידע על תמונות של מחיצות שנעשה בהן שימוש במופע הזה במהלך אתחולים קודמים, כולל המפתח הציבורי.
תוכנת האתחול מאמתת את vbmeta ואת המחיצות המקושרות, כמו
boot
ו-super
, ואם האימות מצליח, היא גוזרת את הסודות של pVM בשלב הבא. לאחר מכן, Microdroid מעביר את השליטה לליבת המערכת.מכיוון שמחיצת הסופר כבר אומתה על ידי טוען האתחול (שלב 3), הליבה מטמיעה את מחיצת הסופר ללא תנאי. בדומה ל-Android המלא, מחיצת הסופר מורכבת ממחיצות לוגיות מרובות שמוצמדות באמצעות dm-verity. השליטה מועברת לתהליך
init
, שמתחיל שירותים מקומיים שונים. הסקריפטinit.rc
דומה לסקריפט של Android מלא, אבל הוא מותאם לצרכים של Microdroid.תהליך
init
מתחיל את מנהל Microdroid, שמקבל גישה לתמונת המופע. שירות הניהול של Microdroid מפענח את התמונה באמצעות המפתח שהועבר מהשלב הקודם, וקורא את המפתחות הציבוריים ואת מוני הביטול של קובצי ה-APK וה-APEX של הלקוח שה-pVM הזה נותן בהם אמון. המידע הזה משמש בהמשך אתzipfuse
ו-apexd
כשהם מטמיעים את ה-APK של הלקוח ואת קובצי ה-APEX המבוקשים, בהתאמה.שירות הניהול של Microdroid מתחיל ב-
apexd
.
apexd
mounts the APEXes at/apex/<name>
directories. ההבדל היחיד בין האופן שבו מערכות Android ו-Microdroid מטמיעות חבילות APEX הוא שב-Microdroid, קובצי ה-APEX מגיעים ממכשירי בלוק וירטואליים (/dev/vdc1
, …), ולא מקבצים רגילים (/system/apex/*.apex
).
zipfuse
היא מערכת הקבצים FUSE של Microdroid. zipfuse
מתקין את קובץ ה-APK של הלקוח, שהוא בעצם קובץ Zip כמערכת קבצים. מתחת לזה, קובץ ה-APK מועבר כמכשיר בלוק וירטואלי על ידי ה-pVM עם dm-verity, כמו APEX. קובץ ה-APK מכיל קובץ הגדרה עם רשימה של חבילות APEX שמפתח האפליקציה ביקש עבור מופע ה-pVM הזה. הרשימה נמצאת בשימוש ב-apexd
כשמפעילים קבצים מסוג APEX.תהליך האתחול חוזר לשירות הניהול של Microdroid. לאחר מכן, שירות הניהול מתקשר עם
VirtualizationService
של Android באמצעות Binder RPC כדי לדווח על אירועים חשובים כמו קריסה או כיבוי, ולקבל בקשות כמו סיום של pVM. שירות הניהול קורא את המיקום של הקובץ הבינארי הראשי מקובץ ההגדרות של ה-APK ומבצע אותו.
החלפת קבצים (AuthFS)
בדרך כלל רכיבי Android משתמשים בקבצים לקלט, לפלט ולמצב, ומעבירים אותם כמתארי קבצים (ParcelFileDescriptor
סוג ב-AIDL) עם גישה שמבוקרת על ידי ליבת Android. AuthFS מאפשרת פונקציונליות דומה להחלפת קבצים בין נקודות קצה שלא סומכות זו על זו, מעבר לגבולות של מכונות וירטואליות פרטיות.
בבסיס, AuthFS היא מערכת קבצים מרוחקת עם בדיקות שקיפות של שלמות בפעולות גישה פרטניות, בדומה ל-fs-verity
. הבדיקות מאפשרות לחלק הקדמי של המערכת, כמו תוכנה לקריאת קבצים שפועלת ב-pVM, לזהות אם החלק האחורי הלא מהימן של המערכת, בדרך כלל Android, שינה את תוכן הקובץ.
כדי להחליף קבצים, ה-backend (fd\_server
) מופעל עם הגדרה לכל קובץ שמציינת אם הוא מיועד לקלט (קריאה בלבד) או לפלט (קריאה וכתיבה). לגבי קלט, ה-frontend מוודא שהתוכן תואם לגיבוב ידוע, בנוסף לעץ מרקל לאימות בזמן הגישה. בפלט, AuthFS שומר באופן פנימי עץ גיבוב של התוכן כפי שנצפה מפעולות כתיבה, ויכול לאכוף את השלמות כשקוראים את הנתונים בחזרה.
ההעברה הבסיסית מבוססת כרגע על Binder RPC, אבל יכול להיות שהיא תשתנה בעתיד כדי לשפר את הביצועים.
ניהול מפתחות
מכונות וירטואליות פרטיות מסופקות עם מפתח חתימה יציב שמתאים להגנה על נתונים קבועים, ועם מפתח אימות שמתאים ליצירת חתימות שאפשר לאמת שהן נוצרו על ידי המכונה הווירטואלית הפרטית.
Binder RPC
רוב הממשקים של Android מבוססים על AIDL, שנבנה על בסיס הדרייבר של ליבת Binder Linux. כדי לתמוך בממשקי משתמש בין מכונות וירטואליות פרטיות, פרוטוקול Binder נכתב מחדש כדי לפעול על פני שקעים, vsock במקרה של מכונות וירטואליות פרטיות. הפעולה דרך שקעים מאפשרת להשתמש בממשקי AIDL הקיימים של Android בסביבה החדשה הזו.
כדי להגדיר את החיבור, נקודת קצה אחת, כמו מטען ייעודי (payload) של pVM, יוצרת אובייקט RpcServer
, רושמת אובייקט בסיס ומתחילה להאזין לחיבורים חדשים. לקוחות יכולים להתחבר לשרת הזה באמצעות אובייקט RpcSession
, לקבל את אובייקט Binder
ולהשתמש בו בדיוק כמו באובייקט Binder
שמשמש עם מנהל ההתקן של Binder בקרנל.