Microdroid הוא מערכת הפעלה מיני-Android שפועלת ב-pVM. לא חייבים להשתמש ב-Microdroid, אפשר להפעיל מכונה וירטואלית עם כל מערכת הפעלה. עם זאת, תרחישי השימוש העיקריים במכונות pVM הם לא הפעלת מערכת הפעלה עצמאית, אלא הצעת סביבת ביצוע מבודדת להפעלת חלק מהאפליקציה עם הבטחות חזקות יותר של סודיות ושלמות מאלה ש-Android יכולה לספק.
במערכות הפעלה מסורתיות, כדי לספק סודיות ויושרה חזקות נדרשת כמות לא מבוטלת של עבודה (שלעתים קרובות משוכפלת), כי מערכות הפעלה מסורתיות לא מתאימות לארכיטקטורת Android הכוללת. לדוגמה, בארכיטקטורת Android רגילה, מפתחים צריכים להטמיע אמצעי לטעינה ולהפעלה מאובטחות של חלק מהאפליקציה שלהם ב-pVM, והמטען הייעודי (payload) בנוי על glibc. אפליקציית Android משתמשת ב-Bionic, התקשורת דורשת פרוטוקול מותאם אישית דרך vsock, והניפוי באגים באמצעות adb הוא מורכב.
Microdroid ממלא את הפערים האלה באמצעות קובץ אימג' של מערכת ההפעלה מוכן מראש, שנועד לדרוש מהמפתחים את המאמץ המינימלי כדי להפחית עומס של חלק מהאפליקציה שלהם ל-pVM. קוד Native בנוי על 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 and exchange of files with implicit integrity checks
- טעינה של קובצי 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. באופן ספציפי, המכונה הווירטואלית מופעלת בהתחלה עם תמונה ריקה של מכונה. 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.
apexdmounts 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. הבדיקות מאפשרות לחלק הקצה (frontend), כמו תוכנה לקריאת קבצים שפועלת ב-pVM, לזהות אם חלק העורף (backend) הלא מהימן, בדרך כלל Android, שינה את תוכן הקובץ.
כדי להחליף קבצים, ה-backend (fd\_server) מופעל עם הגדרה לכל קובץ שמציינת אם הוא מיועד לקלט (קריאה בלבד) או לפלט (קריאה וכתיבה). לגבי קלט, ה-frontend מוודא שהתוכן תואם לגיבוב ידוע, בנוסף לעץ מרקל לאימות גישה. בפלט, מערכת AuthFS שומרת באופן פנימי עץ גיבוב של התוכן כפי שנצפה מפעולות כתיבה, ויכולה לאכוף את השלמות כשקוראים את הנתונים בחזרה.
התעבורה הבסיסית מבוססת כרגע על Binder RPC, אבל יכול להיות שהיא תשתנה בעתיד כדי לשפר את הביצועים.
ניהול מפתחות
מכונות וירטואליות פרטיות מסופקות עם מפתח חתימה יציב שמתאים להגנה על נתונים קבועים, ועם מפתח אימות שמתאים ליצירת חתימות שאפשר לאמת שהן נוצרו על ידי המכונה הווירטואלית הפרטית.
Binder RPC
רוב הממשקים של Android מבוססים על AIDL, שנבנה על בסיס הדרייבר של ליבת Binder Linux. כדי לתמוך בממשקי משתמש בין מכונות pVM, פרוטוקול Binder נכתב מחדש כדי לפעול על גבי sockets, vsock במקרה של מכונות pVM. הפעולה דרך שקעים מאפשרת להשתמש בממשקי AIDL הקיימים של Android בסביבה החדשה הזו.
כדי להגדיר את החיבור, נקודת קצה אחת, כמו מטען ייעודי (payload) של pVM, יוצרת אובייקט RpcServer, רושמת אובייקט בסיס ומתחילה להאזין לחיבורים חדשים. לקוחות יכולים להתחבר לשרת הזה באמצעות אובייקט RpcSession, לקבל את אובייקט Binder ולהשתמש בו בדיוק כמו באובייקט Binder שמשמש עם מנהל ההתקן של Binder בקרנל.