今天繼續來聊 qemu 的內部實作。在 qemu 裡頭,有一個 object 叫做 CPUState,這是一個重要的 qemu data structure,其實作如下(cpu-all.h):
#elif defined(TARGET_ARM)
#define CPUState CPUARMState
...
我們以 ARM 做為 target,再找到 target-arm/cpu.h:
typedef struct CPUARMState {
/* Regs for current mode. */
uint32_t regs[16];
/* Frequently accessed CPSR bits are stored separately for efficiently.
This contains all the other bits. Use cpsr_{read,write} to access
the whole CPSR. */
uint32_t uncached_cpsr;
uint32_t spsr;
/* Banked registers. */
uint32_t banked_spsr[6];
uint32_t banked_r13[6];
uint32_t banked_r14[6];
/* These hold r8-r12. */
uint32_t usr_regs[5];
uint32_t fiq_regs[5];
/* cpsr flag cache for faster execution */
uint32_t CF; /* 0 or 1 */
uint32_t VF; /* V is the bit 31. All other bits are undefined */
uint32_t NZF; /* N is bit 31. Z is computed from NZF */
uint32_t QF; /* 0 or 1 */
int thumb; /* 0 = arm mode, 1 = thumb mode */
/* System control coprocessor (cp15) */
struct {
uint32_t c0_cpuid;
uint32_t c0_cachetype;
uint32_t c1_sys; /* System control register. */
uint32_t c1_coproc; /* Coprocessor access register. */
uint32_t c2; /* MMU translation table base. */
uint32_t c3; /* MMU domain access control register. */
uint32_t c5_insn; /* Fault status registers. */
uint32_t c5_data;
uint32_t c6_insn; /* Fault address registers. */
uint32_t c6_data;
uint32_t c9_insn; /* Cache lockdown registers. */
uint32_t c9_data;
uint32_t c13_fcse; /* FCSE PID. */
uint32_t c13_context; /* Context ID. */
uint32_t c15_cpar; /* XScale Coprocessor Access Register */
} cp15;
/* Coprocessor IO used by peripherals */
struct {
ARMReadCPFunc *cp_read;
ARMWriteCPFunc *cp_write;
void *opaque;
} cp[15];
/* Internal CPU feature flags. */
uint32_t features;
/* exception/interrupt handling */
jmp_buf jmp_env;
int exception_index;
int interrupt_request;
int user_mode_only;
int halted;
/* VFP coprocessor state. */
struct {
float64 regs[16];
uint32_t xregs[16];
/* We store these fpcsr fields separately for convenience. */
int vec_len;
int vec_stride;
/* Temporary variables if we don't have spare fp regs. */
float32 tmp0s, tmp1s;
float64 tmp0d, tmp1d;
float_status fp_status;
} vfp;
/* iwMMXt coprocessor state. */
struct {
uint64_t regs[16];
uint64_t val;
uint32_t cregs[16];
} iwmmxt;
#if defined(CONFIG_USER_ONLY)
/* For usermode syscall translation. */
int eabi;
#endif
CPU_COMMON
} CPUARMState;
這個 object 是 qemu 用來紀錄 ARM 處理器狀態的資料結構,舉例來說,CPUState.regs 紀錄了 ARM 的所有 register 狀態。相關應用,例如,我們只要觀察 r15(pc)暫存器的值,就可以知道現在這台機器的程式執行位置。實際上的應用,像是 qemu 所實作的 gdbserver 即是透過此 object 的資訊,來回覆 gdb client 的命令。
Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue
您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw