摘 要:針對(duì)主流虛擬化協(xié)議對(duì)Android系統(tǒng)支持不足和ARM平臺(tái)廠商對(duì)Linux系統(tǒng)的顯示驅(qū)動(dòng)支持有限的問(wèn)題,提出一種將Android系統(tǒng)與Linux系統(tǒng)相整合的解決方案,以Android系統(tǒng)的驅(qū)動(dòng)為基礎(chǔ)構(gòu)建Linux系統(tǒng)應(yīng)用,通過(guò)中間層技術(shù)將Android系統(tǒng)的Bionic顯示驅(qū)動(dòng)接口轉(zhuǎn)換成Linux系統(tǒng)下Glibc應(yīng)用能夠用的功能接口,具體闡述2D圖形顯示和高清視頻播放的實(shí)現(xiàn)。該方案利用了Android系統(tǒng)與Linux系統(tǒng)的優(yōu)勢(shì),揚(yáng)長(zhǎng)避短,使Android平臺(tái)的設(shè)備作為高性能云終端成為可能,擴(kuò)展云終端的選型范圍,降低云終端的成本。
關(guān)鍵詞:Android; 云終端; Linux
中圖分類號(hào):TP316
文獻(xiàn)標(biāo)識(shí)碼: B
云桌面構(gòu)建于企業(yè)級(jí)虛擬化平臺(tái)之上,共享服務(wù)器CPU、內(nèi)存、網(wǎng)絡(luò)連接和存儲(chǔ)器等底層物理硬件資源,讓多個(gè)用戶桌面以虛擬機(jī)的形式獨(dú)立運(yùn)行,為每個(gè)用戶提供一套獨(dú)立的桌面環(huán)境[1-2]?,F(xiàn)有云桌面的前端設(shè)備云終端主要以X86+Windows和ARM+Linux兩種平臺(tái)為主,長(zhǎng)期以來(lái)X86+Windows占據(jù)著云終端的主導(dǎo)地位。但是近年來(lái),隨著多核ARM平臺(tái)的迅速發(fā)展,通過(guò)對(duì)系統(tǒng)軟件的深度優(yōu)化,ARM+Linux平臺(tái)的云終端已經(jīng)可以提供完美的遠(yuǎn)程桌面體驗(yàn),支持高清的視頻重定向,而且ARM+Linux平臺(tái)的云終端成本遠(yuǎn)低于X86+Windows平臺(tái)。
2014年,Android設(shè)備的銷售量占到全球份額81%的絕對(duì)優(yōu)勢(shì)[3],但目前主流的虛擬化協(xié)議如Citrix的ICA[4]、VMware的PCOIP[5]和Red Hat的SPICE[6],對(duì)Android系統(tǒng)的支持還停留在基礎(chǔ)辦公上,對(duì)于協(xié)議的擴(kuò)展如MMR或者USB設(shè)備重定向的支持幾乎沒(méi)有,同時(shí)Android系統(tǒng)主要針對(duì)觸屏操作,對(duì)鼠標(biāo)操作的支持較弱,導(dǎo)致其虛擬化應(yīng)用體驗(yàn)較差。但這些虛擬化協(xié)議在ARM+Linux上的實(shí)現(xiàn)以及用戶體驗(yàn)都達(dá)到一個(gè)較好的水平。
由于受限于云終端的市場(chǎng)規(guī)模,ARM廠商對(duì)Linux系統(tǒng)的驅(qū)動(dòng)支持有限,只提供Android系統(tǒng)下的驅(qū)動(dòng),且都是閉源的二進(jìn)制動(dòng)態(tài)庫(kù),說(shuō)服廠商針對(duì)Linux系統(tǒng)重新編譯提供一套動(dòng)態(tài)庫(kù)幾乎是不現(xiàn)實(shí)的,如國(guó)內(nèi)主流的ARM廠商海思和瑞芯微都已不再提供針對(duì)Linux的顯示驅(qū)動(dòng),這導(dǎo)致云終端的ARM+Linux硬件平臺(tái)選型受到極大的限制。
綜上,在ARM+Linux上虛擬化體驗(yàn)較好,但缺乏原生廠商的支持,而在ARM+Android上虛擬化體驗(yàn)較差,但其驅(qū)動(dòng)較為完整。由于多數(shù)廠商不提供Linux系統(tǒng)驅(qū)動(dòng)導(dǎo)致ARM+Linux云終端平臺(tái)選型非常困難,若能夠基于Android驅(qū)動(dòng)構(gòu)建Linux系統(tǒng)及其應(yīng)用,那就能夠?qū)ndroid設(shè)備納入云終端的選型范圍。
1 Android系統(tǒng)與Linux系統(tǒng)
Android系統(tǒng)與Linux系統(tǒng)的系統(tǒng)架構(gòu)如圖1所示。從系統(tǒng)架構(gòu)看,Android本質(zhì)上就是一個(gè)Linux變種,二者使用了相同的內(nèi)核,但在基礎(chǔ)庫(kù)上有較大區(qū)別,Linux是基于Glibc,而Android則重寫了Glibc,衍生出了Bionic[7]。但由于Bionic與Glibc不完全兼容,加上鏈接器的不同,導(dǎo)致在Android上編譯的動(dòng)態(tài)庫(kù)是無(wú)法直接在Linux系統(tǒng)中使用。
ARM廠商提供的Android的驅(qū)動(dòng)位于HAL(硬件抽象層)[8],而HAL依賴于基礎(chǔ)庫(kù)Bionic,若希望Linux系統(tǒng)的應(yīng)用能夠調(diào)用Android系統(tǒng)的HAL驅(qū)動(dòng),則需要解決基礎(chǔ)庫(kù)(Bionic與Glibc)的兼容性問(wèn)題。因此在系統(tǒng)融合方案中在Bionic與Glibc之間構(gòu)建中間層LibBridge,讓Linux系統(tǒng)的Glibc環(huán)境下的應(yīng)用通過(guò)LibBridge中間層能夠調(diào)用Android系統(tǒng)的基于Bionic庫(kù)的驅(qū)動(dòng)。在具體實(shí)現(xiàn)中,該方案基于瑞芯微RK3188平臺(tái),實(shí)現(xiàn)了2D圖形顯示和視頻硬解碼功能。
2 云終端系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
整合系統(tǒng)的框架如圖2所示。
系統(tǒng)盡可能地保留了Android原始的HAL及相關(guān)的服務(wù),在進(jìn)入Android系統(tǒng)后,通過(guò)chroot的方式進(jìn)入Linux系統(tǒng)并啟動(dòng)相關(guān)的服務(wù)和應(yīng)用程序主界面。系統(tǒng)啟動(dòng)流程如圖3所示。
在Linux系統(tǒng)中調(diào)用Android的顯示驅(qū)動(dòng)及多媒體驅(qū)動(dòng),實(shí)現(xiàn)了支持1920×1080分辨率的2D圖形顯示和1080P高清視頻的流暢播放,達(dá)到了高性能云終端的基準(zhǔn),在該系統(tǒng)中的Citrix虛擬化體驗(yàn)并能夠達(dá)到Citrix的Ready認(rèn)證水平[9]。下面具體闡述整合系統(tǒng)中中間層LibBridge、2D圖形顯示和高清視頻硬解碼的實(shí)現(xiàn)。
2.1 中間層LibBridge的設(shè)計(jì)與實(shí)現(xiàn)
中間層LibBridge的主要作用是把Android系統(tǒng)中基于Bionic編譯的驅(qū)動(dòng)庫(kù)中的符號(hào)替換成與Linux系統(tǒng)中Glibc相兼容版本的符號(hào)。它封裝了基于Bionic編譯的庫(kù),當(dāng)Linux的應(yīng)用需要調(diào)用到Bionic庫(kù)時(shí),會(huì)首先加載LibBridge中間層,LibBridge中間層就會(huì)使用其內(nèi)部實(shí)現(xiàn)的一個(gè)基于Android鏈接器去加載真正需要加載的庫(kù)。
它的具體原理為:首先封裝所有Android驅(qū)動(dòng)庫(kù)的接口,然后使用鏈接器的機(jī)制動(dòng)態(tài)加載Android驅(qū)動(dòng)庫(kù),最后根據(jù)實(shí)現(xiàn)調(diào)用來(lái)重定向接口。其中鏈接器是一個(gè)基于Android系統(tǒng)中鏈接器修改而成的版本,但其中加入了對(duì)Glibc符號(hào)的特殊處理。其原理如圖4所示。
可以看出,包含字符映射的LibBridge的hooks哈希表中包含兩部分內(nèi)容:一部分是hooks數(shù)組定義的映射,其字符地址指向LibBridge中實(shí)現(xiàn)的封裝函數(shù),由封裝函數(shù)來(lái)處理兼容性問(wèn)題,然后調(diào)用Glibc對(duì)應(yīng)版本。 另一部分是Bionic的字符到libc.so.6和 librt.so對(duì)應(yīng)版本的直接映射。前者是靜態(tài)定義的,后者則是運(yùn)行時(shí)生成的。其中處理字符重定位的關(guān)鍵函數(shù)reloc_library實(shí)現(xiàn)為:
static int reloc_library(soinfo *si, Elf_Rel *rel, unsigned count)
{
Elf_Sym *symtab = si->symtab;
const char *strtab = si->strtab;
…
for(idx = 0; idx < count; ++idx)
{
…
if (sym != 0)
{
sym_name = (char *)(strtab + symtab[sym].st_name);
INFO(\"HYBRIS: '%s' checking hooks for sym '%s'\\n\", si->name,sym_name);
sym_addr = get_hooked_symbol(sym_name);
if (sym_addr != NULL)
{
INFO(\"HYBRIS: '%s' hooked symbol%s to%x\\n\", si->name,sym_name, sym_addr);
}
else
{
s = _do_lookup(si, sym_name, base);
}
…
}
}
}
其中獲取hooks哈希表具體字符的get_hooked_symbol函數(shù)實(shí)現(xiàn)為:
void *get_hooked_symbol(char *sym)
{
struct _hook *ptr = hooks[0];
static int counter = -1;
while (ptr->name != NULL)
{
if (strcmp(sym, ptr->name) == 0)
{
return ptr->func;
}
ptr++;
}
…
}
基于Linux系統(tǒng)的Glibc的應(yīng)用調(diào)用LibBridge的工作流主要如下:
(1)應(yīng)用程序啟動(dòng);
(2) 若是動(dòng)態(tài)鏈接,且應(yīng)用程序中調(diào)用了Android 庫(kù)的接口,則使用LD加載LibBridge庫(kù);
(3)通過(guò)調(diào)用LibBridge庫(kù)的接口來(lái)調(diào)用真正的Android庫(kù)接口。
通過(guò)中間層LibBridge,Linux系統(tǒng)的基于Glibc編譯的應(yīng)用就能夠間接調(diào)用Android系統(tǒng)的HAL驅(qū)動(dòng)庫(kù)了,基于此就能夠在Linux系統(tǒng)中調(diào)用Android的GPU驅(qū)動(dòng)來(lái)實(shí)現(xiàn)2D圖形顯示。
2.2 2D圖形顯示的實(shí)現(xiàn)
目前Linux采用的顯示架構(gòu)都是Xorg,虛擬化廠商提供的客戶端也都是基于X的。Linux系統(tǒng)的顯示架構(gòu)如圖5所示。
從上述架構(gòu)可以看出,在Linux系統(tǒng)中使用了Android自帶的顯示服務(wù),能夠最大限度的利用Android原生驅(qū)動(dòng)效率,同時(shí)也具備了高可移植性,可以屏蔽Linux系統(tǒng)對(duì)Android底層顯示驅(qū)動(dòng)的依賴。
在LibBridge中包含了2D圖形顯示的EGL平臺(tái)接口,它是Android平臺(tái)的libEGL庫(kù)的封裝實(shí)現(xiàn),其內(nèi)部會(huì)加載真正的libEGL庫(kù),在hook一些函數(shù)的同時(shí)也會(huì)增加一些擴(kuò)展函數(shù),它主要包含兩種后端的實(shí)現(xiàn):fbdev和wayland,其結(jié)構(gòu)如圖6所示。
2.3 高清視頻硬解碼的實(shí)現(xiàn)
目前Linux上采用較多的多媒體框架是Gstreamer,基于可插拔插件的Gstreamer多媒體應(yīng)用框架應(yīng)用靈活,擴(kuò)展性強(qiáng),能夠快速裝卸功能模塊,極大地簡(jiǎn)化多媒體應(yīng)用的開(kāi)發(fā)過(guò)程[10],Citrix的多媒體重定向也都是Gstreamer框架,如圖7所示。
Gstreamer通過(guò)LibBridge調(diào)用Android原生的MediaCodec[11],能夠有效的利用Android的硬解碼,屏蔽Linux系統(tǒng)對(duì)硬解底層驅(qū)動(dòng)的依賴。在針對(duì)RK3188的Android版本中已提供OMX硬解的支持,因此只需要在Wayland中支持Gstreaner的xvimagesink視頻輸出,即需要在Wayland中支持X視頻擴(kuò)展[12]。X視頻擴(kuò)展是X Window系統(tǒng)的視頻輸出機(jī)制,它主要用于調(diào)整視頻控制器硬件中的視頻內(nèi)容大小,以放大給定視頻或以全屏模式觀看。沒(méi)有X視頻擴(kuò)展,X將不得不在主CPU上進(jìn)行縮放,這需要大量的處理能力,會(huì)減慢或降低視頻流,這對(duì)ARM幾乎是不可接受的,因此需要在Wayland中針對(duì)RK3188平臺(tái)的X視頻擴(kuò)展接口,利用其硬件縮放和YUV加速能力。X視頻擴(kuò)展的實(shí)現(xiàn)只需要在Wayland中增加RK3188的設(shè)備驅(qū)動(dòng),并實(shí)現(xiàn)XVideo接口即可。RK3188圖像輸出接口的設(shè)備驅(qū)動(dòng)在其內(nèi)核中已定義,不需要調(diào)用Android 下的相關(guān)庫(kù),因此根據(jù)SDK代碼實(shí)現(xiàn)framebuffer相關(guān)操作即可。關(guān)鍵部分代碼為:
//RK平臺(tái)的XVideo初始化函數(shù)
int rk_init(ScreenPtr pScreen)
{
…
rk_xvideo * rkxv = rk_xvideo_init(RkFb_private);
if (rkxv) {
XVideo_private = XVideo_Init(pScreen, rkxv->intf);
}
return 0;
}
在wayland的初始化函數(shù)中將xv_private修改為rk_init,關(guān)鍵代碼為:
void
xwl_xv_init_port(ScreenPtr screen, glamor_port_private *port_priv, int port_number)
{
…
port_priv->xv_private = rk_init_xv();
REGION_NULL(pScreen, port_priv->clip);
}
3 總結(jié)
本文構(gòu)建的基于Android的高性能云終端,通過(guò)構(gòu)建LibBridge中間層解決了Glibc與Bionic的兼容性問(wèn)題,以Android系統(tǒng)的驅(qū)動(dòng)為基礎(chǔ)構(gòu)建Linux系統(tǒng)應(yīng)用,將Android的優(yōu)勢(shì)與Linux優(yōu)勢(shì)相整合,使得Linux系統(tǒng)的應(yīng)用能夠充分利用Android系統(tǒng)的硬件驅(qū)動(dòng),擴(kuò)大云終端ARM+Linux平臺(tái)的選型范圍,使云終端從傳統(tǒng)PC、專用的云終端設(shè)備擴(kuò)展到Android移動(dòng)設(shè)備上。
參考文獻(xiàn):
[1]徐浩, 蘭雨晴. 基于SPICE協(xié)議的桌面虛擬化技術(shù)研究與改進(jìn)方案[J]. 計(jì)算機(jī)工程與科學(xué), 2013, 35(12):20-25.
[2]KHAJEH-HOSSEINI A, GREENWOOD D, SOMMERVILLE I. Cloud Migration: A Case Study of Migrating an Enterprise IT System to IaaS[C]// International Conference on Cloud Computing. IEEE Computer Society, 2010:450-457.
[3]卿斯?jié)h. Android安全研究進(jìn)展[J]. 軟件學(xué)報(bào), 2016, 27(1):45-71.
[4]LI J, JIA Y, LIU L, et al. CyberLiveApp: A secure sharing and migration approach for live virtual desktop applications in a cloud environment[J]. Future Generation Computer Systems, 2013, 29(1):330-340.
[5]CALYAM P, PATALI R, BERRYMAN A, et al. Utility-directed resource allocation in virtual desktop clouds[J]. Computer Networks, 2011, 55(18): 4112-4130.
[6]徐浩, 蘭雨晴. 基于SPICE協(xié)議的桌面虛擬化技術(shù)研究與改進(jìn)方案[J]. 計(jì)算機(jī)工程與科學(xué), 2013, 35(12):20-25.
[7]張超. 面向桌面Linux的Android運(yùn)行環(huán)境構(gòu)建[D]. 長(zhǎng)沙:國(guó)防科學(xué)技術(shù)大學(xué), 2012.
[8]李宇成, 梁宗希. Linux攝像頭驅(qū)動(dòng)的設(shè)計(jì)優(yōu)化及其對(duì)應(yīng)的Android下HAL封裝設(shè)計(jì)方法探究[J]. 計(jì)算機(jī)應(yīng)用與軟件, 2016, 33(9):249-253.
[9]董慧, 方金云, 趙紅超,等. 基于Citrix的異地軟件共享系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J]. 計(jì)算機(jī)工程, 2009, 35(1):49-51.
[10]宮健. 基于Gstreamer的嵌入式流媒體傳輸系統(tǒng)的研究與實(shí)現(xiàn)[D]. 南京:南京郵電大學(xué), 2016.
[11]萬(wàn)海清. 基于Android的運(yùn)動(dòng)檢測(cè)視頻監(jiān)控應(yīng)用的設(shè)計(jì)與實(shí)現(xiàn)[D]. 武漢:華中科技大學(xué), 2015.
[12]SYSTEM X W, SOFTWARE F, ORG F. Video Acceleration API[J]. Human Immunology, 2014, 75(2):124-128.
(責(zé)任編輯:周曉南)