1. 程式人生 > >qemu 二進位制翻譯 執行流程分析

qemu 二進位制翻譯 執行流程分析

一.qemu簡介

         qemu是使用動態二進位制翻譯的cpu模擬器,它支援兩種執行模式:全系統模擬和使用者態模擬。在全系統模擬下,qemu可以模擬處理器和各種外設,可以執行作業系統。使用者態可以執行為另外一種cpu編譯的程序,前提是兩者執行的os要一致。qemu使用了動態二進位制翻譯將targetinstruction翻譯成hostinstruction,完成這個工作的是tcg模組。為了移植性和通用性方面的考慮,qemu定義了mirco-op,首先qemu會將targetinstruction翻譯成mirco-op,然後tcgmirco-op翻譯成host instruction

Qemu程式碼翻譯流程:target instruction ->micro-op->tcg->host instruction

2.qemu程式碼執行流程:

    1. 這部分主要是建立了一個為執行tcg翻譯和執行的執行緒,它的函式是qemu_tcg_cpu_thread_fn,這個函式會呼叫tcg_exec_all,最後cpu_exec.

main
cpu_init
qemu_init_vcpu
qemu_tcg_init_vcpu

qemu_tcg_cpu_thread_fn

     2.執行主函式(cpu_exec)

                主要是處理中斷異常, 找到程式碼翻譯塊,然後執行.

  1. for(;;) {  
  2. process interruptrequest;  
  3. tb_find_fast();  
  4. tcg_qemu_tb_exec(tc_ptr);  
  5. }  

        qemu會將翻譯好到程式碼塊暫存起來,因此首先會去檢視該pc對應的程式碼是否已經翻譯,如果已經存在直接返回,否則就進入tb_find_slow,進行翻譯。

  1. 139 staticinline TranslationBlock *tb_find_fast(CPUArchState *env)  
  2. 140 {  
  3. 141     TranslationBlock *tb;  
  4. 142     target_ulong cs_base, pc;  
  5. 143     int flags;  
  6. 144   
  7. 145     /* we record a subset of the CPU state. It will 
  8. 146        always be the same before a given translated block 
  9. 147        is executed. */
  10. 148     cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);  
  11. 149     tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];  
  12. 150     if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||  
  13. 151                  tb->flags != flags)) {  
  14. 152         tb = tb_find_slow(env, pc, cs_base, flags);  
  15. 153     }  
  16. 154     return tb;  
  17. 155 }  

       進入tb_find_slow後會呼叫tb_gen_code,首先分配TranslationBlock描述符,將要翻譯的pc等資訊記錄下來,然後呼叫cpu_gen_code,這個函式完成程式碼翻譯工作。qemu將翻譯好的程式碼存在一個緩衝區裡面。

  1. 1029 TranslationBlock *tb_gen_code(CPUArchState *env,  
  2. 1030                               target_ulong pc, target_ulong cs_base,  
  3. 1031                               int flags, int cflags)  
  4. 1032 {            
  5. 1033     TranslationBlock *tb;  
  6. 1034     uint8_t *tc_ptr;  
  7. 1035     tb_page_addr_t phys_pc, phys_page2;  
  8. 1036     target_ulong virt_page2;  
  9. 1037     int code_gen_size;  
  10. 1038      
  11. 1039     phys_pc = get_page_addr_code(env, pc);  
  12. 1040     tb = tb_alloc(pc);  
  13. 1041     if (!tb) {  
  14. 1042         /* flush must be done */
  15. 1043         tb_flush(env);  
  16. 1044         /* cannot fail at this point */
  1. 1045         tb = tb_alloc(pc);  
  2. 1046         /* Don't forget to invalidate previous TB info.  */
  3. 1047         tb_invalidated_flag = 1;  
  4. 1048     }  
  5. 1049     tc_ptr = code_gen_ptr;  
  6. 1050     tb->tc_ptr = tc_ptr;  
  7. 1051     tb->cs_base = cs_base;  
  8. 1052     tb->flags = flags;  
  9. 1053     tb->cflags = cflags;  
  10. 1054     cpu_gen_code(env, tb, &code_gen_size);  
  11. 1055     code_gen_ptr = (void *)(((uintptr_t)code_gen_ptr + code_gen_size +  
  12. 1056                              CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));  
  13. 1057   
  14. 1058     /* check next page if needed */
  15. 1059     virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;  
  16. 1060     phys_page2 = -1;  
  17. 1061     if ((pc & TARGET_PAGE_MASK) != virt_page2) {  
  18. 1062         phys_page2 = get_page_addr_code(env, virt_page2);  
  19. 1063     }  
  20. 1064     tb_link_page(tb, phys_pc, phys_page2);  
  21. 1065     return tb;  
  22. 1066 }  

      在cpu_gen_code裡面首先是將targetinstruction翻譯成micro-op,然後將mirco-op翻譯成host機器碼。

  1. 54 int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr)  
  2.  55 {  
  3.  56     TCGContext *s = &tcg_ctx;  
  4.  57     uint8_t *gen_code_buf;  
  5.  58     int gen_code_size;  
  6.  59 #ifdef CONFIG_PROFILER  
  7.  60     int64_t ti;  
  8.  61 #endif  
  9.  62   
  10.  63 #ifdef CONFIG_PROFILER  
  11.  64     s->tb_count1++; /* includes aborted translations because of 
  12.  65                        exceptions */
  13.  66     ti = profile_getclock();  
  14.  67 #endif  
  15.  68     tcg_func_start(s);  
  16.  69   
  17.  70     gen_intermediate_code(env, tb);  
  18.  71   
  19.  72     /* generate machine code */
  20.  73     gen_code_buf = tb->tc_ptr;  
  21.  74     tb->tb_next_offset[0] = 0xffff;  
  22.  75     tb->tb_next_offset[1] = 0xffff;  
  23.  76     s->tb_next_offset = tb->tb_next_offset;  
  24.  77 #ifdef USE_DIRECT_JUMP  
  25.  78     s->tb_jmp_offset = tb->tb_jmp_offset;  
  26.  79     s->tb_next = NULL;  
  27.  80 #else
  28.  81     s->tb_jmp_offset = NULL;  
  29.  82     s->tb_next = tb->tb_next;  
  30.  83 #endif  
  31.  84   
  32.  85 #ifdef CONFIG_PROFILER  
  33.  86     s->tb_count++;  
  34.  87     s->interm_time += profile_getclock() - ti;  
  35.  88     s->code_time -= profile_getclock();  
  36.  89 #endif  
  37.  90     gen_code_size = tcg_gen_code(s, gen_code_buf);  
  38.  91     *gen_code_size_ptr = gen_code_size;  
  39.  92 #ifdef CONFIG_PROFILER  
  40.  93     s->code_time += profile_getclock();  
  41.  94     s->code_in_len += tb->size;  
  42.  95     s->code_out_len += gen_code_size;  
  43.  96 #endif  
  44.  97   
  45.  98 #ifdef DEBUG_DISAS  
  46.  99     if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {  
  47. 100         qemu_log("OUT: [size=%d]\n", *gen_code_size_ptr);  
  48. 101         log_disas(tb->tc_ptr, *gen_code_size_ptr);  
  49. 102         qemu_log("\n");  
  50. 103         qemu_log_flush();  
  51. 104     }  
  52. 105 #endif  
  53. 106     return 0;  
  54. 107 }  

       qemutarget翻譯成中間碼時,將操作碼和運算元分開儲存,分別存在gen_opc_bufgen_opparam_buf中。翻譯的過程就是不斷向gen_opc_bufgen_opparam_buf中填充操作碼和運算元。接下來就是tcg_gen_code.

  1. 2175 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)  
  2. 2176 {  
  3. 2177 #ifdef CONFIG_PROFILER  
  4. 2178     {  
  5. 2179         int n;  
  6. 2180         n = (gen_opc_ptr - gen_opc_buf);  
  7. 2181         s->op_count += n;  
  8. 2182         if (n > s->op_count_max)  
  9. 2183             s->op_count_max = n;  
  10. 相關推薦

    qemu 二進位制翻譯 執行流程分析

    一.qemu簡介          qemu是使用動態二進位制翻譯的cpu模擬器,它支援兩種執行模式:全系統模擬和使用者態模擬。在全系統模擬下,qemu可以模擬處理器和各種外設,可以執行作業系統。使用者態可以執行為另外一種cpu編譯的程序,前提是兩者執行的os要

    qemu翻譯執行流程分析

    一.qemu簡介          qemu是使用動態二進位制翻譯的cpu模擬器,它支援兩種執行模式:全系統模擬和使用者態模擬。在全系統模擬下,qemu可以模擬處理器和各種外設,可以執行作業系統。使用者態可以執行為另外一種cpu編譯的程序,前提是兩者執行的os要一致

    深入淺出Mybatis系列(十)---SQL執行流程分析(源碼篇)(轉)

    factor demo 讀取配置 gist wrapper load 任性 wrap 深入淺出 轉載自:http://www.cnblogs.com/dongying/p/4142476.html 1. SqlSessionFactory 與 SqlSession.   通

    K8S 原始碼探祕 之 kubeadm upgrade apply 執行流程分析

    一、引言        本文將基於 Kubernetes 1.12 版本,分析 kubeadm  upgrade apply 的執行流程,希望對讀者理解 k8s 有幫助!        關

    K8S 原始碼探祕 之 kubeadm join 執行流程分析

    一、引言        本文將基於 Kubernetes 1.12 版本,分析 kubeadm  join 的執行流程,希望對讀者理解 k8s 有幫助!        關於 init 流程

    K8S 原始碼探祕 之 kubeadm init 執行流程分析

    一、引言        kubeadm 是 k8s 重要的快速部署工具,也是其原生支援的部署工具,在實現自動化部署方面具有重要的研究價值。        本文將基於 Kubernetes 1.12 版本,分析

    Glide原理之執行流程分析

    Glide是一個優秀的圖片載入庫,它有如下優點: 1. Glide可以監聽Activity的生命週期管理,更加合理的管理圖片的載入和釋放。 2. 載入質量,Picasso預設採用的ARGB-8888, Glide預設採用的是RGB-565,記憶體佔用會減小一半。 3. Glide可

    深入淺出Mybatis---SQL執行流程分析(原始碼篇)

    最近太忙了,一直沒時間繼續更新部落格,今天忙裡偷閒繼續我的Mybatis學習之旅。在前九篇中,介紹了mybatis的配置以及使用, 那麼本篇將走進mybatis的原始碼,分析mybatis 的執行流程, 好啦,鄙人不喜歡口水話,還是直接上幹活吧: 1. SqlSessionFactory 與 S

    Netty 執行流程分析與重要元件介紹

    Netty的應用場景: 1、Netty可以作為RBC的通訊框架或是通訊的協議、通訊的庫,實現了遠端過程的呼叫,是基於socket的方式。這是在Netty開發裡面很大的應用場景。 2、Netty可以作為長連線的伺服器,就是基於websocket的長連線伺服器,實現伺服器與客

    Spark學習筆記(10)—— wordcount 執行流程分析

    1 啟動叢集 啟動 HDFS start-dfs.sh 啟動 Spark 叢集 /home/hadoop/apps/spark-1.6.3-bin-hadoop2.6/sbin/start-all

    qemu tcg程式碼執行流程

    一.qemu簡介          qemu是使用動態二進位制翻譯的cpu模擬器,它支援兩種執行模式:全系統模擬和使用者態模擬。在全系統模擬下,qemu可以模擬處理器和各種外設,可以執行作業系統。使用者態可以執行為另外一種cpu編譯的程序,前提是兩者執行的os要一致。qemu使用了動態二進位制翻譯將tar

    Web前端(一)-Vue專案執行流程分析(一)

    去年年底離職了創業去了哈,把寫部落格的事情給落下了! 一直盯著專案幾乎很少休息,一個月能休息一天算好的啦,煎熬將近一年啊。 都說 “離職窮半年,創業窮三年”,終於嚐到其中滋味!哎。。。現在終於涼了!哈哈! 最近靜下心來,好好反思總結,其中寫部落格這件事,還是不能停止..

    Vue框架專案實戰整理:3、Vue專案執行流程分析(一)

    宣告:本教程不收取任何費用,歡迎轉載,尊重作者勞動成果,不得用於商業用途,侵權必究!!!! 上兩篇講了Vue框架專案實戰整理:1、快速啟動Vue、開發工具介紹 和 Vue框架專案實戰整理:2、Vue環境搭建,今天應該到Vue專案執行流程分析的時候了,為什麼會有這方便的研究

    dart 非同步事件執行流程分析(一)

    深入研究了dart 的非同步事件執行流程。   main() { /// testNoAwait() and testWithCallerAwait() exe order is same. // testNoAwait(); // testWithCal

    dart 非同步事件執行流程分析(二)

    // use two list to test the async envet exe order. // one record the emitted order; // and the other record the captured order; import 'dart:

    ffplay程式執行流程分析

    1、main()開始: 分別註冊編解碼器,複用以及解複用器 avcodec_register_all(); //register codec avdevice_register_all(); av_register_all(); //register demux a

    struts2執行流程分析

    struts2框架的的執行流程:(使用者要訪問一個Action類) 當web伺服器啟動的時候: 1.第一步:web伺服器啟動的時候讀取到了web.xml檔案中,使用者已經配置了一個struts2的一個核心過濾器,這時候在訪問過濾器配置的過濾請求的時候要先經過此過濾器。而經過

    Toast執行流程分析與複用

    意圖分析的問題 Toast的顯示是非同步的還是同步。 Toast是否可以在子執行緒中例項化並呼叫Toast.show方法。 Toast物件複用的可行性。 原始碼執行流程分析 Toast的本地建立和show()方法 例項化Toast物件

    Spring MVC 執行流程分析

    技術 sar info str user lec solid ogr appdata Spring MVC 的執行流程圖Spring MVC 執行流程分析

    quartz 2.2.x 原始碼學習 基本執行流程分析

    quartz 官網中給出了一些基本概念,請先閱讀官網相關概念。 下面對最簡單的一個任務排程工作進行分析,下面的程式碼每隔三秒中不斷重複執行任務SimpleJob。 public class JobStart { public static v