专利名称::将Wine从x86移植到ARM平台的方法
技术领域:
:本发明涉及计算机运行环境模拟器领域、操作系统领域和CPU体系结构领域,尤其是将Wine从X86移植到ARM平台的方法。
背景技术:
:MicrosoftWindows(简称Windows)是目前桌面电脑上常见的操作系统,有多个不同的版本,适用于个人电脑、工作站和服务器。Windows系列操作在桌面电脑市场的占有率于2010年底达到90%以上,可见其普及率和受欢迎程度。Windows之所以这么受到用户欢迎的一大原因就是Windows平台上的应用软件非常多,大部分的软件开发商都愿意首先为Windows平台开发应用,而很多用户不愿意切换到其他操作系统就是因为其他系统上没有用户所需的某个应用或令用户满意替代版本。ARM架构处理器是目前非常流行的一种处理器架构,其精简指令集(RISC)的设计比起桌面电脑处理器中常见的x86的复杂指令集(CSIC)更加高效,能耗也更低。因此目前很多嵌入式设备或移动设备如智能手机大多都采用了ARM架构的处理器。然而由于ARM的指令集与x86指令集完全不同,无法在ARM处理器上运行传统桌面电脑的Windows操作系统,因而也无法运行Windows操作系统中的众多软件。Wine是一个在x86处理器上的模拟运行环境,利用Wine可在其他操作系统(通常为类Unix的操作系统如Linux)中直接运行Windows的可执行程序。因此利用Wine能够在不同操作系统上直接获得Windows环境下丰富的应用资源,很多Windows应用不需要进行任何修改(不需要重新编译)就能直接在Wine中运行,并且保持较高的运行效率。然而Wine只支持x86的处理器架构,并不支持ARM,因而无法在目前众多基于ARM的设备上运行。
发明内容本发明提出一种将Wine从x86移植到ARM平台的方法,从而使得ARM平台上也能运行众多的Windows程序,应用开发商能够快速地将原有的应用部署到目前众多的基于ARM的设备中,获得更多经济效益。要将原为x86架构CPU编写的Wine模拟器移植到ARM架构的CPU上,首先需要解决的问题就是把x86指令集的机器代码转换为ARM指令集的机器代码。对于使用C等高级语言编写的源代码,只需要在PC上使用生成ARM架构机器代码的编译器交叉编译即可。但Wine为了更有效地控制底层硬件,有一部分源代码是使用汇编代码编写的,由于汇编代码是与CPU指令集有关的,因此需要手工将这些汇编代码改写成ARM指令集的汇编代码。具体的方法是将x86汇编的指令逐条改写为对应的ARM汇编指令,并将指令中的操作数从x86寄存器改为ARM寄存器。由于x86指令集和ARM指令集的差异性,对于不存在对应ARM汇编指令的x86指令,需要使用多条ARM汇编指令来实现对应与对应x86汇编指令相同的功能。所要改写的汇编代码有以下几部分·loader/preloader,c中的所有汇编代码;·libs/wine/port.c中的winecallonstack函数;·libs/wine/port.c中的wineswitchtostack函数。另有一些数据结构并不是汇编指令,但也与具体的CPU有关。Wine中的CONTEXT数据结构用于表示CPU的寄存器上下文,寄存器上下文指某一时刻CPU所有寄存器的值,存储CPU在这一时刻的状态。不同的CPU具有不同的寄存器集合,所以表示它们的寄存器上下文的CONTEXT数据结构也不同。Wine在wine/include/winnt.h中提供了ARM的CONTEXT数据结构定义,但代码中却并没提供有关的代码实现,需要加以补充,增加ARM寄存器上下文保存、恢复、复制以及具体寄存器值提取的函数。Wine中运行的Windows可执行映像格式为PE(PortableExecutable),其文件头中有一个字段指明此可执行文件是针对哪一种CPU的,称为CPU架构签名。对于ARM处理器,这个字段的值为IMAGEFILEMACHINEARM或IMAGEFILEMACHINETHUMB,这两个常数的值分别是OxOIcO和0x01c2。Wine不能识别这两个CPU架构签名,所以无法装载或运行ARM的可执行映像。因此要添加对这种CPU架构签名的支持,需要修改kerne132/pr0cess.Co定义在include/shtypes.idl中的数据结构ITEMIDLIST如下typedefstruct_ITEMIDLIST{SHITEMIDmkid;/*firstitemidinlist*/}ITEMIDLIST,*LPITEMIDLIST;其中SHITEMID的定义为typedefstruct{WORDcb;/氺nrofbytesinthisitem氺/BYTEabID[l];/*firstbyteinthisitem*/}SHITEMID,*LPSHITEMID;这里数组abID的大小可变,其大小记录在字段cb中,这个数组用来存放文件名。当文件名的长度为奇数时,数据结构SHITEMID的大小是奇数,从而ITEMIDLIST的大小也是奇数,因而不与长字或字的边界对齐。在实际使用中,好几个SHITEMID数据结构会首尾相连叠在一起,形成一个列表。这样,如果第一个SHITEMID数据结构的大小是奇数,第二个SHITEMID数据结构的起点就不与长字或字的边界对齐了。x86处理器允许这样的不对齐的地址访问,但ARM处理器只允许与长字或字边界对齐的内存访问,否则就不保证操作的正确性。由于这个原因,当CPU从非对齐的SHITEMID数据结构中读取其cb字段的数值时,所得到的可能是个错误的数值。本发明通过对有关的函数ILGetSize、ILGetNext进行修改来解决这个问题,ILGetSize函数用于获得单个SHITEMID数据结构的大小,ILGetNext函数用于获得SHITEMID数据结构组成的列表中某一项的下一项地址。修改方法为在ILGetSize函数计算单个SHITEMID结构大小以及ILGetNext函数计算下一项地址时,新增一个」nsigma_align函数计算cb部分的大小,其计算方法是如果abID数组的大小为奇数的话,就在此数值上加1,使其与长字或字的边界对齐。通过复制一组SHITEMID数据结构形成一个列表的时候,实际复制的长度取决于ILGetSize函数的返回值,而返回值经过了_insigma_align函数调整,地址一定是偶数。因此在一个列表中,每一个SHITEMID数据结构的起点就都是与长字或字的边界对齐的,解决了ARM处理器访问内存时边界必须对齐的问题。图1是本发明实施例的将Wine从x86移植到ARM平台的流程图。具体实施例方式如图1所示。本实施例的将Wine从x86移植到ARM平台的流程包括如下步骤第一,将x86汇编的指令逐条改写为对应的ARM汇编指令,并将指令中的操作数从x86寄存器改为ARM寄存器。由于x86指令集和ARM指令集的差异性,对于不存在对应ARM汇编指令的x86指令,需要使用多条ARM汇编指令来实现对应与对应x86汇编指令相同的功能。具体的实现方法是通过增加宏定义_arm_来在编译时控制编译ARM专用的代码,因此ARM的汇编代码会被检测_arm_宏是否定义的条件编译语句包围。由于有较多的源代码涉及到x86汇编代码到ARM汇编代码的转换,因此这里只针对libs/wine/port,c中的wine_call_on_stack函数进行举例说明。wine_call_on_stack函数在转换后的代码如下intwine—call—on—stack(int(氺func)(void氺),void氺arg,void氺stack);#ifdefined(_i386_)Mldefined(_GNUC_)#elifdefined(—arm—)&&defined(—GNUC—)/氺AddedforARMProcessors,byInsigma氺/一ASM—GLOBAL—FUNC(wine_cal1—on—stack,movip,sp\n/氺saveoldspinip氺/〃bicr2,r2,#0xf\n〃"subr2,r2,#12\n〃movsp,r2\n/氺newsp氺/〃stmfdsp!,{ip,Ir}\n〃/氺saveipandIrinnewstack*/movr7,rO\n/水func水/movrO,rl\n/水arg水/〃movIr,pc\n〃movpc,r7\n〃/ホcallfuncホ/ldmfdsp!,{ip,Ir}\n/本restoreipandIrfromnewstack水/〃movsp,ip\n/水restoreoldspfromip水/〃movpc,Irノ;#elsefterrorYoumustimplementwine_switch_to_stackforyourplatform#endif以上代码保留_i386_宏的条件编译指令包围的x86的汇编代码(x86的具体代码使用“......”省略),新增用_arm_宏的条件编译指令包围的ARM汇编代码,其代码内容是将x86的对应指令按照功能改写为ARM汇编指令。第二,增加ARM表示寄存器上下文的CONTEXT数据结构步骤如下1、在dlls/ntdll目录下创建名为signal_arm.C的文件,其中需要实现与原signal_i386.c相同的函数,包括save_context>restore_context等函数。2、在dlls/ntdll/thread.c中有个函数copy_context,需要增力口对ARM的CONTEXT与x86的CONTEXT中不同的字段的复制代码。3、在WineServer的代码中,需要在server目录下面创建名为context_arm.c的文件,其中需要实现与原context」386.c相同的函数,例如copy_context、get_context_ip等函数。第三,增加对ARM架构可执行映像PE头文件CPU架构签名支持的具体方法是修改kerne132/process.c中的start_process函数为staticvoidstart_process(void氺arg){#ifdef一arm一//AddedbyInsigma.if(nt->FileHeader.Machine==IMAGE_FILE—MACHINE—THUMB||nt->FileHeader.Machine==IMAGE—FILE—MACHINE_ARM){//winceforarmentry_arm=entry;ExitThread(entry—arm(GetModuleHandleA(NULL),0,GetCommandLineW(),peb->ProcessParameters->wShowWindow));}else#endif}以上代码中增加了对头文件的CPU架构签名字段(FileHeader.Machine)为IMAGEFILEMACHINETHUMB或IMAGEFILEMACHINEARM时的情况判断,使得ARM处理器的可执行文件能够被加载运行。第四,ITEMIDLIST数据结构的存储位置修正需要修改ILGetSize和ILGetNext函数,分别都要在计算ITEMIDLIST数据结构大小时增加对_insigma_align函数的调用,_insigma_align函数的定义如下#ifdef一Insigma一WORD——insigma—align(WORDχ){if(χ%2){returnχ+1;}returnχ;}#endif以上函数被Jnsigmi^宏定义的条件编译包围,即定义了Jnsigmi^宏后才提供存储位置修正。_insigma_align函数提供的修正方法是若abID数组的大小为奇数的话,就在此数值上加1,使其与长字或字的边界对齐。修改后的ILGetSize函数和ILGetNext函数如下UINTWINAPIILGetSize(LPCITEMIDLISTpidl){LPCSHITEMIDsi=&(pidl->mkid);UINTIen=O;if(pidl){while(si->cb){#ifdef—Insigma一Ien+二—insigma—align(si_>cb);si=(LPCSHITEMID)(((constBYTE*)si)+—insigma—align(si->cb));#elseIen+二si_>cb;si=(LPCSHITEMID)(((constBYTE*)si)+si->cb);#endif}Ien+=2;}TRACE(〃pidl=%psize=%u\n〃’pidl,len);returnlen;LPITEMIDLISTWINAPIILGetNext(LPCITEMIDLISTpidl){WORDlen;TRACE(〃%p\n〃,pidl);if(pidl){#ifdef—Insigma—Ien=—insigma—align(pidl->mkid.cb);#elseIen=pidl->mkid.cb;#endifif(Ien){pidl=(LPCITEMIDLIST)(((constBYTE*)pidl)+len);TRACE(〃--%p\n〃,pidl);return(LPITEMIDLIST)pidl;}}returnNULL;}以上两个函数在计算aiITEMID数据结构大小时根据是否定义了Jnsigma一宏来决定是否调用—insigma_align函数获得修正后的SHITEMID数据结构大小或下一SHITEMID数据结构的起始地址。权利要求1.将Wine从X86移植到ARM平台的方法,其特征是1.1、改写x86汇编代码为ARM汇编代码;1.2、增加ARM的CONTEXT数据结构,表示ARM处理器上的寄存器上下文;1.3、增加对ARM架构可执行映像PE文件头CPU架构签名的支持,使Wine能识别ARM可执行映像;1.4、对ITEMIDLIST数据结构的存储位置进行修正,保证其内存地址是与长字或字的边界对齐的。2.根据权利要求1所述的方法,其特征在于,改写x86汇编代码为ARM汇编代码的方法为2.1、将x86汇编指令的指令逐条改写为对应的ARM汇编指令,并将操作数改为ARM的寄存器;2.2、对于不存在对应ARM汇编指令的x86汇编指令,使用多条ARM汇编指令以实现与对应x86汇编指令相同的功能。3.根据权利要求2所述的方法,其特征在于,需要改写的汇编代码包括=Ioader/preloader,c中的所有汇编代码;libs/wine/port.c中的winecallonstack函数;libs/wine/port,c中的wineswitchtostack函数。4.根据权利要求1所述的方法,其特征在于,增加ARM架构可执行映像PE文件头CPU架构签名的支持方法具体为增加对文件头中ARM架构签名的判断,允许ARM架构可执行映像被装载执行。5.根据权利要求1所述的方法,其特征在于,对ITEMIDLIST数据结构的存储位置进行修正,若ITEMIDLIST数据结构的大小为奇数,则计算地址时在原来的地址上加1,使得数据结构的地址总是偶数对齐的。全文摘要本发明公开了一种将Wine从x86移植到ARM平台的方法。Wine能够在其他操作系统中模拟Windows应用的执行环境,从而可在其他操作系统中直接运行Windows二进制程序。本发明提出的方法包括以下步骤1)将x86汇编代码改写为ARM汇编代码;2)增加ARM的CONTEXT数据结构表示ARM上的寄存器上下文;3)增加对ARM可执行映像中CPU架构签名支持;4)修正ITEMIDLIST数据结构存储位置,保证内存地址对齐。本发明使得Wine能够在使用ARM平台的系统如大量的嵌入式系统上运行,让大量Windows程序在各种嵌入式平台上能直接运行,从而降低各种已有应用的部署成本。文档编号G06F9/445GK102364442SQ20111017390公开日2012年2月29日申请日期2011年6月24日优先权日2011年6月24日发明者俞立呈,徐鼎鼎,毛德操,王承志,陈天洲申请人:浙大网新科技股份有限公司