級別: 初級
陳渝
(yuchen@tsinghua.edu.cn)清華大學
2004 年 10 月 01 日
?
前兩篇文章分別介紹了 SkyEye 項目及其安裝,下面的幾篇文章將對其設計實現(xiàn)展開討論。
一. SkyEye的總體結構
SkyEye基于GDB/ARMulator(目前由David McCullough 維護),并進行了全面的改變和擴展。SkyEye建立在GNU GDB的底層,可以模仿多種完整的嵌入式計算機系統(tǒng),目前模擬的硬件包括CPU、內存、I/O寄存器、時鐘、UART、網絡芯片、MMU、CACHE,將來還會模擬 LCD、USB等各種硬件。在SkyEye上運行的操作系統(tǒng)和各種系統(tǒng)軟件"意識"不到它們是在一個虛擬的計算機系統(tǒng)上運行。
SkyEye從總體上分為四個層次:
- 用戶接口模塊:包括命令行用戶界面和圖形用戶界面,完成處理用戶的輸入命令,并把相關調試數(shù)據(jù)輸出給用戶的任務。這一部分基本上直接利用了GDB的用戶接口模塊,并在此基礎上有一定的擴充。
- 符號處理模塊:主要處理執(zhí)行文件的頭信息,解釋執(zhí)行文件中內嵌的debuger調試信息,對符號表的管理,對源代碼表達式的解析,定位源代碼中的語句位置和機器碼的位置關系等。這一部分也是直接利用了GDB的符號處理模塊,也正是有了這個模塊的支持,SkyEye可以支持源碼級調試。
- 目標控制模塊:主要完成執(zhí)行控制(如中斷程序的執(zhí)行,設置中斷條件等),程序棧結構分析,對具體目標硬件的控制(如本地調試、遠程調試和模擬調試的控制)。這一部分完成對SkyEye上運行的軟件的控制,提供了多種調試手段。
- 目標模擬模塊:這一部分是SkyEye的核心。它的功能是模仿計算機系統(tǒng)中的主要硬件(包括CPU、內存和各種硬件外設等)的執(zhí)行,對執(zhí)行文件的機器指令進行解釋,并模擬執(zhí)行每一條機器指令,產生相應的硬件響應等。
二. SkyEye目標模擬模塊功能劃分
SkyEye目標模擬模塊模擬的硬件邏輯結構圖如圖 0 1所示。SkyEye目標模擬模塊從功能上可分為如下幾大模塊:
- 配置選項解析和初始化模塊:在模擬硬件開始運行前,根據(jù)配置文件的選項,控制對模擬硬件的配置和初始化。相關文件包括:
- arminit.c:控制各種模擬硬件的初始化
- skyeye_config.[ch]:解析配置文件的選項行
- skyeye_options.c:根據(jù)各種硬件的選項,完成各種配置
- 處理器模擬宏模塊:主要完成與處理器體系結構相關的模擬,它可細分為:CPU指令模擬執(zhí)行模塊、MMU/CACHE模擬模塊、CoProcessor(又稱協(xié)處理器)模擬模塊。
- CPU指令模擬執(zhí)行模塊:其主要任務是:當模擬硬件開始運行,完成指令讀取,指令譯碼,指令執(zhí)行的工作;如果CPU狀態(tài)發(fā)生了改變,調整指令和各種寄存器值;在指令執(zhí)行前,調用開發(fā)板IO模擬模塊的io_do_cycle驅動模擬各種外設的行為。主要的文件包括:
- armemu.[ch]:模擬CPU的3級流水線,并具體執(zhí)行各種指令
- MMU/CACHE模擬模塊:本模塊分為兩部分:與具體CPU類型無關的MMU/CACHE模擬子模塊和與具體CPU類型相關的模擬子模塊。主要的任務是:根據(jù)配置文件進行初始化;進行MMU/CACHE模擬;執(zhí)行與MMU/CACHE相關的指令。如果CPU指令模擬模塊執(zhí)行讀寫存儲器的操作指令,則轉到MMU/CACHE模擬模塊。如果模擬的CPU類型不支持MMU(如ARM7TDMI),則SkyEye會根據(jù)將訪問的地址,直接轉到MEMORY模擬模塊或開發(fā)板IO模擬模塊;否則轉到具體CPU類型相關的模擬子模塊進行MMU/CACHE模擬。主要的文件包括兩部分:
- 與具體CPU類型無關的MMU/CACHE模擬子模塊:
- armvirt.c、armmmu.c、mmu/*.[ch]
- 與具體CPU類型相關的MMU/CACHE模擬子模塊:
- sa_mmu.[ch]:模擬strongarm的MMU/CACHE
- arm7100_mmu.[ch]:模擬arm7[12]0T的MMU/CACHE
- xscale_copro.c:模擬xscale的MMU/CACHE
- arm920t_mmu.[ch]:模擬arm920t的MMU/CACHE
- CoProcessor(又稱協(xié)處理器)模擬模塊:其主要任務是:完成各種協(xié)處理器的初始化;執(zhí)行各種協(xié)處理器的指令。實際上MMU/CACHE模擬模塊的一部分工作是模擬ARM的第15號協(xié)處理器,它的主要功能是配置MMU/CACHE等。主要的文件包括:
- armcopro.c:根據(jù)配置信息,完成對ARM協(xié)處理器的初始化配置
- xscale_copro.c:模擬xscale的協(xié)處理器cp13、cp14、cp15
- sa_mmu.[ch]、arm7100_mmu.[ch]:模擬strongarm、ep7312的協(xié)處理器cp15
- arm920t_mmu.[ch]:模擬arm920t的協(xié)處理器cp13、cp14、cp15
- IO模擬宏模塊:本模塊包含各種邏輯行為各異的外設模擬,主要包括系統(tǒng)IO模擬模塊、網絡芯片模擬模塊、LCD模擬模塊等。
- 系統(tǒng)IO模擬模塊:本模塊的主要任務包括:根據(jù)配置文件進行IO和外設初始化;完成各種外部IO設備的模擬(如時鐘計數(shù)器累加、產生中斷、LCD顯示等);進行各種特定CPU和外設的IO寄存器讀寫的模擬。本模塊與各種具體的開發(fā)板和CPU有很緊密的聯(lián)系,主要的文件包括:
- armio.[ch]:建立在各個特定模擬子模塊上的抽象層模塊
- skyeye_mach_at91.c:模擬Atmel AT91X40開發(fā)板
- skyeye_mach_ep7312.c:模擬cirrus ep7312開發(fā)板
- skyeye_mach_pxa.c:模擬intel xscale lubbock開發(fā)板
- skyeye_mach_s3c4510b.c:模擬基于samsung s3c4510b的開發(fā)板
- skyeye_mach_s3c44b0.c:模擬基于samsung s3c44b0的開發(fā)板
- skyeye_mach_sa.c:模擬基于intel strongam的adsbitsy開發(fā)板
- skyeye_mach_lpc.c:模擬基于philip lpc2249的開發(fā)板
- skyeye_mach_sharp.c:模擬基于sharp lh7a400的開發(fā)板
- skyeye_mach_at91rm92.c:模擬基于atmel at91rm9200的開發(fā)板
- skyeye_mach_cs89712.c:模擬基于cs89712的開發(fā)板
- 網絡芯片模擬模塊:本模塊主要完成了對8019AS網絡芯片的模擬工作,主要任務包括:模擬8019AS的控制邏輯、8019AS與具體開發(fā)板IO模擬模塊的接口、虛擬網絡輸入輸出接口處理。主要的文件包括:
- skyeye-ne2k.[ch]:8019AS的硬件邏輯模擬
- skyeye_mach_at91.c:部分內容完成接收虛擬網絡輸入處理模擬
- skyeye_net_tuntap.c:配置tuntap虛擬網絡的接口
- skyeye_net_vnet.c:配置vnet虛擬網絡的接口
- vnet.c、if_vnet.h:獨立存在的軟件包,vnet虛擬網絡的具體實現(xiàn)
- LCD/TouchScreen模擬模塊:本模塊主要完成LCD/TouchScreen控制邏輯的模擬,是目前唯一需要GUI支持的模塊,它的主要任務是:配置LCD/TouchScreen硬件模擬、模擬LCD/TouchScreen控制邏輯。有關LCD/TouchScreen模擬相關的文件包括:
- skyeye_lcd.[ch]: LCD/TouchScreen配置和LCD/TouchScreen模擬的通用控制邏輯
- skyeye_mach_*.c:與開發(fā)板相關LCD/TouchScreen的控制邏輯和中斷處理,目前支持ep7312和pxa255的skyeye模擬。
- MEMORY模擬模塊:本模塊與具體的CPU和開發(fā)板無關,它的主要任務包括:根據(jù)配置文件進行內存初始化,并加載binary image文件;進行RAM/ROM讀寫的模擬。主要的文件包括:
- armmem.[ch]:主要完成RAM/ROM讀寫模擬
|
|
三. SkyEye關鍵數(shù)據(jù)結構
SkyEye目標模擬模塊中,各種數(shù)據(jù)結構很多,用于模擬硬件總體機構定義的主要數(shù)據(jù)結構有skyeye_config_t和ARMul_State。把握這兩個數(shù)據(jù)結構,是理解整個skyeye模擬的硬件體系結構的關鍵,在這兩個數(shù)據(jù)結構上進行進一步細化分析,則可充分了解skyeye的硬件體系結構細節(jié)。
1. skyeye_config數(shù)據(jù)結構
skyeye_config_t結構描述了SkyEye模擬的整個硬件的靜態(tài)配置,它的具體內容如下:
typedef struct {
cpu_config_t *cpu;
machine_config_t *mach;
mem_config_t mem;
net_config_t net[NET_MAXNICNUM_PER_HOST];
uart_config_t uart;
log_config_t log;
ARMword start_address;
ARMword no_lcd;
char config_file[MAX_FILE_NAME];
} skyeye_config_t;
|
skyeye_config_t結構包含了CPU核心配置信息-cpu、開發(fā)板配置信息-mach、memory map 配置信息-mem、網絡芯片和網絡環(huán)境配置信息-net、面向主機的輸入輸出配置信息-uart、測試記錄輸出配置信息-log、模擬執(zhí)行起始地址配置信息-start_address、是否有LCD-no_lcd和記錄文件名信息-config_file。這里面與模擬硬件緊密相關的是CPU核心配置信息、開發(fā)板配置信息、memory map 配置信息、網絡芯片和網絡環(huán)境、LCD配置信息。
2. cpu_config_t數(shù)據(jù)結構
描述CPU核心的結構定義在cpu_config_t數(shù)據(jù)結構中,具體內容如下:
typedef struct {
const char *cpu_arch_name;
const char *cpu_name;
ARMword cpu_val;
ARMword cpu_mask;
ARMword cachetype;
} cpu_config_t;
|
其具體描述解釋如下:
- cpu_arch_name:描述了arm cpu體系結構的名稱,根據(jù)ARM CPU內核的發(fā)展,其體系結構已經從Version1發(fā)展到了Version5,其最新版本為Version5TE。而Intel在其基礎上又進行了自己的擴展體系結構StrongARM(基于ARM version4)和XScale(基于ARM version5)。目前SkyEye支持"armv3"、"armv4"、"arm5"、"arm5TE"、"xscale"的體系結構。
- cpu_name:描述了具體的arm cpu名稱,如arm7TDMI、ARM720T、StrongARM1100/1110、XScale PXA2xx等。目前SkyEye支持"arm710"、"arm7TDMI"、"arm720t"、"sa1100"、"xscale"等。
- cpu_val:這是用來表示process id,一般而言每種具體的ARM CPU 都有一個ID,更詳細的描述可參考《ARM Architecture Reference Manual》的B2-6。操作系統(tǒng)根據(jù)這個ID來識別cpu的類型并執(zhí)行相關配置。
- cpu_mask:這是用來確定process id的屏蔽位數(shù)。由于process id中的某些位用于其它目的,并不用來表示具體的CPU類型。實際上操作系統(tǒng)在確定CPU類型時用到的數(shù)字是cpu_val&cpu_mask。
- cache_type:基于ARM內核的CPU種類繁多,但如果根據(jù)CACHE類型來分,可分為三種:無CACHE類型、統(tǒng)一結構CACHE類型和哈佛結構CACHE類型。SkyEye支持這三種類型。統(tǒng)一結構CACHE類型的CPU中,指令和數(shù)據(jù)共用同一個CACHE;而哈佛結構CACHE類型的CPU中,存在相互獨立的數(shù)據(jù)CACHE和指令CACHE。無CACHE的CPU尺寸比有CACHE的CPU尺寸要小很多,成本上有優(yōu)勢,但在性能上要低于有CACHE的CPU。
SkyEye定義了一個cpu_config_t結構的數(shù)組(位于skyeye_option.c中),結構如下:
cpu_config_t arm_cpu[] = {
{"armv3", "arm710", 0x41007100, 0xfff8ff00, DATACACHE},
{"armv3", "arm7tdmi", 0x41007700, 0xfff8ff00, NONCACHE},
{"armv4", "arm720t", 0x41807200, 0xffffff00, DATACACHE},
{"armv4", "sa1110", 0x6901b110, 0xfffffff0, INSTCACHE},
{"armv4", "sa1100", 0x4401a100, 0xffffffe0, INSTCACHE},
{"xscale", "xscale", 0x69052100, 0xfffffff0, INSTCACHE}
};
|
3. machine_config_t數(shù)據(jù)結構
machine_config_t結構描述了開發(fā)板配置信息,定義在skyeye_config.h中,具體內容如下:
typedef struct machine_config{
const char *machine_name;
void (*mach_init)(ARMul_State *state,\
struct machine_config *this_mach);
void (*mach_io_do_cycle)(ARMul_State *state);
void (*mach_io_reset)(ARMul_State *state);
void (*mach_update_int)(ARMul_State *state);
ARMword (*mach_io_read_byte)(ARMul_State *state, ARMword addr);
void (*mach_io_write_byte)(ARMul_State *state, ARMword addr,\
ARMword data);
ARMword (*mach_io_read_halfword)(ARMul_State *state, \
ARMword addr);
void (*mach_io_write_halfword)(ARMul_State *state, ARMword addr,\
ARMword data);
ARMword (*mach_io_read_word)(ARMul_State *state, ARMword addr);
void (*mach_io_write_word)(ARMul_State *state, ARMword addr,\
ARMword data);} machine_config_t;
}machine_config_t
|
其具體描述解釋如下:
- machine_name:開發(fā)板的名稱。目前支持的開發(fā)板有:atmel的基于AT91X40 CPU的開發(fā)板、基于Cirrus Logic ep7312的開發(fā)板、基于Intel StrongARM的adsbitsy開發(fā)板、基于Intel XScale PXA25x的Lubbock開發(fā)板等。
- mach_init:開發(fā)板初始化配置函數(shù),主要初始化一些與開發(fā)板相關的變量和配置mach_io_do_cycyle、mach_io_read/write_byte/halfword/word函數(shù)。mach_init函數(shù)被wrappe.c中的init函數(shù)調用。
- mach_io_reset:開發(fā)板運行初始化函數(shù)。主要初始化與開發(fā)板相關的變量。
- mach_update_int :定義了與開發(fā)板相關的中斷處理函數(shù)。
- mach_io_read/write_*:分別定義與開發(fā)板相關的I/O函數(shù)。
SkyEye定義了一個machine_config_t結構的數(shù)組(位于skyeye_option.c中),結構如下:
machine_config_t arm_machines[] = {
{"at91", at91_mach_init, NULL, ......},
{"ep7312", ep7312_mach_init, NULL, ......},
{"s3c4510b", s3c4510b_mach_init, NULL, ......},
{"s3c44b0", s3c44b0_mach_init, NULL, ......},
{"sa1100", sa1100_mach_init, NULL, ......},
{"pxa_lubbock", pxa_mach_init, NULL, ......} ……
};
|
4. mem_config_t和mem_bank_t數(shù)據(jù)結構
SkyEye的內存映射配置結構由mem_config_t和mem_bank_t數(shù)據(jù)結構描述。ARM體系結構與x86體系結構在I/O內存映射上有所不同。X86體系結構可以使用I/O端口來映射外部設備上的寄存器和設備內存;而ARM體系結構是通過標準的memory地址空間來映射外設的寄存器或設備內存,而且在通常情況下,I/O地址空間不會通過CACHE進行緩存。目前SkyEye支持三種類型的內存映射:ROM SPACE(只讀)、RAM SPACE(可讀寫)、IO SPACE(可讀寫,與特定開發(fā)板相關)。SkyEye對這三種類型的內存映射的處理是不同的。在SkyEye中把一段連續(xù)的地址空間稱為一個mem_bank,多個mem_bank之間不一定連續(xù)。mem_config_t數(shù)據(jù)結構的具體內容如下:
typedef struct {
int bank_num;
int current_num;
mem_bank_t mem_banks[MAX_BANK];
} mem_config_t;
|
其中 bank_num用來記錄當前的硬件配置中的mem_bank總數(shù),current_num是用于解析skyeye.conf中的mem_bank配置信息的一個輔助變量,mem_banks數(shù)組具體記錄了每個mem_bank的類型和相關的訪問函數(shù)。mem_bank_t數(shù)據(jù)結構的具體內容如下:
typedef struct mem_bank_t {
ARMword (*read_byte)(ARMul_State *state, ARMword addr);
void (*write_byte)(ARMul_State *state, ARMword addr, ARMword data);
ARMword (*read_halfword)(ARMul_State *state, ARMword addr);
void(*write_halfword)(ARMul_State *state, ARMword addr, ARMword data);
ARMword (*read_word)(ARMul_State *state, ARMword addr);
void (*write_word)(ARMul_State *state, ARMword addr, ARMword data);
unsigned long addr, len;
char filename[MAX_STR];
unsigned type;
} mem_bank_t;
|
其中的read/write_* 函數(shù)指針分別對應了不同類型內存映射的訪問函數(shù);addr表示mem_bank的起始地址;len表示mem_bank_的大??;filename是binary image文件名;type表示mem_bank的類型。函數(shù)指針賦值等配置過程由skyeye_options.c中的函數(shù)do_mem_bank_option完成。如果在skyeye.conf中存在binary image文件名,則do_mem_bank_option函數(shù)會把文件內容讀入到對應的mem_bank中。
5. net_config_t數(shù)據(jù)結構
SkyEye支持網絡模擬,目前描述網絡配置的數(shù)據(jù)結構是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:這三個函數(shù)與具體的模擬網絡交互方式有關,分別完成初始化操作和與主機網絡的輸入輸出操作。相關的實現(xiàn)在文件skyeye_net_*.c中。
有關8019AS模擬芯片(NE2000兼容)的具體配置與實現(xiàn)位于文件skyeye-ne2k.[ch]中。有關網絡模擬的具體實現(xiàn)可參考錯誤!未找到引用源。節(jié)。
6. ARMul_State數(shù)據(jù)結構
上面講述的是與SkyEye的硬件配置相關的數(shù)據(jù)結構,可以理解為一種靜態(tài)硬件配置的數(shù)據(jù)結構,這些數(shù)據(jù)結構中的域基本不隨著SkyEye模擬硬件的運行而改變。而ARMul_State描述的是一種動態(tài)硬件配置的數(shù)據(jù)結構,它保存了隨著SkyEye模擬硬件的運行而時刻改變的硬件數(shù)據(jù)。由于ARMul_State中的域數(shù)量繁多,大體分為
- 與CPU模擬相關的域
- 與協(xié)處理器模擬相關的域
- 與內存和MMU/CACHE相關的域
- 與統(tǒng)計相關的域
- 與具體開發(fā)板相關的io部分
這里只描述其中關鍵的部分:
- 與CPU模擬相關的域
- ARMword Reg[16]:CPU當前模式下的寄存器值
- ARMword RegBank[7][16]:CPU所有七種模式下的寄存器值
- ARMword Cpsr:CPU的當前程序狀態(tài)寄存器
- ARMword Spsr[7]:CPU所有七種模式下的程序狀態(tài)保存寄存器
- ARMdword Accumulator:40bit的累加寄存器,目前用于xscale體系結構中
- ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags, Sflag,TFlag:各種狀態(tài)位
- ARMword Bank:CPU對應模式寄存器組的索引值
- ARMword Mode:CPU模式索引值
- ARMword instr, pc:pc是目前正在執(zhí)行的程序指針,instr是pc所指地址的內容
- ARMword loaded, decoded:loaded是正在加載的指令,decoded是正在解碼的指令
- unsigned NfiqSig:FIQ信號
- unsigned NirqSig:IRQ信號
- 與協(xié)處理器模擬相關的域
- ARMul_CPInits *CPInit[16]:16個協(xié)處理器的初始化函數(shù)
- ARMul_CPExits *CPExit[16]:16個協(xié)處理器的退出函數(shù)
- ARMul_LDCs *LDC[16]:16個協(xié)處理器的LDC指令函數(shù)
- ARMul_STCs *STC[16]:16個協(xié)處理器的STC指令函數(shù)
- ARMul_MRCs *MRC[16]:16個協(xié)處理器的MRC指令函數(shù)
- ARMul_MCRs *MCR[16]:16個協(xié)處理器的MCR指令函數(shù)
- ARMul_CDPs *CDP[16]:16個協(xié)處理器的CDP指令函數(shù)
- ARMul_CPReads *CPRead[16]:16個協(xié)處理器的讀CP寄存器函數(shù)
- ARMul_CPWrites *CPWrite[16]:16個協(xié)處理器的寫CP寄存器函數(shù)
- unsigned char *CPData[16]:16個協(xié)處理器的數(shù)據(jù)指針
- ARMword CP14R0_CCD:在xscale體系結構的CP14協(xié)處理器中,用于統(tǒng)計時鐘周期
- 與內存和MMU/CACHE相關的域
- mmu_state_t mmu:mmu/cache的數(shù)據(jù)結構,在armmmu.h中定義,詳解請參考"SkyEye的MMU/CACHE和Memory模擬實現(xiàn)"一節(jié)
- mem_state_t mem:memory的數(shù)據(jù)結構,在armmem.h中定義,詳解請參考"SkyEye的MMU/CACHE和Memory模擬實現(xiàn)"一節(jié)
- 與統(tǒng)計相關的域
- unsigned long NumScycles, NumNcycles, NumIcycles, NumCcycles, NumFcycles:用于統(tǒng)計不同狀態(tài)下的周期數(shù)
- unsigned long NumInstrs:當前執(zhí)行的指令數(shù)
其它與特定CPU和開發(fā)板相關的各種io寄存器的定義放到了各個與開發(fā)板相關的文件中,如skyeye_mach_at91/ep7312/pxa/sa.c等處,詳解請參考"SkyEye的開發(fā)板IO模擬實現(xiàn)"。
與具體開發(fā)板相關的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是記錄當前的中斷狀態(tài)
net_flag判斷網絡選項是否打開
net_int用來記錄網絡中斷號
lcd_is_enable來記錄LCD是否使能
lcd_addr_begin記錄lcd顯存的起始位置
lcd_addr_end記錄顯存的結束位置
7. SkyEye邏輯執(zhí)行流程
了解SkEye的總體邏輯執(zhí)行流程,對了解硬件的體系結構和軟件/硬件的接口有較大幫助。從總體上,可把SkyEye邏輯執(zhí)行流程按執(zhí)行的時間順序劃分為兩個階段:
1. SkyEye加載與配置處理過程
2. SkyEye模擬執(zhí)行過程
第一階段為第二階段的正常執(zhí)行做了充分的準備,具體的執(zhí)行內容包括;
- 讀入帶調試信息的操作系統(tǒng)執(zhí)行文件(由GDB完成)
- 根據(jù)配置文件skyeye.conf的信息配置模擬硬件
- 如果skyeye.conf中存在binary image格式文件,加載這些文件
- 根據(jù)操作系統(tǒng)執(zhí)行文件的內容加載調試信息(由GDB完成)
- 根據(jù)操作系統(tǒng)執(zhí)行文件信息加載執(zhí)行文件中的代碼段和數(shù)據(jù)段等(由GDB完成)
- 執(zhí)行相關模擬硬件的初始化函數(shù)
其中總的初始化函數(shù)是位于wrapper.c中的init函數(shù),它調用如下函數(shù)完成整個模擬硬件的初始化工作:
- ARMul_EmulateInit:初始化與執(zhí)行機器指令相關的數(shù)據(jù)ARMul_ImmedTable和ARMul_BitList
- ARMul_NewState:初始化結構為ARMul_State的全局變量state
- skyeye_option_init:初始化全局變量skyeye_config
- skyeye_read_config:讀取配置文件skyeye.conf并根據(jù)配置文件進行相關配置
- nic_init:根據(jù)配置文件信息配置網絡模擬環(huán)境
- skyeye_config.mach->mach_init(state, skyeye_config.mach):根據(jù)配置文件信息配置CPU和開發(fā)板的相關I/O函數(shù)
- ARMul_Reset(state):進一步初始化全局變量state,并根據(jù)配置文件信息配置MMU/CACHE和memory
- io_reset:初始化特定CPU和開發(fā)板的IO寄存器
第二階段根據(jù)特定硬件的配置描述,開始執(zhí)行特定硬件模擬處理。整個過程圍繞CPU執(zhí)行指令展開,根據(jù)模擬硬件可分為如下幾個階段:
- CPU執(zhí)行三級流水線處理,即取指令、譯碼、執(zhí)行指令,主要處理集中在armemu.c中的ARMul_Emulate32/26函數(shù)。
- 在執(zhí)行指令過程中,如果有中斷產生,CPU調整運行模式,并改變指令指向中斷向量起始地址,主要處理集中在arminit.c中的函數(shù)ARMul_Abort函數(shù)、armemu.c中的ARMul_Emulate32/26函數(shù)。
- 在執(zhí)行指令過程中,如果指令是協(xié)處理器指令,則把指令轉交給協(xié)處理器模擬模塊進行進一步處理,主要處理集中在文件armcopro.c、xscale_copro.c等文件中。
- 在執(zhí)行指令過程中,如果發(fā)現(xiàn)指令是訪問內存/IO的指令,則根據(jù)SkyEye模擬的特定CPU是否有MMU/CACHE分別進行處理:
- 如果CPU有MMU/CACHE,則進入MMU/CACHE模擬模塊,如果還需要內存訪問,則進入memory模擬模塊處理。如果訪問地址屬于IO地址空間,則轉到特定CPU和開發(fā)板的IO模擬模塊處理。
- 如果CPU沒有MMU/CACHE,則直接進入memory模擬模塊處理。如果訪問地址屬于IO地址空間,則轉到特定CPU和開發(fā)板的IO模擬模塊處理。
處理訪問內存/IO的指令的相關內容集中在armvirt.c;與MMU/CACHE處理、read/write buffer(用于StrongARM和XScale體系結構的模擬)處理相關的文件包括armmmu.[ch]、mmu/*.[ch];與訪問memory模擬有關的內容主要集中在armmem.[ch]中。
- 如果要執(zhí)行IO地址訪問,這具體的處理過程由特定CPU和開發(fā)板IO模擬模塊中的read/write_byte/halfword/word函數(shù)處理。
- 為了模擬外設的執(zhí)行,在執(zhí)行指令過程的每一個周期,會執(zhí)行一個io_do_cycle函數(shù),它會調用特定CPU和開發(fā)板的IO模擬模塊中的*_io_do_cycle函數(shù),完成對時鐘、網絡輸入輸出、UART輸入輸出等的處理,并根據(jù)條件產生中斷信號。
下一篇文章將討論 CPU/開發(fā)板仿真。
參考資料
關于作者