QEMU1.3.0的源碼分析三:user model之linux

做者:snsn1984 linux

從源碼目錄來看,user model有兩塊內容bsd-user和linux-user。我主要研究了下linux-user這種狀況。 app

首先要提一下一般容易關注的焦點,linux-user下的函數入口點:/源碼目錄/linux-user/main.c中的
Line:3388    int main(int argc, char **argv, char **envp).
找到了入口函數,就能夠根據這個main函數中的調用關係來看看這個狀況下的主要執行流程和動做了。

int main(int argc, char **argv, char **envp)
{

    module_call_init(MODULE_INIT_QOM);

    qemu_cache_utils_init(envp);

    /*初始化了tcg的相關部分,包含了cpu動態轉化的一些初始化操做。*/
    tcg_exec_init(0);
    cpu_exec_init_all();

    /*包含了虛擬cpu的初始化*/
    env = cpu_init(cpu_model);
 
    /*加載可執行程序,即Guest code*/
    ret = loader_exec(filename, target_argv, target_environ, regs,
        info, &bprm);


    target_set_brk(info->brk);
    /*系統調用初始化*/
    syscall_init();
    /*信號初始化*/
    signal_init();

   /*此函數是主要的循環體,經過這個函數來實現對指令的動態翻譯,而且執行翻譯以後的Host Code。
   經過最終調用cpu_gen_code()函數(位於translate-all.c文件中)來實現
    動態翻譯,其中調用了兩個關鍵函數。一個關鍵函數是gen_intermediate_code()
   函數(位於target-arm/translate.c,此處以guest指令集爲arm爲例,其餘的能夠自行替換),
   這個函數的主要功能是根據Guest Code生成TCG Operations。另一個重要的函數是
  tcg_gen_code()函數(位於tcg/tcg.c),這個函數主要是把TCG Operations轉化成Host code。*/
    cpu_loop(env);
    /* never exits */
 
    return 0;
}

下面來分析下剛纔介紹的重要函數cpu_loop(). cpu_loop()函數在linux-user/main.c中有多個版本,區別在於參數,參數是不一樣的cpu state,下面舉例仍然以arm爲主。

void cpu_loop(CPUARMState *env)
{
    int trapnr;
    unsigned int n, insn;
    target_siginfo_t info;
    uint32_t addr;

    for(;;) {
        cpu_exec_start(env);
        trapnr = cpu_arm_exec(env);
        cpu_exec_end(env);
   ...............
}
能夠看到for循環裏有三個函數調用,分別是cpu_exec_start,cpu_arm_exec,cpu_exec_end。其中最重要的
cpu_arm_exec函數,經過target-arm/cpu.h中的宏定義#define cpu_exec cpu_arm_exec調用了cpu-exec.c文件
中的cpu_exec()函數。
cpu_exec()是整個qemu中的一個重要函數,它負責整個核心的從guest code 到host code的翻譯和執行。
cpu_exec()首先會去調用tb_find_fast(),tb_find_fast()會判斷取回來的tb是否合法,若是不合法會去調用tb_find_slow()函數。
tb_find_slow()會試圖經過物理mapping去尋找tb,若是尋找失敗則會調用tb_gen_code()去翻譯代碼。
cpu_exec()函數調用tb_find_fast()以後會調用tcg_qemu_tb_exec()去執行所找到的tb。最後再調用cpu_exec_nocache()去執行剩下的代碼。
相關文章
相關標籤/搜索