原创 ARM平台上实现NDS模拟器(虚拟机)

2011-5-3 10:03 3426 4 4 分类: MCU/ 嵌入式

1. 关于NES,GBA,NDS

1.1 NES是Nintendo在80年代开发的一款家用游戏机,配置基于6502内核的CPU和2D图形加速器,著名的游戏有超级马里奥,魂斗罗等.

1.2 GBA是Nintendo在2001上市的手持式游戏机,配置基于ARM7内核的CPU和2D图形加速器.

1.3 NDS于2004年面市,其CPU包含一个ARM7内核和一个ARM9内核,配置有2D和3D图形加速器.

 

2. NES,GBA模拟器的实现方法

在32位嵌入式平台上,现在有NES模拟器和GBA模拟器,其实现的技术方法分别为指令解释和动态指令翻译.

NES模拟器一般由指令解释的方法实现,模拟器程序每读一条指令,调用相应的过程来实现其功能,在X86+Windows平台是,几乎所有的模拟器都是这种方式.

GBA模拟器用指令解释的方式来实现可能速度不够快,几年前Exophase在PSP平台上编写的模拟器gPSP,采用了动态指令翻译的方式. PSP的CPU是MIPS,gPSP将GBA程序里的ARM指令翻译成MIPS指令运行,每次翻译一段代码,而不是逐条解释.

在ARM平台上实现NDS模拟器,一个比较可行的方法是虚拟机.

 

3. 关于虚拟机

对于Linux开发人员来说,如果操作系统是Windows,搭建开发环境可基于Cygwin或VMWare,VMWare是一款虚拟机软件,提供虚拟的X86硬件环境,在上面既可以运行Windows,也可以运行Linux.电脑启动后运行的Window系统称为Host系统,运行在虚拟机里的Linux或Windows称为Guest系统.

 

4. NDS虚拟机

4.1 ARM平台虚拟机

实现虚拟机,需要有一套机制,使得CPU的控制权可以在Guest(NDS程序)和Host(虚拟机程序)之间切换,Intel和AMD在X86架构的CPU上,提供了相应的功能,使得这种切换可由硬件实现,另外还提供了嵌套式的页表支持.

在ARM架构上,目前没有这种功能,相应的切换须由软件方式来实现,而且需要对Guest的二进制代码进行修改,这也可称为动态指令翻译,但不是翻译所有的指令,而是某些特定的指令.

4.2 Guest程序的运行模式

ARM CPU从复位状态开始运行时,CPU模式是supervisor mode,Host系统引导Guest系统运行时,需要将CPU模式设置为user mode.

4.3 CPU控制权的切换.

guest程序运行起来后,执行到特定的指令时,需要将CPU控制权交给host.这些特定指令包括在user mode下结果未知的指令和非法的指令,对协处理器访问的指令等.对于非法指令,CPU会产生未定义指令异常,从而退出当前guest程序的运行,而某些指令如MRS,MSR,ADDS等,则需要在guest运行前修改,修改成SWI, 模拟器程序在SWI处理程序里模拟相应的功能.

4.4 双内核的模拟

建立通过两个线程,来分别运行ARM7和ARM9程序.ARM9和ARM7会访问的虚拟地址相同而物理地址不同的内存空间,所以在切换这连个线程时,需要对这部分进行重新映射.

5. 实验过程

硬件环境: Freescale i.MX51 开发板

软件环境: Redboot.  选择Redboot的原因是Freescale 提供的Redboot代码里包含LCD显示驱动.

第一步先编写线程调度程序,不采用eCos的调度程序,希望使用起来更加灵活.

接下来整理出哪些指令需要翻译,编写动态翻译代码,将NDS程序读入内存后,程序首先搜索这些指令,并重新编码成SWI..

NDS的外设I/O寄存器区域是04XXXXXX,配置MMU的时候,host程序对这部分地址不做映射,当NDS程序访问这部分地址时,CPU产生data abort异常,host在异常处理程序里对NDS的外设进行模拟.

NDS的ARM7和ARM9内核通过IPC模块来进行同步和通信,通过分析NDS程序运行,发现NDS程序还通过某些信号量来进行同步.在NDS程序访问同步寄存器的时候,进程调度程序需要在ARM9和ARM7之间灵活切换.

在经历了一段时间的编码和调试后,某些游戏可以在这套虚拟环境上运行起来,在LCD屏上可以看到游戏画面.

后续还需要完成的工作,包含模拟性能提升,线程调度和异常处理效率的评估,3D加速器的模拟等等.

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /1 下一条