本系列文章主要介绍了SkyEye硬件模拟平台的实现细节。主要内容包括SkyEye的总体设计、SkyEye的可扩展框架、SkyEye的关键数据结构、SkyEye对各种CPU的模拟实现、SkyEye对各种外设的模拟实现、如何安装使用SkyEye以及如何扩展SkyEye的仿真模块等。对SkyEye的深入了解,有助于对嵌入式硬件系统有更深入的认识,特别是对操作系统、驱动程序如何与嵌入式硬件系统进行交互有更深刻的了解。
1.1.1 SkyEye的CPU和开发板模拟实现
1. CPU总体模拟实现
CPU是计算机硬件的核心,目前的SkyEye模拟的是基于ARM CPU内核的CPU体系结构(将来会扩展到非ARM体系结构的其它CPU)。虽然存在数量众多的基于ARM内核的CPU,但这些CPU的核心基本上是相同的,大部分基于ARM v3-v5体系结构,并加以扩展。从硬件实现上,ARM CPU内核已经发展到第五代,芯片设计也越来越复杂,但由于SkyEye的模拟级别是指令级的,所以在设计上可以从软件实现角度进行各种模拟优化和简化。
操作系统的任务是提供一个环境,使得上层的应用程序不用与底层的硬件直接打交道,且多个应用程序之间可以共同执行,共享硬件资源。实际上,操作系统是建立在硬件上的一个虚拟机环境,而应用程序是建立在操作系统之上的程序,这个程序感觉好像它独占了整个硬件资源,而这实际上是操作系统给应用程序提供的一个假象,就象电影"Matrix"中描述的那个虚幻的繁华世界一样。而SkyEye的任务就是让操作系统感觉在一个真实的硬件环境中运行,这是一个更低层次的虚拟机环境,操作系统"看到"的所有硬件都是SkyEye虚拟出来的。
为了达到这个目标,首先需要分析操作系统可以看到什么硬件。从操作系统的角度看,操作系统可以访问到的ARM CPU内核硬件部分包括通用寄存器(R0-R15)、程序状态寄存器(CPSR和SPSR)、基于ARM内核的特定CPU的IO寄存器等、基于ARM内核的特定CPU的协处理器等。如果需要深入了解ARM的体系结构,建议参考Steve Furber编写的《ARM System-on-Chip Architecture》和ARM公司编写的《ARM Architecture Reference Manual》。
为了能够支持ARM v1-v5的体系结构模拟,我们在设计CPU模拟时,必须完成如下工作:
如果完成了这四部分工作,ARM CPU核心的模拟工作基本就算完成了。
2. 三级流水线模拟实现
三级流水线的ARM体系结构的主要的组成包括:
三级流水线的硬件逻辑描述如下:
1. 取指令:即从存储器中取出指令,放入指令流水线。对应于SkyEye的实现是根据pc值取对应的存储器内容到instr变量中;
2. 指令译码:指令被译码,占用译码逻辑,并为下一周期准备数据通路的控制信号。SkyEye没有具体的对应实现,只是把译码阶段的指令保存在一个变量中。
3. 指令执行:根据译码的情况,执行具体的指令控制逻辑,即指令占用数据通路,读取相关的寄存器,完成数据处理操作、地址转移操作或执行存储器数据访问操作等。
前两部分在armemu.c的函数ARMul_Emulate32/26中的前一小部分实现,第三部分在armemu.c的函数ARMul_Emulate32/26中的后大半部分实现。
3. 异常处理模拟实现
异常是指在程序运行时发生的异步意外事件,如外设产生中断,硬件故障等,在逻辑上它发生在指令执行中。对应ARM和其它一些CPU体系结构而言,异常也包括软件产生的中断(如除零操作)和未定义指令陷阱等,而这些是同步事件,在逻辑上它发生在指令执行前。
ARM体系结构的异常分为三类:
当异常发生时,ARM CPU内核尽量完成当前指令,然后改变当前的程序计数寄存器R15的值,使其指向异常向量地址。间接异常和外设引起的异常将打乱流水线的正常处理过程。如果发生异常,ARM CPU将执行如下操作:
1. CPU进入与特定异常相对应的CPU操作模式;
2. 将引起异常指令的下一条指令的地址保存到新模式的R14寄存器中;
3. 将原模式中的CPSR保存到新模式的SPSR中;
4. 如果是IRQ异常,则设置CPSR的第七位来禁止IRQ;如果是FIQ,则除了禁止IRQ,还要进一步设置CPSR的第六位来禁止FIQ;
5. 根据异常的种类,把R15寄存器设置为相对应的异常向量地址,并执行对应的指令。
上述的处理过程在arminit.c的ARMul_Abort函数中和armemu.c的ARMul_Emulate32/26函数中的一部分实现。而与具体指令的执行相关的部分可直接参考armemu.c的ARMul_Emulate32/26函数后半部分实现的源码,这是整个函数的主体。
4. 协处理器模拟
ARM基本核心的功能并不能满足各种各样的应用需求(如浮点处理、信号处理等),所以为了能够提高ARM体系结构的扩展性,ARM通过增加硬件协处理器和协处理器接口在支持指令集扩展,也可以通过未定义指令异常来实现软件扩展指令模拟(这样性能差很多)。最常用的ARM协处理器是控制MMU/CACHE等的系统协处理器,如ARM720T的MMU/CACHE管理单元。
ARM的协处理器体系结构支持16个协处理器,每个协处理器可以有16个寄存器(位数不定),协处理器使用类RISC的Load/Store体系结构,主要有以下几类指令:
实际协处理器的硬件实现还要考虑协处理器的接口实现技术(即如果与ARM CPU核心进行通信)。SkyEye实现的协处理器模拟比较简单,与协处理器模拟的关键数据保存在ARMul_State的如下域中:
协处理器的模拟处理主要有如下几个部分:
XScale体系结构的CPU存在第13号和第14号协处理器,且ARM Linux对它们也有逻辑控制,所以在文件xscale_copro.c的函数xscale_cp13/14/15_*完成了对应的协处理器指令的硬件逻辑模拟。
通过上述的协处理器模拟实现,SkyEye能够完成ARM Linux for ep7312/SA1100/PXA25x等内核执行的协处理器指令,保证内核能够正常运行。
5. I/O硬件模拟
由于大部分基于ARM内核的各种CPU和开发板都有自己的扩展,而且一般各不相同。由于这一部分与硬件系统的I/O有很大的关系,因此SkyEye建立了一个I/O抽象层,把这一部分独立出来,然后建立各个特定CPU和开发板的I/O处理模拟实现,这样最大程度地减少了代码冗余,同时结构和模块化更清晰,这也有利于开发者在此基础上开发其它类型的CPU和开发板。SkyEye的I/O抽象层的实现在armio.c文件中,而与特定硬件相关的实现则分别在如下文件中:
实际上,SkyEye如果实现clock的I/O模拟,再加上内存模拟(mem_bank的起始地址和大小由配置文件skyeye.conf定义),则可以运行支持分时操作的最基本操作系统(如μC/OS-II等)了。而为了能够支持字符的输入输出,则还需要进一步实现UART模拟。所以支持clock和UART两部分的模拟是SkyEye能够运行一个比较实际的操作系统的最基本要求。下面分别对主要几个特定CPU和开发板的模拟进行介绍。
6. 基于AT91X40的开发板
AT91X40为ATMEL公司基于ARM7TDMI核的32位CPU,其核心为高性能的32位RISC体系结构,并具有高密度的16位指令集和极低的功耗。AT91X40系列微控制器内部有一个8优先级、可单独屏蔽的向量中断控制器,称为先进中断控制器AIC(Advanced Interrupt Controller)。AT91X40系列微控制器集成了两个完全相同的全双工通用同步/异步收发器(USART)。Time Clock共有3个通道,有16位定时器/计数器,支持捕获和波形模式。每个TC都可以测量或产生不同的波形,并可以检测及控制两个I/O信号。TC还有3个外部时钟信号。这些外设都可以通过相关的I/O寄存器进行设置和访问。
μClinux包含对基于AT91X40的开发板的BSP(Board Support Package),通过分析AT91X40体系结构和μClinux内核源码,SkyEye只需保存如下数据结构描述的寄存器、内部数据(这些寄存器的值和内部数据可能被操作系统或硬件改变)和一些只读寄存器就基本可以支持μClinux内核和基本命令行用户界面以及相关应用程序。查看at91_io_read/write_byte/halfword/word函数的实现可以看到所有操作系统需要访问的寄存器。
|
下面的的字符串数组描述的是与UART相关的I/O寄存器的简称,它们会被μClinux访问。
|
由于LCD模拟实现还在开发中,目前与LCD模拟实现相关的lcdcon和lcd_limit还没有用到。下面对一些关键的I/O模拟函数进行介绍:
这样SkyEye就可以很好地模拟基于AT91X40的开发板,而且μClinux针对真实基于AT91X40的开发板的内核和文件系统可以很好地在SkyEye上运行。
7. 基于ep7312的开发板
ep7312为Cirrus Logic公司基于ARM720T核的32位CPU,其核心为高性能的32位RISC体系结构,并具有高密度的16位指令集和极低的功耗,支持MMU/CACHE。ARM720核实际上是ARM7TDMI核加上一个8KB的数据和指令混合的CACHE,外部存储器和外围硬件通过AMBA总线主控单元访问,它还集成了MMU、写缓冲器(write buffer)、LCD控制器、中断控制器等。
ARM Linux包含对基于ep7312的开发板的BSP(Board Support Package)。通过分析ep7312体系结构和ARM Linux内核源码,SkyEye只需保存如下数据结构描述的寄存器、内部数据(这些寄存器和内部数据的值可能被操作系统或硬件改变)和一些只读寄存器就基本可以支持ARM Linux内核和基本命令行用户界面和相关应用程序。查看ep7312_io_read/write_byte/halfword/word函数的实现可以看到所有操作系统需要访问的寄存器。与MMU/CACHE相关的模拟实现可参考"SkyEye的MMU/CACHE和Memory模拟实现"一节。
|
细心的读者可能注意到这里的结构与at91_io_t数据结构是一样的。其实它们在中断处理和UART处理上有所不同,但在时钟处理上很类似。有关LCD的模拟实现可参考"SkyEye的LCD模拟实现"。下面对一些关键的I/O模拟函数进行介绍:
加上MMU/CACHE和内存模拟,SkyEye就可以很好地模拟基于ep7312的开发板,而且ARM Linux针对真实基于ep7312的开发板的内核和文件系统可以很好地在SkyEye上运行。
8. 基于StrongARM的开发板
目前基于StrongARM CPU核的CPU有SA-110、SA1100和SA1110。StrongARM CPU核是基于ARM v4 体系结构,并进行了大量的扩展,采用了独立的指令MMU/CACHE和数据MMU/CACHE,并增加了read buffer和write buffer。StrongARM体系结构的SA-1100/1110还包括LCD控制器、系统控制单元、DMA控制器、UART串口单元、定时器、实时时钟、中断控制器、电源管理控制器和28个通用I/O引脚等。用SA-1100组成的系统在PCB这一层次会比较简单,且功能强大。虽然目前Intel公司已经停止了对StrongARM结构的开发,但基于StrongARM体系结构的PDA曾经称雄一时,与Palm公司的PDA系列成两足鼎立之势。而且,理解StrongARM体系结构会有助于了解Intel公司新的XScale体系结构,二者有很多相近之处。
ARM Linux包含对基于StrongARM的开发板的BSP(Board Support Package)。通过分析基于StrongARM体系结构的SA1100内部细节和ARM Linux内核源码,SkyEye只需保存如下数据结构描述的寄存器、内部数据(这些寄存器和内部数据的值可能被操作系统或硬件改变)和一些只读寄存器就基本可以支持ARM Linux内核和基本命令行用户界面以及相关应用程序。查看ep7312_io_read/write_byte/halfword/word函数的实现可以看到所有操作系统需要访问的寄存器。与MMU/CACHE相关的模拟实现可参考错误!未找到引用源节。
|
在上述结构中,包括四部分的I/O寄存器组:与中断控制相关的寄存器、与实时时钟控制相关的寄存器、与OS timer相关的寄存器和与UART 3(UART0-2在内核中没有使用,这里就没有模拟了)相关的寄存器。下面对一些关键的I/O模拟函数进行介绍:
加上MMU/CACHE和内存模拟,SkyEye就可以很好地模拟基于StrongARM的开发板,而且ARM Linux针对真实基于StrongARM的adsbitsy开发板的内核和文件系统可以很好地在SkyEye上运行。
9. 基于XScale的Lubbock开发板
支持XScale体系结构CPU的开发板目前已有数款,如代号为lubbock、 cerf、 idp等的开发板,这里分析的开发板是Intel推出的代号为Lubbock的经典开发板,它目前支持PXA25x系列CPU,有64MBytes SDRAM、32MBytes Boot ROM、32MBytes Flash ROM、USB插槽、PCMICA插槽、CF卡插槽、带有640x480的LCD显示器,可以称之为一个小型的全功能计算机。
ARM Linux对XScale体系结构的支持已经放到Linux-2.6.x内核中,目前由R.King维护,且已经支持多款基于XScale体系结构的开发板,而lubbock开发板是ARM Linux最早支持且支持得很全面的开发板之一。通过分析基于XScale体系结构的PXA250内部细节和ARM Linux内核源码,SkyEye只需保存如下数据结构描述的寄存器、内部数据(这些寄存器和内部数据的值可能被操作系统或硬件改变)和一些只读寄存器就基本可以支持ARM Linux内核和基本命令行用户界面以及相关应用程序。查看pxa_io_read/write_byte/halfword/word函数的实现可以看到所有操作系统需要访问的寄存器。与MMU/CACHE相关的模拟实现可参考"SkyEye的MMU/CACHE和Memory模拟实现"一节。
|
下面对一些关键的I/O模拟函数进行介绍:
加上MMU/CACHE和内存模拟,SkyEye就可以很好地模拟基于XScale体系结构的开发板,而且ARM Linux针对真实基于XScale体系结构的lubbock开发板的内核和文件系统可以很好地在SkyEye上运行。