苏 煜,张 涛,靳国杰,荣 辉,王金双,赵 敏
(1.解放军理工大学指挥信息系统学院,江苏南京210007)(2.龙芯中科技术有限公司,北京100098)
核心软硬件的自主化对于国家信息安全至关重要.目前,国产处理器主要有龙芯、飞腾等;操作系统主要代表是中标麒麟;数据库主要有人大金仓、神通和达梦等.龙芯处理器采用MIPS指令集,运行类Unix操作系统,由于该平台上应用软件还相对匮乏,且Windows程序无法直接在该平台上运行,这对传统应用的移植以及该平台的推广与应用造成一定的影响.
传统的软件移植的主要类型通常是二进制移植(移植可执行文件)和源代码移植(移植源语言表达式)[1].源代码移植是通过对软件源代码进行分析,找出其相关于目标环境的代码,并进行修改,使其符合环境的运行要求,但有些时候源代码无法获得.二进制移植是指可执行文件通过向目标环境移植,达到在目标环境正常运行的移植方法.虚拟化技术是常用的二进制移植方法,但目前龙芯处理器的性能还难以克服当前虚拟化技术带来的性能影响.
因此,文中提出了在龙芯处理器上交叉编译Wine软件,使其提供Windows应用软件运行环境的轻量级解决方案,并通过Wine与Bochs模拟器相结合实现了X86指令集向龙芯MIPS指令集的解释执行,从而实现了Windows程序向龙芯平台的零修改迁移.
指令集仿真是解决不同指令集之间软件二进制移植的主要方法.当前,对指令集的仿真主要分为两种方式:一种是指令解释执行,一种是二进制翻译[2].解释执行通过对源指令进行取指、译码和仿真,实现源指令集体系结构ISA(instruction set architecture)向目标ISA的映射.Bochs便是一个开源的指令集解释器,它可以通过对不同设备进行模拟,实现应用对虚拟化的不同要求,而不需要对整个系统进行仿真.二进制翻译是把源指令块翻译成执行同样功能的目标指令,因为是指令块之间的对应,相对于解释执行,效率会更高.QEMU(quick EMUlator)是目前较为先进的支持多元多目标平台的动态二进制翻译系统[3].为了实现Windows应用程序在跨操作系统,跨指令集的平台下运行,不仅需要对用户指令进行翻译,同时还需要仿真Windows的系统调用.单纯的使用指令集仿真无形当中加重了虚拟化的负担,影响了使用效率.因此,将Wine编译到MIPS环境,由Wine来提供Windows应用程序所需的部分API,同时通过Bochs实现在MIPS环境下用户指令和部分Windows原生动态库的解释执行,构建Bochs+Wine方式提高运行效率.未来可考虑实现QEMU+Wine的方式来进一步优化系统,提高效率.
采用分层思想的计算机体系结构存在ISA和ABI(application binary interface)[4]两个重要接口.ISA由用户ISA和系统ISA组成,ABI主要由系统调用接口和用户ISA组成[5].X86与MIPS分别有不同的ISA且相互不兼容.同时为了提高软件在不同ISA的运行效率,面临着系统调用跨平台执行的性能优化问题.
为了迎合自主化的需要,该虚拟结构运行在搭载Linux操作系统的龙芯3A处理器上.龙芯3A是国家自主研制的基于MIPS指令集的处理器.在该平台上运行X86指令的Windows应用程序既跨体系结构又跨操作系统平台.本系统采用开源软件Wine和Bochs来完成此任务,整体设计方案如图1.
图1 跨平台中间件的整体设计方案Fig.1 Overall design of cross platform middleware
该系统通过虚拟化技术构造一个进程虚拟机,该虚拟机通过Wine提供并实现应用程序运行所需的动态库.结合X86模拟器对应用程序调用的Windows原生动态库以及Wine的初始化指令进行翻译执行,通过X86模拟器实现Wine在不同ISA平台下对Windows系统库的兼容.
虚拟化是构建一个将虚拟的客户系统映射到真实的主机系统上的同态.通过虚拟化技术,可以实现依赖于客户系统的软件在主机系统上良好运行.虚拟化过程包含两个部分:①把虚拟资源或状态映射成底层机器中的真实资源;②使用真实机器上的指令和/或系统调用来执行虚拟机的指令和/或系统调用规定的活动[6].虚拟机便是通过虚拟化技术,构建一个介于主机和客户系统的中间件实现仿真平台的设计架构.通过虚拟机ABI或ISA的仿真,实现可执行文件的跨平台移植.
Wine通过Window API仿真实现Windows软件在类UNIX系统中运行[7].与一般的模拟器不同,它并不提供虚拟cpu以及I/O设备的仿真,而是通过Winelib把Windows API(应用程序接口)用标准的Unix和X接口重新实现(图2).Windows应用程序的运行主要依赖于 NTDLL,KERNEL32,GDI32和USER32 4个动态库.Wine已经基本实现该DLL动态库与UNIX API的对应.Wine与Windows NT架构对应关系如图 3[8].
图2 Wine实现相同指令集下的虚拟机架构Fig.2 Virtual machine architecture of Wine implementation
图3 Wine架构以及与Windows NT架构的对应关系Fig.3 Corresponding relation between Wine architecture and Windows NT architecture
Bochs是开源的X86仿真平台.它能够支持多种不同指令集实现跨指令集的X86仿真.Bochs通过在不同的操作系统与指令集和目标应用之间构建一个虚拟的仿真层(图4),将目标软件执行的代码指令解释为主机可识别指令.Bochs可以模拟Intel X86 CPU、通用I/O设备和客户BIOS,还能够模拟运行大部分的操作系统,如Linux,DOS,Windows 95/98,Windows NT/2000/XP 等[9].Bochs 能够被编译和使用为多种模式,通常使用Bochs来提供完整的X86 PC模拟器,包括X86处理器,硬件设备和内存.
图4 利用Bochs实现在MIPS架构下的Windows应用Fig.4 Application of Windows in MIPS framework using Bochs
由上文可以得出,Windows应用程序在运行中,可能会调用Wine内置动态库,或者Windows原生动态库.在本系统中,由于应用程序和Windows原生动态库是X86指令集的二进制制品,他们都要通过Bochs来模拟执行.
系统在运行Windows应用程序时,整个进程地址空间中存在着如下几种形态的线性区:①Windows应用程序,PE格式,X86指令;②Windows原生动态库,PE格式,X86指令;③Wine内置动态库,ELF格式,MIPS指令;④Bochs模块,ELF格式,MIPS指令.相应的,系统在运行时,有两种执行形态:①Wine内置动态库和Bochs模块,在龙芯CPU上直接执行;②Windows应用程序和Windows原生动态库,通过Bochs模拟执行.
系统在运行时,需要在线性区之间进行交互,由一个线性区到另一个线性区的切换往往通过函数调用.根据线性区类型和函数调用方式,文中把交互分为如下4种类型,并针对每种类型,进行相应的接口设计.
1)从X86指令线性区调用到X86指令线性区.X86指令的线性区都是在Bochs上执行,这种类型的调用方式在X86指令内部已经完成,并不需要多余的操作.
2)从MIPS指令线性区调用到MIPS指令线性区.MIPS指令的线性区是在龙芯CPU上直接执行,这种类型的调用方式也不需要二进制指令外的多余的操作.
3)从X86指令线性区调用到MIPS指令线性区.X86指令的线性区是在Bochs上执行的,在本系统中,这种类型的调用存在于两个地方:Bochs对指令JMP和CALL的模拟,系统需要在这两处地方进行相应的判断,如果判断为到MIPS指令线性区的调用,则跳转到MIPS指令执行.
4)从MIPS指令线性区调用到X86指令线性区.回调就是这种类型的一个典型.当回调发生时,一部分回调会跳转到Wine内置动态库,另一部分会跳转到X86指令部分.除了回调,Wine的内置动态库中也会有向X86指令部分的调用.
系统设计了相应的调用方式,如图5所示.
图5 Wine和Bochs交互设计框图Fig.5 Interaction design of Wine and Bochs
2.5.1 X86指令线性区调用MIPS指令函数
系统开始运行时,会统计所有MIPS动态库中API的名字、地址、参数个数等,并把它们记录在数据表中.Bochs在对指令JMP和CALL模拟时,首先获得要跳转到的指令的地址,该地址存储在EIP(extended instruction pointer)寄存器中,系统判断该EIP是指向X86指令空间,还是MIPS指令空间.Bochs在初始化时,遍历了该进程空间中所有的MIPS动态库,查表获取每个MIPS动态库的基地址和大小.系统通过将EIP的值和该数据表中地址空间范围比较,来确定该EIP是否指向MIPS指令空间.如果该EIP属于MIPS指令空间,则进行相应的处理,跳转到MIPS函数执行;否则继续按照Bochs的方式执行.
2.5.2 MIPS指令线性区调用X86指令函数
这种类型的调用主要分为两种情况:①回调函数;②PE格式的动态库在加载完成后,要执行它的入口函数,执行入口函数需要进入X86指令空间.
在Bochs中,本文设计了开启Bochs模拟执行的接口.每个接口都是一个X86指令空间的函数调用,根据调用的参数个数设计不同的接口类型.接口内部的实现中,首先要找到 Bochs的虚拟CPU,然后进行相应的现场保护,之后进行函数调用,调用完成后返回.2.6 多线程的实现
Wine中的程序通过createThread创建新的线程,由Wineserver进行线程调度,并发起线程的执行.新创建的线程从一个入口开始执行,线程可能会执行到X86指令,需要Bochs来模拟执行.
由于每个线程都要有一个独立的模拟执行部件,而且在执行的时机上是物理并发的,因此需要创建多个Bochs模拟CPU,每个模拟CPU用于执行一个线程中的X86指令.
本文测试评估时基于龙芯3A硬件平台实现了一个原型系统.实验系统的运行环境为龙芯3A 8核心1Ghz处理器,DDR800 2G内存的服务器,中标麒麟高级服务器版V6.0操作系统.系统评估实验设置了系统功能和系统性能两种类型的测试,其中:
1)系统功能测试:通过在原型系统中运行Delphi,VC++开发的简单单线程程序和多线程程序,以及复杂的MIS系统程序来评估系统功能的完善性.
2)系统性能测试:以Windows下运行记事本程序的响应时间作为基准,通过本原型系统运行Windows下编译的记事本程序和 Linux下通过Wine交叉编译生成的记事本程序的响应时间来评估系统性能.
采用虚拟执行环境运行一个delphi程序,该程序绘制基本的delphi控件,并多线程的运行(图6a)),采用该虚拟执行环境运行贪吃蛇,如图6b).采用该虚拟执行环境运行一个数据库客户端,该客户端采用ODBC的方式访问远程数据库服务器(如图6c)).该数据库客户端可以正常读写服务器里的数据.
图6 功能测试Fig.6 Function test
获得 Windows记事本可执行文件 notepad.exe,在Linux终端上使用命令Wine notepad.exe运行notepad.exe程序(图7).测试该应用在运行速度、响应时间、稳定性等性能是否能够达到一般用户的使用要求.测试中与Windows平台进行比较,测试实例如表1,测试结果如表2.
表1 测试实例Table 1 Test case
表2 测试结果Table 2 Test results
经系统功能测试,该虚拟环境支持Delphi,C,C++等多种语言开发的程序,以及支持网络、数据库等多种功能.经系统性能测试,系统运行notepad.exe基本满足使用要求,但需要进一步改进.同时,用oprofile软件分析影响虚拟环境性能的函数,为以后的优化提供了参考.
文中设计的零修改软件移植中间件可以很好地完成Windows程序跨平台移植,基本实现了简单程序(notepad.exe)在龙芯平台上的运行.通过优化结构,目标实现Office软件在龙芯平台上的正常运行.这将使国家机关在自主化平台上的办公得以实现.同时,可以基于该系统架构进行信息流的分析与追踪,提高系统安全保障.
References)
[1] 陈丹丹.软件移植实践[D].杭州:浙江大学,2007.
[2] Cifuentes C,Malhotra V.Binary translation:static,dynamic,retargetable[C]∥Proceedings of International Conference on Software Maintenance.Monterey CA USA:IEEE -CS Press.1996:340 -349.
[3] 陈乔,蒋烈辉,董卫宇,等.基于动态二进制翻译技术的仿真器研究[J].计算机工程,2011,37(20):277-279.Chen Qiao,Jiang Liehui,Dong Weiyu,et al.Simulator research based on dynamic binary translation technology[J]].Computer Engineering,2011,37(20):277 -279.(in Chinese)
[4] 黄聪会,陈靖,罗樵,等.面向二进制移植的虚拟化技术[J].计算机应用研究,2012,29(11):4185 -4187.Huang Conghui,Chen Jing,Luo Qiao,et al.Virtualization technology for binary migration[J].Application Research of Computer,2012,29(11):4185 - 4187.(in Chinese)
[5] Smith E,Nair R.The architecture of virtual machines[J].Computer,2005,38(5):32 -38.
[6] Smith J E,Nair R.虚拟机:系统与进程的通用平台[M].北京:机械工业出版社,2009:4-7.
[7] Wine User’s Guide.Chapter 1 Introduction.[DB/OL].http:∥www.winehq.org/docsen/wineusr-guide.html#introduction.
[8] Wine Developer’s Guide.Chapter Ⅱ.Wine architect[DB/OL].http:∥www.winehq.orgsite/docs/winedevguide/×2884.
[9] Bochs User Manual.Chapter 1 Introduction to Bochs[DB/OL].http:∥bochs.sourceforge.net.