徐志亮,郭真鈴,李博,袁泉,謝小龍
(1.中電(海南)聯(lián)合創(chuàng)新研究院,海南 澄邁 571924;2.中軟信息系統(tǒng)工程有限公司,北京 102209)
為了在信息技術(shù)產(chǎn)業(yè)鏈各個(gè)環(huán)節(jié)擁有自主知識產(chǎn)權(quán),我國已將信創(chuàng)工程納入國家發(fā)展戰(zhàn)略,在政策和市場的逐步引導(dǎo)下,基礎(chǔ)軟硬件、應(yīng)用軟件、信息安全等領(lǐng)域國產(chǎn)化發(fā)展如火如荼。在這過程中,面臨著大量現(xiàn)有應(yīng)用軟件與信創(chuàng)計(jì)算體系無法兼容的問題。各行業(yè)應(yīng)用便開始了與信創(chuàng)相關(guān)計(jì)算體系的適配與遷移工作。
但是在實(shí)踐的過程中往往會面臨諸多問題,例如自研應(yīng)用軟件依賴一些第三方的閉源組件或信息系統(tǒng)是由第三方提供,使用單位不具備遷移適配的條件等,如何運(yùn)行不做任何修改的Window 軟件,為當(dāng)前不具備遷移條件的Window 軟件在信創(chuàng)相關(guān)計(jì)算體系上運(yùn)行提供臨時(shí)解決方案。
本文將基于PKS 體系以SilverLight 插件為例進(jìn)行研究,該插件是基于x86 處理器和Windows 操作系統(tǒng)進(jìn)行開發(fā)的,過去廣泛應(yīng)用于Web 網(wǎng)頁程序中。在指令集和操作系統(tǒng)存在差異的情況下,SilverLight 插件在PKS 體系上無法運(yùn)行。
目前,存在以下兩種解決方案:一是在宿主機(jī)中安裝Qemu 環(huán)境并創(chuàng)建Windows 虛擬機(jī),在虛擬機(jī)中訪問插件頁面;二是在Wine 中運(yùn)行瀏覽器并訪問插件頁面。
當(dāng)前這兩種解決方案均需耗費(fèi)一定的硬件資源,且運(yùn)行過程中存在高延遲的情況,未能有效解決Silver-Light 在PKS 體系上無法運(yùn)行的問題。因此,本文提出一套解決方案,該方案將SilverLight 運(yùn)行在由二進(jìn)制翻譯工具和Wine 構(gòu)成的系統(tǒng)環(huán)境兼容層中,以Pipelight 作為通信機(jī)制,將系統(tǒng)環(huán)境兼容層與Pipelight 相結(jié)合,實(shí)現(xiàn)SilverLight 在PKS 體系上的順利運(yùn)行。
網(wǎng)景插件應(yīng)用程序編程接口(Netscape Plugin Application Programming Interface,NPAPI)是 由Mozilla推出的一種瀏覽器插件的接口標(biāo)準(zhǔn)。NPAPI 的接口分為兩類,一是以“NP”“NPP”開頭,該類接口由插件實(shí)現(xiàn),主要用于創(chuàng)建并初始化插件實(shí)例、銷毀插件實(shí)例等;二是以“NPN”開頭,該類接口由瀏覽器實(shí)現(xiàn),主要用于創(chuàng)建數(shù)據(jù)流、查詢?yōu)g覽器相關(guān)信息等。通常使用<o(jì)bject>標(biāo)簽或<embed>標(biāo)簽在網(wǎng)頁中嵌入一個(gè)插件,標(biāo)簽中的type 屬性是多用途互聯(lián)網(wǎng)郵件擴(kuò)展類型(Multipurpose Internet Mail Extensions,MIME),瀏覽器通過該屬性確定嵌入的插件。
當(dāng)訪問一個(gè)嵌有插件的頁面時(shí),瀏覽器通過MIME查找并加載相應(yīng)插件。若該插件是首次加載,則瀏覽器調(diào)用插件的NP_GetEntryPoints 函數(shù)和NP_Initialize 函數(shù)進(jìn)行插件初始化,其中NP_GetEntryPoints 函數(shù)負(fù)責(zé)提供插件的函數(shù)表,NP_Initialize 函數(shù)負(fù)責(zé)記錄瀏覽器提供的函數(shù)表。首次加載完成后,瀏覽器會根據(jù)頁面內(nèi)容創(chuàng)建一個(gè)或多個(gè)插件實(shí)例,即調(diào)用插件的NPP_New 函數(shù)。當(dāng)關(guān)閉頁面時(shí),瀏覽器會調(diào)用插件的NPP_Destory 函數(shù)銷毀該頁面中的插件實(shí)例。當(dāng)瀏覽器關(guān)閉時(shí),瀏覽器調(diào)用插件的NPP_Shutdown 函數(shù)卸載插件[1]。瀏覽器調(diào)用插件函數(shù)的順序如圖1 所示。
圖1 瀏覽器調(diào)用插件函數(shù)的順序
Pipelight 是為解決在Linux 瀏覽器中無法運(yùn)行SilverLight 的問題而設(shè)計(jì)的NPAPI 瀏覽器插件[2]。Pipelight 不僅針對SilverLight 作了適配,還適配了Flash、ActiveX 等Windows插件。Pipelight 分為兩部 分:pluginloader.exe 和libpipelight.so。libpipelight.so作為NPAPI瀏覽器插件,由瀏覽器調(diào)用;pluginloader.exe 負(fù)責(zé)調(diào)用SilverLight,獲取相應(yīng)的數(shù)據(jù)。但Pipelight 是基于x86-Linux 開發(fā)的,因此無法直接運(yùn)行在PKS 體系中,還需根據(jù)PKS 體系做相應(yīng)的修改和適配。
SilverLight 是微軟于2007 年針對Web 應(yīng)用程序中多媒體服務(wù)需求大和網(wǎng)頁交互性差的問題提出的解決方案[3]。在傳統(tǒng)的B/S 技術(shù)中,客戶端只是呈現(xiàn)靜態(tài)頁面和結(jié)果,而SilverLight 能讓用戶體驗(yàn)豐富的圖形界面和流暢的交互效果。用戶在使用瀏覽器訪問嵌有SilverLight 插件的頁面之前,需在系統(tǒng)中部署SilverLight。網(wǎng)頁開發(fā)者需使用<o(jì)bject>標(biāo)簽將SilverLight 插件嵌入到頁面中,標(biāo)簽中的type 屬性常為application/xsilverlight 和application/x-silverlight-2[4]。
為實(shí)現(xiàn)SilverLight 在PKS 體系中運(yùn)行,需要解決以下三個(gè)方面的問題:
(1)如何在ARM 處理器上運(yùn)行x86 程序:飛騰處理器屬于ARM 處理器的一種,而SilverLight 是在x86 處理器上開發(fā)和運(yùn)行的程序,無法直接在ARM 處理器上運(yùn)行。這本質(zhì)上是指令集不同的問題。
(2)如何在Linux 操作系統(tǒng)上運(yùn)行Windows 程序:麒麟操作系統(tǒng)是基于Linux 內(nèi)核開發(fā)的,屬于Linux 操作系統(tǒng),而SilverLight 是基于Windows 操作系統(tǒng)開發(fā)的程序,無法直接在Linux 操作系統(tǒng)上運(yùn)行。
(3)瀏覽器如何調(diào)用SilverLight:在PKS 體系下瀏覽器插件以NPAPI 插件為主,而且瀏覽器無法直接調(diào)用SilverLight 這類Windows 專用插件,因此這兩者之間需要建立一個(gè)通信機(jī)制,該機(jī)制不僅能作為NPAPI 插件供瀏覽器調(diào)用,同時(shí)能根據(jù)瀏覽器請求信息調(diào)用Silver-Light 插件并返回相應(yīng)數(shù)據(jù)。
根據(jù)上述問題設(shè)計(jì)了一套解決方案,如圖2 所示。該方案中用二進(jìn)制翻譯工具解決指令集不同的問題;用Wine 解決操作系統(tǒng)不同的問題;用Pipelight 解決瀏覽器調(diào)用SilverLight 的問題。
圖2 方案整體設(shè)計(jì)
基于上述方案,當(dāng)用戶訪問嵌有插件的頁面時(shí),調(diào)用步驟如下:
(1)瀏覽器根據(jù)MIME 在插件默認(rèn)路徑下查找并加載相應(yīng)的插件程序,即libpipelight.so。在Linux 系統(tǒng)中,瀏覽器插件默認(rèn)存放路徑是/usr/lib/mozilla/plugins。
(2)libpipelight.so 啟動系統(tǒng)環(huán)境兼容層、創(chuàng)建子進(jìn)程并調(diào)用pluginloader.exe,將瀏覽器的函數(shù)調(diào)用通過管道傳輸給pluginloader.exe。
(3)pluginloader.exe 根據(jù)接收信息調(diào)用插件相應(yīng)的NPAPI。
系統(tǒng)環(huán)境兼容層主要分為兩部分:二進(jìn)制翻譯工具和Wine。
二進(jìn)制翻譯技術(shù)分為靜態(tài)翻譯和動態(tài)翻譯。靜態(tài)翻譯是指先進(jìn)行翻譯工作,再運(yùn)行翻譯后的程序。動態(tài)二進(jìn)制翻譯技術(shù)是指在程序運(yùn)行時(shí)動態(tài)將原指令翻譯成目標(biāo)指令的技術(shù)。本文使用的二進(jìn)制翻譯工具屬于動態(tài)二進(jìn)制翻譯工具,實(shí)現(xiàn)從x86 指令翻譯成ARM 指令的功能,即在二進(jìn)制翻譯工具所設(shè)的環(huán)境內(nèi),系統(tǒng)是x86-Linux 環(huán)境。要想進(jìn)一步將x86-Linux 環(huán)境更換成x86-Windows,則需要另一個(gè)操作系統(tǒng)模擬工具——Wine。
Wine 是一個(gè)將Windows API 調(diào)用翻譯成動態(tài)的POSIX 調(diào)用的兼容層。與虛擬機(jī)完全模擬Windows 內(nèi)部邏輯的原理不同,這是一種庫級虛擬化工具。比起笨重的虛擬機(jī),Wine 的運(yùn)行效率更高、系統(tǒng)資源占用更少、對計(jì)算機(jī)的性能要求更低。通過Wine,可以實(shí)現(xiàn)從Linux 操作系統(tǒng)到Windows 操作系統(tǒng)的轉(zhuǎn)換。
由二進(jìn)制翻譯工具和Wine 構(gòu)成的系統(tǒng)環(huán)境兼容層,實(shí)現(xiàn)了從ARM64-Linux 到x86-Windows 的雙重翻譯,給在PKS 體系上運(yùn)行SilverLight 提供了可能。
為解決瀏覽器與SilverLight 通信的問題,本文采用開源工具Pipelight 并在Pipelight 的基礎(chǔ)上針對PKS 體系進(jìn)行適配。
通信機(jī)制分為兩部分:數(shù)據(jù)傳輸和函數(shù)調(diào)用分發(fā)。數(shù)據(jù)傳輸通過在libpipelight.so 和pluginloader.exe 之間建立管道和設(shè)定傳輸格式實(shí)現(xiàn)。
管道的建立在初始化階段完成。當(dāng)訪問嵌有Silver-Light 的網(wǎng)頁時(shí),瀏覽器會調(diào)用libpipelight.so 中的attach函數(shù),完成配置文件的加載、插件的安裝檢查、pluginloader.exe 的調(diào)用和插件的初始化。在管道的兩端分別使用fread 函數(shù)和fwrite 函數(shù)實(shí)現(xiàn)數(shù)據(jù)的讀寫功能。
Pipelight 設(shè)定每次傳輸?shù)膬?nèi)容由命令和數(shù)據(jù)構(gòu)成,如圖3 所示。每條命令共4 個(gè)字節(jié),其中第1 個(gè)字節(jié)代表命令類型,后面3 個(gè)字節(jié)代表數(shù)據(jù)長度,單位是字節(jié)。命令后緊接著傳輸具體數(shù)據(jù),數(shù)據(jù)的最大長度是0xFFFFFF 字節(jié)。在Pipelight 中命令類型是一個(gè)枚舉類型,一共有9 種枚舉值,每個(gè)枚舉值都有對應(yīng)的含義,例如圖3 中的0x02 表示傳輸32 位有符號數(shù)。
圖3 數(shù)據(jù)傳輸格式
在傳輸數(shù)據(jù)的過程中發(fā)現(xiàn),當(dāng)遇到某些特殊字節(jié)時(shí)會出現(xiàn)傳輸錯(cuò)誤的情況,例如:發(fā)送端發(fā)送0x0A,接收端接收到0x0A0D。因此在傳輸命令和具體數(shù)據(jù)之前需要分別對其按字節(jié)處理并傳輸相應(yīng)的標(biāo)志數(shù)據(jù)(Flag)和位置數(shù)據(jù)(Site)。傳輸順序如圖4 所示。接收端同樣按照這個(gè)順序接收命令和數(shù)據(jù),對于有特殊情況的字節(jié)要做相應(yīng)的還原處理。當(dāng)?shù)趇個(gè)字節(jié)出現(xiàn)特殊情況,處理方法如下:
圖4 數(shù)據(jù)傳輸順序
(1)發(fā)送端:
(2)接收端:
函數(shù)調(diào)用分發(fā)主要由棧、函數(shù)枚舉和命令類型實(shí)現(xiàn)。當(dāng)出現(xiàn)函數(shù)調(diào)用的情況時(shí),調(diào)用方將函數(shù)參數(shù)從右往左依次傳輸?shù)焦艿乐校鬏斦{(diào)用的函數(shù)枚舉值。被調(diào)用方依次接收函數(shù)參數(shù)并將參數(shù)存入棧中,當(dāng)接收到函數(shù)枚舉值時(shí)會調(diào)用相應(yīng)的函數(shù)。在函數(shù)執(zhí)行完畢后,被調(diào)用方將執(zhí)行結(jié)果傳輸?shù)焦艿乐胁⑾蚬艿纻鬏斠粋€(gè)函數(shù)返回的命令。在這過程中,棧主要負(fù)責(zé)暫存函數(shù)參數(shù)和返回值;命令類型主要負(fù)責(zé)將函數(shù)調(diào)用、參數(shù)和函數(shù)返回區(qū)分開。在9 種命令類型中BLOCKMCD_CALL_DIRECT 表示函數(shù)調(diào)用,隨后接收的數(shù)據(jù)是函數(shù)枚舉值;BLOCKMCD_RETURN 表示函數(shù)返回,隨后無需從管道讀取數(shù)據(jù);其余命令類型分別表示接收的數(shù)據(jù)類型,用于從管道中讀取參數(shù)并存入棧中。
葛立方的筆記,由左思、陶潛的詩說起,對于兩位詩人貶低荊軻人格,予以糾正,并指出均出自于以成敗論人之庸俗歷史觀。這是作者的高明之處,值得贊賞。然而,在他指責(zé)太子丹催促荊軻出發(fā)行刺而導(dǎo)致了荊軻之失敗,并謂“概之于義,雖得秦王之首,于燕亦未能保終吉也”之時(shí),同樣犯了以成敗論人的痼疾。至于舉漢代揚(yáng)雄之言,斥荊軻無義,并視其為后代黑幕刺客之緒,則更為無稽。蓋揚(yáng)雄身處排斥游士的漢代,處禁錮日深,站在時(shí)代的立場,自然要非議荊軻,反對復(fù)仇;何況揚(yáng)雄信奉古文經(jīng)學(xué),與今文經(jīng)學(xué)有隔。故此,揚(yáng)雄反感以公羊?qū)W為思想基礎(chǔ)的作品及其所塑造出來的人物。
當(dāng)瀏覽器調(diào)用NP 或NPP 函數(shù)時(shí),libpipelight.so 負(fù)責(zé)將函數(shù)調(diào)用轉(zhuǎn)發(fā)到pluginloader.exe,由pluginloader.exe 調(diào)用DLL 中相應(yīng)的NPP 和NP 函數(shù)。當(dāng)插件調(diào)用NPN 函數(shù)時(shí),pluginloader.exe 負(fù)責(zé)將函數(shù)調(diào)用轉(zhuǎn)發(fā)到libpipelight.so,由libpipelight.so 調(diào)用瀏覽器的NPN 函數(shù)。例如:瀏覽器調(diào)用libpipelight.so 的NPP_StreamAs-File函數(shù),經(jīng)libpipelight.so 轉(zhuǎn)發(fā)到pluginloader.exe,由pluginloader.exe 調(diào)用DLL 中的NPP_StreamAsFile 函數(shù)。
本次實(shí)驗(yàn)將本文提出的方案和另外兩種解決方案從系統(tǒng)內(nèi)存消耗、運(yùn)行速度等方面做對比,結(jié)果如圖5、圖6 所示。
圖5 系統(tǒng)內(nèi)存消耗實(shí)驗(yàn)結(jié)果
圖6 運(yùn)行速度實(shí)驗(yàn)結(jié)果
2.4.1 方案設(shè)定
方案1:在宿主機(jī)中安裝Qemu 環(huán)境并創(chuàng)建Windows虛擬機(jī),在虛擬機(jī)中訪問嵌有SilverLight 插件的頁面。
方案2:在Wine 中安裝并運(yùn)行FireFox 瀏覽器,通過FireFox 瀏覽器訪問嵌有SilverLight 插件的頁面。
方案3:本文提出的方案。
本次實(shí)驗(yàn)在一臺PKS 終端機(jī)上進(jìn)行,終端機(jī)為8 核CPU、16 GB 內(nèi)存。三個(gè)方案中使用到的軟件信息如表1 所示。
表1 實(shí)驗(yàn)環(huán)境一覽表
2.4.3 結(jié)果分析
如圖5 所示,在系統(tǒng)內(nèi)存消耗方面,方案3 占用系統(tǒng)內(nèi)存最少,是方案1 消耗量的20%、方案2 消耗量的79%。
運(yùn)行速度主要分為兩方面:一是訪問目標(biāo)頁面時(shí),頁面加載的時(shí)長;二是頁面加載完畢后,用戶在頁面中進(jìn)行一次點(diǎn)擊操作時(shí),頁面的響應(yīng)時(shí)長。如圖6 所示,無論是頁面加載時(shí)長還是點(diǎn)擊操作時(shí)長,方案3 的運(yùn)行速度都遠(yuǎn)超方案1 和方案2,尤其是在點(diǎn)擊操作時(shí)長方面,基本沒有時(shí)延。
在用戶操作的簡易程度方面,對于方案1 和方案2,用戶都是在非宿主系統(tǒng)的瀏覽器中進(jìn)行操作,而方案3在原先的瀏覽器中便可訪問目標(biāo)頁面,可見方案3 的用戶操作簡易程度優(yōu)于另外兩種方案。
本文針對PKS 體系中無法運(yùn)行SilverLight 的問題,提出一套解決方案。研究Pipelight 的原理,將Pipelight和系統(tǒng)環(huán)境兼容層結(jié)合并根據(jù)PKS 體系進(jìn)行了修改和適配,最終能在PKS 體系中運(yùn)行該插件且運(yùn)行速度在可接受范圍內(nèi)。該方案的思路同樣適用于ActiveX 控件的兼容適配。這給在PKS 體系中開展相關(guān)工作提供了思路。