今天繼續來聊 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