Microdroid היא מערכת הפעלה מיני-Android שפועלת ב-pVM. אתם לא חייבים להשתמש ב-Microdroid, אפשר להפעיל מכונה וירטואלית עם כל מערכת הפעלה. עם זאת, התרחישים העיקריים לדוגמה לשימוש ב-pVMs לא כוללים הפעלה של מערכת הפעלה עצמאית, אלא סביבה מבודדת להרצה של חלק מאפליקציה עם ערבויות חזקות יותר של סודיות ושלמות מאשר Android יכול לספק.
במערכות הפעלה רגילות, כדי לשמור על סודיות ויושרה נדרשת כמות גדולה של עבודה (לעיתים קרובות כפול) כי מערכות הפעלה רגילות לא מתאימות לארכיטקטורה המקיפה של Android. לדוגמה, בארכיטקטורה הרגילה של Android, המפתחים צריכים להטמיע דרך לטעון ולבצע באופן מאובטח חלק מהאפליקציה ב-pVM, ועומס התועלת נבנה מול glibc. באפליקציית Android נעשה שימוש ב-Bionic, התקשורת דורשת פרוטוקול מותאם אישית דרך vsock ותיקון באגים באמצעות adb הוא מאתגר.
Microdroid ממלא את הפערים האלה על ידי מתן קובץ אימג' של מערכת הפעלה מוכנה לשימוש, שנועד לדרוש מהמפתחים את המאמץ המינימלי כדי להעביר חלק מהאפליקציה שלהם ל-pVM. הקוד המקומי נבנה על Bionic, התקשורת מתבצעת דרך Binder, הוא מאפשר לייבא קובצי APEX מ-Android המארח ומציג קבוצת משנה של Android API, כמו מאגר מפתחות לפעולות קריפטוגרפיות עם מפתחות שמגובים בחומרה. באופן כללי, המפתחים אמורים למצוא ב-Microdroid סביבה מוכרת עם הכלים שהם התרגלו אליהם ב-Android OS המלא.
תכונות
Microdroid היא גרסה פשוטה של Android עם כמה רכיבים נוספים שספציפיים ל-pVM. Microdroid תומך:
- קבוצת משנה של ממשקי API של NDK (כל ממשקי ה-API להטמעה של Android ב-libc וב-Bionic)
- תכונות לניפוי באגים, כמו adb, Logcat, tombstone ו-gdb.
- הפעלה מאומתת ו-SELinux
- טעינת קובץ בינארי והרצה שלו, יחד עם ספריות משותפות שמוטמעות ב-APK
- Binder RPC ב-Pvock והחלפה של קבצים עם בדיקות תקינות מרומזות
- מתבצעת טעינה של APEX
Microdroid לא תומך באפשרויות הבאות:
ממשקי API של Java ל-Android בחבילות
android.\*
SystemServer ו-Zygote
גרפיקה/ממשק משתמש
HAL
ארכיטקטורת מיקרו-דרואיד
Microdroid דומה ל-Cuttlefish בכך שלשניהם יש ארכיטקטורה שדומה ל-Android רגיל. Microdroid מורכב מתמונות המחיצות הבאות שמקובצות יחד בתמונת דיסק מורכבת:
bootloader
– אימות והפעלה של הליבה.boot.img
– מכיל את הליבה ואת init ramdisk.vendor_boot.img
– מכיל מודולים של ליבה ספציפיים למכונות וירטואליות, כמו virtio.super.img
– כולל מחיצות לוגיות של המערכת והספק.vbmeta.img
– מכיל מטא-נתונים של אתחול מאומת.
קובצי האימג' של המחיצות נשלחים ב-Virtualization APEX ומארזים בתמונה מורכבת של דיסק על ידי VirtualizationService
. בנוסף לתמונת הדיסק המשולבת הראשית של מערכת ההפעלה, VirtualizationService
אחראי ליצירת המחיצות הבאות:
payload
- קבוצת מחיצות שמגובות על ידי חבילות APK ו-APEX של Androidinstance
– מחיצה מוצפנת לנתוני אתחול מאומתים שנשמרים לכל מכונה, כמו מלח לכל מכונה, מפתחות ציבוריים מהימנים של APEX ומספרי ספירה לביטול משיכה לאחור
רצף האתחול
רצף האתחול של Microdroid מתרחש אחרי הפעלת המכשיר. הפעלת המכשיר מוסבר בקטע 'קושחת pVM' במסמך 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
מחבר את ה-APEXes לספריות/apex/<name>
. ההבדל היחיד בין האופן שבו קבצים מסוג APEX מותקנים ב-Android וב-Microdroid הוא שב-Microdroid, קבצי ה-APEX מגיעים ממכשירי בלוק וירטואליים (/dev/vdc1
, …), ולא מקובצים רגילים (/system/apex/*.apex
).zipfuse
היא מערכת הקבצים של Microdroid.zipfuse
טוען את ה-APK של הלקוח, שהוא בעצם קובץ ZIP בתור מערכת קבצים. מתחת, קובץ ה-APK מועבר כמכשיר בלוק וירטואלי על ידי ה-pVM עם dm-verity, כמו ב-APEX. חבילת ה-APK מכילה קובץ תצורה עם רשימת APEX שמפתח האפליקציה ביקש למופע ה-pVM הזה. הרשימה משמשת אתapexd
כשמפעילים חשבונות APEX.תהליך האתחול חוזר לשירות הניהול של Microdroid. לאחר מכן, שירות הניהול מתקשר עם
VirtualizationService
של Android באמצעות Binder RPC כדי לדווח על אירועים חשובים כמו קריסה או כיבוי, ולקבל בקשות כמו סיום של ה-pVM. שירות הניהול קורא את המיקום של הקובץ הבינארי הראשי מקובץ התצורה של ה-APK ומריץ אותו.
החלפת קבצים (AuthFS)
רכיבים של Android משתמשים בדרך כלל בקבצים להזנת קלט, לפלט ולמצב, ומעבירים אותם כמזהים של קבצים (ParcelFileDescriptor
type ב-AIDL) עם גישה שנשלטת על ידי הליבה של Android. AuthFS מאפשרת פונקציונליות דומה להחלפת קבצים בין נקודות קצה מהימנות הדדיות בין גבולות pVM.
ביסודו, AuthFS היא מערכת קבצים מרוחקת עם בדיקות תקינות שקופות של פעולות גישה ספציפיות, בדומה ל-fs-verity
. הבדיקות מאפשרות לקצה הקדמי, כמו תוכנית לקריאת קבצים שפועלת ב-pVM, לזהות אם הקצה העורפי הלא מהימן, בדרך כלל Android, שינה את תוכן הקובץ.
כדי להחליף קבצים, הקצה העורפי (fd\_server
) מתחיל עם הגדרות אישיות לכל קובץ, שמציינת אם הוא מיועד לקלט (לקריאה בלבד) או לפלט (קריאה-כתיבה). לגבי קלט, ממשק הקצה אוכף שהתוכן תואם ל-hash ידוע, מעל עץ Merkle לאימות בזמן הגישה. לצורך פלט, AuthFS שומרת באופן פנימי את עץ הגיבוב (hash) של התוכן של התוכן כפי שנמדד מפעולות כתיבה, והיא יכולה לאכוף את התקינות בזמן הקריאה החוזרת של הנתונים.
התעבורה הבסיסית מבוססת כרגע על Binder RPC, אבל יכול להיות שהיא תשתנה בעתיד כדי לבצע אופטימיזציה של הביצועים.
ניהול מפתחות
למכונות הווירטואליות יש מפתח סגירה יציב שמתאים להגנה על נתונים קבועים, ומפתח אימות שמתאים ליצירת חתימות שמופקות על ידי ה-pVM בצורה מאומתת.
RPC ב-Binder
רוב ממשקי Android מבוססים על AIDL, שנבנה על גבי מנהל ההתקן של ליבה של Binder Linux. כדי לתמוך בממשקים בין מכונות pVM, פרוטוקול Binder נכתב מחדש כדי שיעבוד עם sockets, למשל vsock במקרים של מכונות pVM. הפעולה דרך שקעים מאפשרת להשתמש בממשקי ה-AIDL הקיימים של Android בסביבה החדשה הזו.
כדי להגדיר את החיבור, נקודת קצה אחת, כמו מטען ייעודי (payload) של pVM, יוצרת אובייקט RpcServer
, רושמת אובייקט ברמה הבסיסית (root) ומתחילה להאזין לחיבורים חדשים. לקוחות יכולים להתחבר לשרת הזה באמצעות אובייקט RpcSession
, לקבל את האובייקט Binder
ולהשתמש בו בדיוק כמו שמשתמשים באובייקט Binder
עם מנהל ה-Binder של הליבה.