SkyEye支持网络模拟,目前描述网络配置的数据结构是net_config_t,它的具体内容如下:
typedef struct { int state; unsigned char macaddr[6]; unsigned char hostip[4]; int ethmod; int fd; int hubindex; int (*net_init)(int index, unsigned char *macaddr, unsigned char *hostip); unsigned char (*net_output)(int if_fd, ARMul_State *state,\ unsigned char startpage,unsigned short packet_len); void (*net_input)(int if_fd, ARMul_State *state); }net_config_t;
其中各个field的含义描述如下: ●state:是一个布尔变量,为1表示网络芯片工作,为0表示网络芯片不工作 ●macaddr:用来保存网络芯片的mac地址 ●hostip:用来保存主机上与SkyEye进行网络通信所用的IP地址
●ethmod:表示与主机的模拟网络交互的方式,目前定义的交互方式有: #define NET_MOD_LINUX 0 #define NET_MOD_TUNTAP 1 #define NET_MOD_WIN 2 #define NET_MOD_VNET 3 目前可以使用的两种方式有 NET_MOD_VNET(与SkyEye提供的vnet.o内核模块进行网络交互)和 NET_MOD_TUNTAP(与linux的tun.on内核模块进行网络交互)。 ●fd:表示SkyEye用于与主机进行网络交互的设备文件描述符 ●hubindex:用于NET_MOD_VNET方式,表示所处的是第几个虚拟hub网段。如果它的值是i,则处于第i个hub网段中。 ●net_init/net_input/net_output:这三个函数与具体的模拟网络交互方式有关,分别完成初始化操作和与主机网络的输入输出操作。相关的实现在文件skyeye_net_*.c中。 有关8019AS模拟芯片(NE2000兼容)的具体配置与实现位于文件skyeye-ne2k.[ch]中。
6、ARMul_State数据结构: 上面讲述的是与SkyEye的硬件配置相关的数据结构,可以理解为一种静态硬件配置的数据结构,这些数据结构中的域基本不随着SkyEye模拟硬件的运行而改变。而ARMul_State描述的是一种动态硬件配置的数据结构,它保存了随着SkyEye模拟硬件的运行而时刻改变的硬件数据。
ARMul_State中的域数量繁多,大体分为: 与CPU模拟相关的域、与协处理器模拟相关的域、与内存和MMU/CACHE相关的域 、与统计相关的域、与具体开发板相关的io部分。
这里只描述其中关键的部分: ●与CPU模拟相关的域 : ARMword Reg[16]:CPU当前模式下的寄存器值 ARMword RegBank[7][16]:CPU所有七种模式下的寄存器值 ARMword Cpsr:CPU的当前程序状态寄存器 ARMword Spsr[7]:CPU所有七种模式下的程序状态保存寄存器 ARMdword Accumulator:40bit的累加寄存器,目前用于xscale体系结构中 ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags, Sflag,TFlag:各种状态位 ARMword Bank:CPU对应模式寄存器组的索引值 ARMword Mode:CPU模式索引值 ARMword instr, pc:pc是目前正在执行的程序指针,instr是pc所指地址的内容 ARMword loaded, decoded:loaded是正在加载的指令,decoded是正在解码的指令 unsigned NfiqSig:FIQ信号 unsigned NirqSig:IRQ信号
● 与协处理器模拟相关的域: ARMul_CPInits *CPInit[16]:16个协处理器的初始化函数 ARMul_CPExits *CPExit[16]:16个协处理器的退出函数 ARMul_LDCs *LDC[16]:16个协处理器的LDC指令函数 ARMul_STCs *STC[16]:16个协处理器的STC指令函数 ARMul_MRCs *MRC[16]:16个协处理器的MRC指令函数 ARMul_MCRs *MCR[16]:16个协处理器的MCR指令函数 ARMul_CDPs *CDP[16]:16个协处理器的CDP指令函数 ARMul_CPReads *CPRead[16]:16个协处理器的读CP寄存器函数 ARMul_CPWrites *CPWrite[16]:16个协处理器的写CP寄存器函数 unsigned char *CPData[16]:16个协处理器的数据指针 ARMword CP14R0_CCD:在xscale体系结构的CP14协处理器中,用于统计时钟周期
●与内存和MMU/CACHE相关的域: mmu_state_t mmu:mmu/cache的数据结构,在armmmu.h中定义,详解请参考"SkyEye的MMU/CACHE和Memory模拟实现"一节 mem_state_t mem:memory的数据结构,在armmem.h中定义,详解请参考"SkyEye的MMU/CACHE和Memory模拟实现"一节 与统计相关的域 unsigned long NumScycles, NumNcycles, NumIcycles, NumCcycles, NumFcycles:用于统计不同状态下的周期数 unsigned long NumInstrs:当前执行的指令数 其它与特定CPU和开发板相关的各种io寄存器的定义放到了各个与开发板相关的文件中,如skyeye_mach_at91/ep7312/pxa/sa.c等处,详解请参考"SkyEye的开发板IO模拟实现"。
●与具体开发板相关的io部分: ARMul_io mach_io; 其中ARMul_io的结构目前为
struct ARMul_io { ARMword *instr; //to display the current interrupt state ARMword *net_flag;//to judge if network is enabled ARMword *net_int; //netcard interrupt
ARMword *lcd_is_enable; //turn lcd on? ARMword *lcd_addr_begin; //the begining display mem addr of lcd ARMword *lcd_addr_end; //the end display mem addr of lcd };
instr:是记录当前的中断状态 net_flag:判断网络选项是否打开 net_int:用来记录网络中断号 lcd_is_enable:来记录LCD是否使能 lcd_addr_begin:记录lcd显存的起始位置 lcd_addr_end:记录显存的结束位置
7、SkyEye逻辑执行流程: 了解SkEye的总体逻辑执行流程,对了解硬件的体系结构和软件/硬件的接口有较大帮助。从总体上,可把SkyEye逻辑执行流程按执行的时间顺序划分为两个阶段: 1、SkyEye加载与配置处理过程 2、SkyEye模拟执行过程
第一阶段为第二阶段的正常执行做了充分的准备,具体的执行内容包括: ●读入带调试信息的操作系统执行文件(由GDB完成) ●根据配置文件skyeye.conf的信息配置模拟硬件 ●如果skyeye.conf中存在binary image格式文件,加载这些文件 ●根据操作系统执行文件的内容加载调试信息(由GDB完成) ●根据操作系统执行文件信息加载执行文件中的代码段和数据段等(由GDB完成) ●执行相关模拟硬件的初始化函数 其中总的初始化函数是位于wrapper.c中的init函数,它调用如下函数完成整个模拟硬件的初始化工作:
ARMul_EmulateInit:初始化与执行机器指令相关的数据ARMul_ImmedTable和ARMul_BitList ARMul_NewState:初始化结构为ARMul_State的全局变量state skyeye_option_init:初始化全局变量skyeye_config skyeye_read_config:读取配置文件skyeye.conf并根据配置文件进行相关配置 nic_init:根据配置文件信息配置网络模拟环境 skyeye_config.mach->mach_init(state, skyeye_config.mach):根据配置文件信息配置CPU和开发板的相关I/O函数 ARMul_Reset(state):进一步初始化全局变量state,并根据配置文件信息配置MMU/CACHE和memory io_reset:初始化特定CPU和开发板的IO寄存器
第二阶段根据特定硬件的配置描述,开始执行特定硬件模拟处理。整个过程围绕CPU执行指令展开,根据模拟硬件可分为如下几个阶段:
●CPU执行三级流水线处理,即取指令、译码、执行指令,主要处理集中在armemu.c中的ARMul_Emulate32/26函数。 ●在执行指令过程中,如果有中断产生,CPU调整运行模式,并改变指令指向中断向量起始地址,主要处理集中在arminit.c中的函数ARMul_Abort函数、armemu.c中的ARMul_Emulate32/26函数。 ●在执行指令过程中,如果指令是协处理器指令,则把指令转交给协处理器模拟模块进行进一步处理,主要处理集中在文件armcopro.c、xscale_copro.c等文件中。 ●在执行指令过程中,如果发现指令是访问内存/IO的指令,则根据SkyEye模拟的特定CPU是否有MMU/CACHE分别进行处理: 如果CPU有MMU/CACHE,则进入MMU/CACHE模拟模块,如果还需要内存访问,则进入memory模拟模块处理。如果访问地址属于IO地址空间,则转到特定CPU和开发板的IO模拟模块处理。 如果CPU没有MMU/CACHE,则直接进入memory模拟模块处理。如果访问地址属于IO地址空间,则转到特定CPU和开发板的IO模拟模块处理。 处理访问内存/IO的指令的相关内容集中在armvirt.c;与MMU/CACHE处理、read/write buffer(用于StrongARM和XScale体系结构的模拟)处理相关的文件包括armmmu.[ch]、mmu/*.[ch];与访问memory模拟有关的内容主要集中在armmem.[ch]中。 如果要执行IO地址访问,这具体的处理过程由特定CPU和开发板IO模拟模块中的read/write_byte/halfword/word函数处理。 为了模拟外设的执行,在执行指令过程的每一个周期,会执行一个io_do_cycle函数,它会调用特定CPU和开发板的IO模拟模块中的*_io_do_cycle函数,完成对时钟、网络输入输出、UART输入输出等的处理,并根据条件产生中断信号。
|