qemu 二進位制翻譯 執行流程分析
一.qemu簡介
qemu是使用動態二進位制翻譯的cpu模擬器,它支援兩種執行模式:全系統模擬和使用者態模擬。在全系統模擬下,qemu可以模擬處理器和各種外設,可以執行作業系統。使用者態可以執行為另外一種cpu編譯的程序,前提是兩者執行的os要一致。qemu使用了動態二進位制翻譯將targetinstruction翻譯成hostinstruction,完成這個工作的是tcg模組。為了移植性和通用性方面的考慮,qemu定義了mirco-op,首先qemu會將targetinstruction翻譯成mirco-op,然後tcg將mirco-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.
maincpu_init
qemu_init_vcpu
qemu_tcg_init_vcpu
qemu_tcg_cpu_thread_fn
2.執行主函式(cpu_exec)
主要是處理中斷異常, 找到程式碼翻譯塊,然後執行.
- for(;;) {
- process interruptrequest;
- tb_find_fast();
- tcg_qemu_tb_exec(tc_ptr);
- }
qemu會將翻譯好到程式碼塊暫存起來,因此首先會去檢視該pc對應的程式碼是否已經翻譯,如果已經存在直接返回,否則就進入tb_find_slow,進行翻譯。
-
139 staticinline TranslationBlock *tb_find_fast(CPUArchState *env)
- 140 {
- 141 TranslationBlock *tb;
- 142 target_ulong cs_base, pc;
- 143 int flags;
- 144
- 145 /* we record a subset of the CPU state. It will
- 146 always be the same before a given translated block
- 147 is executed. */
- 148 cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
- 149 tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
- 150 if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
- 151 tb->flags != flags)) {
- 152 tb = tb_find_slow(env, pc, cs_base, flags);
- 153 }
- 154 return tb;
- 155 }
進入tb_find_slow後會呼叫tb_gen_code,首先分配TranslationBlock描述符,將要翻譯的pc等資訊記錄下來,然後呼叫cpu_gen_code,這個函式完成程式碼翻譯工作。qemu將翻譯好的程式碼存在一個緩衝區裡面。
- 1029 TranslationBlock *tb_gen_code(CPUArchState *env,
- 1030 target_ulong pc, target_ulong cs_base,
- 1031 int flags, int cflags)
- 1032 {
- 1033 TranslationBlock *tb;
- 1034 uint8_t *tc_ptr;
- 1035 tb_page_addr_t phys_pc, phys_page2;
- 1036 target_ulong virt_page2;
- 1037 int code_gen_size;
- 1038
- 1039 phys_pc = get_page_addr_code(env, pc);
- 1040 tb = tb_alloc(pc);
- 1041 if (!tb) {
- 1042 /* flush must be done */
- 1043 tb_flush(env);
- 1044 /* cannot fail at this point */
- 1045 tb = tb_alloc(pc);
- 1046 /* Don't forget to invalidate previous TB info. */
- 1047 tb_invalidated_flag = 1;
- 1048 }
- 1049 tc_ptr = code_gen_ptr;
- 1050 tb->tc_ptr = tc_ptr;
- 1051 tb->cs_base = cs_base;
- 1052 tb->flags = flags;
- 1053 tb->cflags = cflags;
- 1054 cpu_gen_code(env, tb, &code_gen_size);
- 1055 code_gen_ptr = (void *)(((uintptr_t)code_gen_ptr + code_gen_size +
- 1056 CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
- 1057
- 1058 /* check next page if needed */
- 1059 virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
- 1060 phys_page2 = -1;
- 1061 if ((pc & TARGET_PAGE_MASK) != virt_page2) {
- 1062 phys_page2 = get_page_addr_code(env, virt_page2);
- 1063 }
- 1064 tb_link_page(tb, phys_pc, phys_page2);
- 1065 return tb;
- 1066 }
在cpu_gen_code裡面首先是將targetinstruction翻譯成micro-op,然後將mirco-op翻譯成host機器碼。
- 54 int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr)
- 55 {
- 56 TCGContext *s = &tcg_ctx;
- 57 uint8_t *gen_code_buf;
- 58 int gen_code_size;
- 59 #ifdef CONFIG_PROFILER
- 60 int64_t ti;
- 61 #endif
- 62
- 63 #ifdef CONFIG_PROFILER
- 64 s->tb_count1++; /* includes aborted translations because of
- 65 exceptions */
- 66 ti = profile_getclock();
- 67 #endif
- 68 tcg_func_start(s);
- 69
- 70 gen_intermediate_code(env, tb);
- 71
- 72 /* generate machine code */
- 73 gen_code_buf = tb->tc_ptr;
- 74 tb->tb_next_offset[0] = 0xffff;
- 75 tb->tb_next_offset[1] = 0xffff;
- 76 s->tb_next_offset = tb->tb_next_offset;
- 77 #ifdef USE_DIRECT_JUMP
- 78 s->tb_jmp_offset = tb->tb_jmp_offset;
- 79 s->tb_next = NULL;
- 80 #else
- 81 s->tb_jmp_offset = NULL;
- 82 s->tb_next = tb->tb_next;
- 83 #endif
- 84
- 85 #ifdef CONFIG_PROFILER
- 86 s->tb_count++;
- 87 s->interm_time += profile_getclock() - ti;
- 88 s->code_time -= profile_getclock();
- 89 #endif
- 90 gen_code_size = tcg_gen_code(s, gen_code_buf);
- 91 *gen_code_size_ptr = gen_code_size;
- 92 #ifdef CONFIG_PROFILER
- 93 s->code_time += profile_getclock();
- 94 s->code_in_len += tb->size;
- 95 s->code_out_len += gen_code_size;
- 96 #endif
- 97
- 98 #ifdef DEBUG_DISAS
- 99 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
- 100 qemu_log("OUT: [size=%d]\n", *gen_code_size_ptr);
- 101 log_disas(tb->tc_ptr, *gen_code_size_ptr);
- 102 qemu_log("\n");
- 103 qemu_log_flush();
- 104 }
- 105 #endif
- 106 return 0;
- 107 }
qemu將target翻譯成中間碼時,將操作碼和運算元分開儲存,分別存在gen_opc_buf和gen_opparam_buf中。翻譯的過程就是不斷向gen_opc_buf和gen_opparam_buf中填充操作碼和運算元。接下來就是tcg_gen_code.
- 2175 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
- 2176 {
- 2177 #ifdef CONFIG_PROFILER
- 2178 {
- 2179 int n;
- 2180 n = (gen_opc_ptr - gen_opc_buf);
- 2181 s->op_count += n;
- 2182 if (n > s->op_count_max)
- 2183 s->op_count_max = n;
-
相關推薦
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