Microdroid एक छोटा Android OS है, जो pVM में चलता है. आपको Microdroid का इस्तेमाल करने की ज़रूरत नहीं है. किसी भी ओएस के साथ एक वर्चुअल मशीन शुरू की जा सकती है. हालांकि, पीवीएम के लिए इस्तेमाल के मुख्य उदाहरण, स्टैंडअलोन ओएस के बजाय, अलग-अलग काम करने की सुविधा देते हैं. इससे ऐप्लिकेशन का कुछ हिस्सा चलाया जा सकता है. यह Android की तुलना में ज़्यादा भरोसेमंद और इंटिग्रिटी गारंटी के साथ काम करता है.
पारंपरिक ऑपरेटिंग सिस्टम में, डेटा की गोपनीयता और सुरक्षा को बेहतर बनाने के लिए ज़्यादा काम करना पड़ता है. आम तौर पर, यह काम दोहराना पड़ता है. ऐसा इसलिए होता है, क्योंकि पारंपरिक ऑपरेटिंग सिस्टम, Android के बड़े आर्किटेक्चर के साथ काम नहीं करते. उदाहरण के लिए, स्टैंडर्ड Android आर्किटेक्चर के साथ, डेवलपर को अपने ऐप्लिकेशन के कुछ हिस्से को सुरक्षित तरीके से लोड करने और pVM में चलाने का तरीका लागू करना होगा. साथ ही, पेलोड को glibc के हिसाब से बनाया जाएगा. Android ऐप्लिकेशन, Bionic का इस्तेमाल करता है. साथ ही, बातचीत के लिए vsock के ऊपर कस्टम प्रोटोकॉल की ज़रूरत होती है. साथ ही, adb का इस्तेमाल करके डीबग करना मुश्किल होता है.
Microdroid, पहले से तैयार ओएस इमेज उपलब्ध कराकर इन अंतरालों को भरता है. इस इमेज को इस तरह से डिज़ाइन किया गया है कि डेवलपर को अपने ऐप्लिकेशन के किसी हिस्से को pVM में ऑफ़लोड करने के लिए कम से कम मेहनत करनी पड़े. नेटिव कोड को बायोनिक के आधार पर बनाया जाता है और कम्यूनिकेशन, बाइंडर की मदद से होता है. इसकी मदद से, होस्ट Android से APEXes इंपोर्ट किए जा सकते हैं. साथ ही, यह Android API का सबसेट दिखाता है, जैसे कि हार्डवेयर-बैक्ड कुंजियों की मदद से क्रिप्टोग्राफ़िक ऑपरेशन के लिए कीस्टोर. कुल मिलाकर, डेवलपर को उन टूल के साथ Microsoft के लिए एक जाना-पहचाना माहौल मिलना चाहिए जिन्हें वे पूरे Android OS में इस्तेमाल कर चुके हैं.
सुविधाएं
माइक्रोडेटा, Android का एक सामान्य वर्शन है. इसमें पीवीएम के लिए खास तौर पर कुछ अतिरिक्त कॉम्पोनेंट शामिल किए जाते हैं. Microdroid इनके साथ काम करता है:
- NDK एपीआई का सबसेट (Android के libc और Bionic को लागू करने के लिए सभी एपीआई उपलब्ध कराए जाते हैं)
- डीबग करने की सुविधाएं, जैसे कि adb, logcat, tombstone, और gdb
- वेरिफ़ाइड बूट और SELinux
- APK में एम्बेड की गई शेयर की गई लाइब्रेरी के साथ-साथ, बाइनरी को लोड और एक्सीक्यूट करना
- इंप्लिसिट इंटिग्रिटी जांच की मदद से, फ़ाइलों के एक्सचेंज और बनाम बाइंडर आरपीसी से
- APEX लोड करना
माइक्रोड्रॉइड में इनका इस्तेमाल नहीं किया जा सकता:
android.\*
पैकेज में Android Java APISystemServer और Zygote
ग्राफ़िक्स/यूज़र इंटरफ़ेस (यूआई)
एचएएल
Microdroid आर्किटेक्चर
Microdroid, Cuttlefish से मिलता-जुलता है. दोनों का आर्किटेक्चर, स्टैंडर्ड Android जैसा ही है. Microdroid में, कॉम्पोनेंट डिस्क इमेज में एक साथ ग्रुप की गई ये पार्टीशन इमेज शामिल होती हैं:
bootloader
- पुष्टि करता है और कर्नेल को शुरू करता है.boot.img
- इसमें कर्नेल और init ramdisk शामिल होता है.vendor_boot.img
- इसमें वीएम के लिए खास कर्नेल मॉड्यूल शामिल हैं, जैसे कि virtio.super.img
- इसमें सिस्टम और वेंडर के लॉजिकल पार्टीशन शामिल होते हैं.vbmeta.img
- इसमें पुष्टि किए गए बूट मेटाडेटा शामिल हैं.
पार्टीशन इमेज, वर्चुअलाइज़ेशन APEX में शिप की जाती हैं और VirtualizationService
के ज़रिए एक कंपोजिट डिस्क इमेज में पैकेज की जाती हैं. मुख्य ओएस कंपोज़िट डिस्क इमेज के अलावा, VirtualizationService
इन अन्य विभाजनों को बनाने के लिए ज़िम्मेदार है:
payload
- Android के APEX और APK के बैकअप वाले पार्टीशन का एक सेटinstance
- एन्क्रिप्ट (सुरक्षित) किया गया ऐसा पार्टीशन जिसमें हर इंस्टेंस के लिए, पुष्टि किए गए बूट डेटा को सेव किया जाता है. जैसे, हर इंस्टेंस के लिए साल्ट, भरोसेमंद APEX सार्वजनिक कुंजियां, और रोलबैक काउंटर
बूट करने का क्रम
Microdroid का बूट क्रम, डिवाइस के बूट होने के बाद शुरू होता है. डिवाइस बूट के बारे में स्ट्रक्चर दस्तावेज़ के pVM फ़र्मवेयर सेक्शन में बताया गया है. पहली इमेज में, Microdroid के बूट होने के क्रम के दौरान होने वाले चरणों को दिखाया गया है:
यहां इस प्रोसेस के बारे में बताया गया है:
crosvm की मदद से बूटलोडर को मेमोरी में लोड किया जाता है और pvmfw शुरू होता है. बूटलोडर पर जाने से पहले, pvmfw दो काम करता है:
- बूटलोडर की पुष्टि करके यह पता लगाता है कि यह किसी भरोसेमंद सोर्स (Google या किसी OEM) का है या नहीं.
- यह पक्का करता है कि इंस्टेंस इमेज का इस्तेमाल करके, एक ही pVM के कई बूट में एक ही बूटलोडर का लगातार इस्तेमाल किया जाए. खास तौर पर, pVM को शुरुआत में खाली इंस्टेंस इमेज से चालू किया जाता है. pvmfw, इंस्टेंस इमेज में बूटलोडर की पहचान को सेव करता है और उसे एन्क्रिप्ट (सुरक्षित) करता है. इसलिए, अगली बार जब pVM को उसी इंस्टेंस इमेज के साथ बूट किया जाता है, तो pvmfw, इंस्टेंस इमेज से सेव की गई पहचान को डिक्रिप्ट करता है और पुष्टि करता है कि यह वही है जो पहले सेव की गई थी. अगर पहचानें अलग-अलग हैं, तो pvmfw बूट नहीं होगा.
इसके बाद, बूटलोडर Microdroid को बूट करता है.
बूटलोडर, इंस्टेंस डिस्क को ऐक्सेस करता है. pvmfw की तरह, बूटलोडर में एक इंस्टेंस डिस्क ड्राइव होती है. इसमें, पिछली बार चालू हुए बूट के दौरान इस इंस्टेंस में इस्तेमाल की गई पार्टीशन इमेज की जानकारी होती है. इसमें सार्वजनिक कुंजी भी शामिल होती है.
बूटलोडर, vbmeta और चेन किए गए पार्टीशन की पुष्टि करता है. जैसे,
boot
औरsuper
. पुष्टि होने पर, वह अगले चरण के pVM के पासवर्ड हासिल करता है. इसके बाद, Microdroid, कंट्रोल को कर्नेल को सौंप देता है.बूटलोडर ने पहले ही सुपर पार्टीशन की पुष्टि कर ली है (तीसरा चरण), इसलिए केरनल बिना किसी शर्त के सुपर पार्टीशन को माउंट कर देता है. Android के पूरी तरह से काम करने वाले वर्शन की तरह ही, सुपर पार्टीशन में कई लॉजिकल पार्टीशन होते हैं. ये dm-verity पर माउंट किए जाते हैं. इसके बाद, कंट्रोल
init
प्रोसेस को भेज दिया जाता है, जो कई नेटिव सेवाएं शुरू करती है.init.rc
स्क्रिप्ट, पूरी Android स्क्रिप्ट से मिलती-जुलती है. हालांकि, इसे Microdroid की ज़रूरतों के हिसाब से बनाया गया है.init
प्रोसेस, Microdroid मैनेजर को शुरू करती है, जो इंस्टेंस इमेज को ऐक्सेस करती है. Microdroid मैनेजर सेवा, पिछले चरण से मिली कुंजी का इस्तेमाल करके इमेज को डिक्रिप्ट करती है. साथ ही, क्लाइंट APK और उन APEX के सार्वजनिक पासकोड और रोलबैक काउंटर को पढ़ती है जिन पर इस pVM का भरोसा है.zipfuse
औरapexd
बाद में इस जानकारी का इस्तेमाल तब करते हैं, जब वे क्लाइंट APK को माउंट करते हैं और APEXes का अनुरोध करते हैं.Microdroid मैनेजर सेवा
apexd
से शुरू होगी.apexd
,/apex/<name>
डायरेक्ट्री में APEX को माउंट करता है. Android और Microdroid में APEX फ़ाइलों को माउंट करने के तरीके में सिर्फ़ एक अंतर है. Microdroid में, APEX फ़ाइलें सामान्य फ़ाइलों (/system/apex/*.apex
) से नहीं, बल्कि वर्चुअल ब्लॉक डिवाइसों (/dev/vdc1
, …) से आती हैं.zipfuse
, माइक्रोडेटा का FUSE फ़ाइल सिस्टम है.zipfuse
, क्लाइंट APK को माउंट करता है. यह फ़ाइल सिस्टम के तौर पर एक Zip फ़ाइल होती है. इसके बाद, APK फ़ाइल को APEX की तरह ही, dm-verity की मदद से pVM के ज़रिए वर्चुअल ब्लॉक डिवाइस के तौर पर पास किया जाता है. APK में एक कॉन्फ़िगरेशन फ़ाइल होती है. इसमें उन APEX की सूची होती है जिनका अनुरोध ऐप्लिकेशन डेवलपर ने इस pVM इंस्टेंस के लिए किया है.apexd
, APEX को चालू करते समय इस सूची का इस्तेमाल करता है.बूट फ़्लो, Microdroid मैनेजर सेवा पर वापस आ जाता है. इसके बाद, मैनेजर सेवा, बाइंडर आरपीसी का इस्तेमाल करके, Android के
VirtualizationService
से संपर्क करती है, ताकि वह क्रैश या बंद होने जैसे अहम इवेंट की शिकायत कर सके. साथ ही, पीवीएम बंद करने जैसे अनुरोधों को स्वीकार कर सके. मैनेजर सेवा, APK की कॉन्फ़िगरेशन फ़ाइल से मुख्य बाइनरी की जगह पढ़ती है और उसे लागू करती है.
फ़ाइल एक्सचेंज (AuthFS)
Android के कॉम्पोनेंट, इनपुट, आउटपुट, और स्टेट के लिए फ़ाइलों का इस्तेमाल करते हैं और उन्हें फ़ाइल डिस्क्रिप्टर (एआईडीएल में ParcelFileDescriptor
टाइप) के तौर पर पास करते हैं. इनका ऐक्सेस, Android कर्नेल के ज़रिए कंट्रोल किया जाता है. AuthFS, pVM की सीमाओं के बीच, एक-दूसरे पर भरोसा न करने वाले एंडपॉइंट के बीच फ़ाइलें शेयर करने के लिए, मिलती-जुलती सुविधा देता है.
बुनियादी तौर पर, AuthFS एक रिमोट फ़ाइल सिस्टम है जो fs-verity
की तरह, व्यक्तिगत ऐक्सेस ऑपरेशन पर पारदर्शी इंटिग्रिटी जांच करता है. इन जांचों की मदद से,
पीवीएम में चल रहे फ़ाइल-रीडिंग प्रोग्राम जैसे फ़्रंटएंड को यह पता चलता है कि क्या गैर-भरोसेमंद बैकएंड (आम तौर पर, Android) के साथ फ़ाइल के कॉन्टेंट के साथ छेड़छाड़ की गई है.
फ़ाइलों की अदला-बदली करने के लिए, बैकएंड (fd\_server
) को हर फ़ाइल
कॉन्फ़िगरेशन के साथ शुरू किया जाता है, जिससे यह पता चलता है कि यह इनपुट (रीड-ओनली) या आउटपुट
(रीड-राइट) के लिए है या नहीं. इनपुट के लिए, फ़्रंटएंड इस बात को लागू करता है कि कॉन्टेंट, किसी जाने-पहचाने हैश से मेल खाता हो. यह कॉन्टेंट, Merकल ट्री के ऊपर लगा, ताकि ऐक्सेस की पुष्टि की जा सके. आउटपुट के लिए, AuthFS, कॉन्टेंट का हैश ट्री अंदरूनी तौर पर बनाए रखता है. यह ट्री, लिखने के ऑपरेशन से पता चलता है. साथ ही, डेटा को फिर से पढ़ने पर, यह डेटा की अखंडता को लागू कर सकता है.
फ़िलहाल, ट्रांसपोर्ट प्रोटोकॉल Binder RPC पर आधारित है. हालांकि, आने वाले समय में परफ़ॉर्मेंस को ऑप्टिमाइज़ करने के लिए, इसमें बदलाव किया जा सकता है.
कुंजी मैनेजमेंट
pVM को एक ऐसी सीलिंग पासकोड दी जाती है जो हमेशा मौजूद रहने वाले डेटा को सुरक्षित रखने के लिए सही होती है. साथ ही, एक ऐसी पुष्टि करने वाली पासकोड दी जाती है जो ऐसे हस्ताक्षर बनाने के लिए सही होती है जिनकी पुष्टि pVM से की जा सकती है.
Binder RPC
Android के ज़्यादातर इंटरफ़ेस, AIDL में दिखाए जाते हैं. इसे Binder Linux kernel driver के ऊपर बनाया गया है. pVMs के बीच इंटरफ़ेस के साथ काम करने के लिए, Binder प्रोटोकॉल को फिर से लिखा गया है, ताकि यह pVMs के मामले में, सोकेट और vsock के साथ काम कर सके. सॉकेट पर काम करने की सुविधा की मदद से, Android के मौजूदा AIDL इंटरफ़ेस का इस्तेमाल इस नए एनवायरमेंट में किया जा सकता है.
कनेक्शन सेट अप करने के लिए, pVM पेलोड जैसा कोई एक एंडपॉइंट, RpcServer
ऑब्जेक्ट बनाता है, रूट ऑब्जेक्ट को रजिस्टर करता है, और नए कनेक्शन के लिए सुनना शुरू करता है. क्लाइंट, RpcSession
ऑब्जेक्ट का इस्तेमाल करके इस सर्वर से कनेक्ट कर सकते हैं,
Binder
ऑब्जेक्ट पा सकते हैं, और इसका इस्तेमाल ठीक उसी तरह कर सकते हैं जिस तरह Binder
ऑब्जेक्ट का इस्तेमाल, kernel Binder ड्राइवर के साथ किया जाता है.