日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

qemu源码架构

發布時間:2025/6/15 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 qemu源码架构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:本文主要概括了QEMU的代碼結構,特別從代碼翻譯的角度分析了QEMU是如何將客戶機代碼翻譯成TCG代碼和主機代碼并且最終執行的過程。并且在最后描述了QEMU和KVM之間聯系的紐帶。

申明:本文前面部分從qemu detailed study第七章翻譯而來。

?

1.代碼結構

如我們所知,QEMU是一個模擬器,它能夠動態模擬特定架構的CPU指令,如X86,PPC,ARM等等。QEMU模擬的架構叫目標架構,運行 QEMU的系統架構叫主機架構,QEMU中有一個模塊叫做微型代碼生成器(TCG),它用來將目標代碼翻譯成主機代碼。如下圖所示。

????


?

我們也可以將運行在虛擬cpu上的代碼叫做客戶機代碼,QEMU的主要功能就是不斷提取客戶機代碼并且轉化成主機指定架構的代碼。整個翻譯任務分為兩個部分:第一個部分是將做目標代碼(TB)轉化成TCG中間代碼,然后再將中間代碼轉化成主機代碼。

QEMU的代碼結構非常清晰但是內容非常復雜,這里先簡單分析一下總體的結構

1. 開始執行:

主要比較重要的c文件有:/vl.c,/cpus.c, /exec-all.c, /exec.c, /cpu-exec.c.

QEMU的main函數定義在/vl.c中,它也是執行的起點,這個函數的功能主要是建立一個虛擬的硬件環境。它通過參數的解析,將初始化內存,需要的模擬的設備初始化,CPU參數,初始化KVM等等。接著程序就跳轉到其他的執行分支文件如:/cpus.c, /exec-all.c, /exec.c, /cpu-exec.c.

2. 硬件模擬

所有的硬件設備都在/hw/ 目錄下面,所有的設備都有獨自的文件,包括總線,串口,網卡,鼠標等等。它們通過設備模塊串在一起,在vl.c中的machine _init中初始化。這里就不講每種設備是怎么實現的了。

3.目標機器

現在QEMU模擬的CPU架構有:Alpha, ARM, Cris, i386, M68K, PPC, Sparc, Mips, MicroBlaze, S390X and SH4.

我們在QEMU中使用./configure 可以配置運行的架構,這個腳本會自動讀取本機真實機器的CPU架構,并且編譯的時候就編譯對應架構的代碼。對于不同的QEMU做的事情都不同,所以不同架 構下的代碼在不同的目錄下面。/target-arch/目錄就對應了相應架構的代碼,如/target-i386/就對應了x86系列的代碼部分。雖然 不同架構做法不同,但是都是為了實現將對應客戶機CPU架構的TBs轉化成TCG的中間代碼。這個就是TCG的前半部分。

4.主機

這個部分就是使用TCG代碼生成主機的代碼,這部分代碼在/tcg/里面,在這個目錄里面也對應了不同的架構,分別在不同的子目錄里面,如i386就在/tcg/i386中。整個生成主機代碼的過程也可以教TCG的后半部分。

5.文件總結和補充:

/vl.c:???????????????????????????????????? 最主要的模擬循環,虛擬機機器環境初始化,和CPU的執行。

/target-arch/translate.c??? 將客戶機代碼轉化成不同架構的TCG操作碼。

/tcg/tcg.c????????????????????????????? 主要的TCG代碼。

/tcg/arch/tcg-target.c???????? 將TCG代碼轉化生成主機代碼

/cpu-exec.c????????????????????????? 其中的cpu-exec()函數主要尋找下一個TB(翻譯代碼塊),如果沒找到就請求得到下一個TB,并且操作生成的代碼塊。

2. TCG - 動態翻譯

QEMU在 0.9.1版本之前使用DynGen翻譯c代碼.當我們需要的時候TCG會動態的轉變代碼,這個想法的目的是用更多的時間去執行我們生成的代碼。當新的代 碼從TB中生成以后,?將會被保存到一個cache中,因為很多相同的TB會被反復的進行操作,所以這樣類似于內存的cache,能夠提高使用效率。而 cache的刷新使用LRU算法。

?

?

編譯器在執行器會從源代碼中產生目標代碼,像GCC這種編譯器,它為了產生像函數調用目標代碼會產生一些特殊的匯編目標代碼,他們能夠讓編譯器需要知道在調用函數。需要什么,以及函數調用以后需要返回什么,這些特殊的匯編代碼產生過程就叫做函數的Prologue和Epilogue,這里就叫前端和后段吧。我在其他文章中也分析過匯編調用函數的過程,至于匯編里面函數調用過程中寄存器是如何變化的,在本文中就不再描述了。

函數的后端會恢復前端的狀態,主要做下面2點:

1.?恢復堆棧的指針,包括棧頂和基地址。

2.?修改cs和ip,程序回到之前的前端記錄點。

TCG就如編譯器一樣可以產生目標代碼,代碼會保存在緩沖區中,當進入前端和后端的時候就會將TCG生成的緩沖代碼插入到目標代碼中。

接下來我們就來看下如何翻譯代碼的:

客戶機代碼

?

TCG中間代碼


主機代碼

?

?

3. TB鏈

在QEMU中,從代碼cache到靜態代碼再回到代碼cache,這個過程比較耗時,所以在QEMU中涉及了一個TB鏈將所有TB連在一起,可以讓一個TB執行完以后直接跳到下一個TB,而不用每次都返回到靜態代碼部分。具體過程如下圖:

?

4. QEMU的TCG代碼分析

接下來來看看QEMU代碼中中到底怎么來執行這個TCG的,看看它是如何生成主機代碼的。

main_loop(...){/vl.c} :?

函數main_loop 初始化qemu_main_loop_start()然后進入無限循環cpu_exec_all() , 這個是QEMU的一個主要循環,在里面會不斷的判斷一些條件,如虛擬機的關機斷電之類的。

qemu_main_loop_start(...){/cpus.c} :

函數設置系統變量?qemu_system_ready = 1并且重啟所有的線程并且等待一個條件變量。?

cpu_exec_all(...){/cpus.c} :

它是cpu循環,QEMU能夠啟動256個cpu核,但是這些核將會分時運行,然后執行qemu_cpu_exec() 。

struct CPUState{/target-xyz/cpu.h} :

它是CPU狀態結構體,關于cpu的各種狀態,不同架構下面還有不同。

?

cpu_exec(...){/cpu-exec.c}:

這個函數是主要的執行循環,這里第一次翻譯之前說道德TB,TB被初始化為(TranslationBlock *tb) ,然后不停的執行異常處理。其中嵌套了兩個無限循環 find tb_find_fast() 和tcg_qemu_tb_exec().

cantb_find_fast()為客戶機初始化查詢下一個TB,并且生成主機代碼。

tcg_qemu_tb_exec()執行生成的主機代碼?

struct TranslationBlock {/exec-all.h}:

結構體TranslationBlock包含下面的成員:PC, CS_BASE, Flags (表明TB), tc_ptr (指向這個TB翻譯代碼的指針), tb_next_offset[2], tb_jmp_offset[2] (接下去的Tb), *jmp_next[2], *jmp_first (之前的TB).

?

tb_find_fast(...){/cpu-exec.c} :

函數通過調用獲得程序指針計數器,然后傳到一個哈希函數從 tb_jmp_cache[] (一個哈希表)得到TB的所以,所以使用tb_jmp_cache可以找到下一個TB。如果沒有找到下一個TB,則使用tb_find_slow。

?tb_find_slow(...){/cpu-exec.c}:

這個是在快速查找失敗以后試圖去訪問物理內存,尋找TB。

tb_gen_code(...){/exec.c}:

開始分配一個新的TB,TB的PC是剛剛從CPUstate里面通過using get_page_addr_code()找到的

phys_pc = get_page_addr_code(env, pc);

tb = tb_alloc(pc);

ph當調用cpu_gen_code()?以后,接著會調用tb_link_page()它將增加一個新的TB,并且指向它的物理頁表。

cpu_gen_code(...){translate-all.c}:

函數初始化真正的代碼生成,在這個函數里面有下面的函數調用:

gen_intermediate_code(){/target-arch/translate.c}->gen_intermediate_code_internal(){/target-arch/translate.c }->disas_insn(){/target-arch/translate.c}

disas_insn(){/target-arch/translate.c}

函數disas_insn() 真正的實現將客戶機代碼翻譯成TCG代碼,它通過一長串的switch case,將不同的指令做不同的翻譯,最后調用tcg_gen_code。

?

tcg_gen_code(...){/tcg/tcg.c}:

這個函數將TCG的代碼轉化成主機代碼,這個就不細細說明了,和前面類似。

?

#define tcg_qemu_tb_exec(...){/tcg/tcg.g}:

通過上面的步驟,當TB生成以后就通過這個函數進行執行.

next_tb = tcg_qemu_tb_exec(tc_ptr) :

extern uint8_t code_gen_prologue[];

#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM(*)(void *)) code_gen_prologue)(tb_ptr)

?

通過上面的步驟我們就解析了QEMU是如何將客戶機代碼翻譯成主機代碼的,了解了TCG的工作原理。接下來看看QEMU與KVM是怎么聯系的。

5. QEMU中的IOCTL

在QEMU-KVM中,用戶空間的QEMU是通過IOCTL與內核空間的KVM模塊進行通訊的。

1. 創建KVM

在/vl.c中通過kvm_init()將會創建各種KVM的結構體變量,并且通過IOCTL與已經初始化好的KVM模塊進行通訊,創建虛擬機。然后創建VCPU,等等。

2. KVM_RUN

這個IOCTL是使用最頻繁的,整個KVM運行就不停在執行這個IOCTL,當KVM需要QEMU處理一些指令和IO等等的時候就會退出通過這個IOCTL退回到QEMU進行處理,不然就會一直在KVM中執行。

它的初始化過程:

vl.c中調用machine->init初始化硬件設備接著調用pc_init_pci,然后再調用pc_init1。

接著通過下面的調用初始化KVM的主循環,以及CPU循環。在CPU循環的過程中不斷的執行KVM_RUN與KVM進行交互。

pc_init1->pc_cpus_init->pc_new_cpu->cpu_x86_init->qemu_init_vcpu->kvm_init_vcpu->ap_main_loop->kvm_main_loop_cpu->kvm_cpu_exec->kvm_run

3.KVM_IRQ_LINE

這個IOCTL和KVM_RUN是不同步的,它也是個頻率非常高的調用,它就是一般中斷設備的中斷注入入口。當設備有中斷就通過這個IOCTL最終 調用KVM里面的kvm_set_irq將中斷注入到虛擬的中斷控制器。在kvm中會進一步判斷屬于什么中斷類型,然后在合適的時機寫入vmcs。當然在 KVM_RUN中會不斷的同步虛擬中斷控制器,來獲取需要注入的中斷,這些中斷包括QEMU和KVM本身的,并在重新進入客戶機之前注入中斷。

?

總結: 通過這篇文章能夠大概的了解QEMU的代碼結構,其中主要包括TCG翻譯代碼的過程以及QEMU和KVM的交互過程。

總結

以上是生活随笔為你收集整理的qemu源码架构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 曰韩精品 | 自拍av在线 | jvid视频| 无码日韩精品视频 | 日本高清精品 | 亚洲AV无码一区二区三区性 | 最近中文字幕 | 欧美久久影院 | 欧美hdxxxx| 国产永久毛片 | 欧美在线视频免费播放 | 日韩精品电影一区二区三区 | 狠狠91 | 欧美激情综合色综合啪啪五月 | 国产视频xxx | 国产欧美一区二区精品性色超碰 | 一本一道波多野结衣av黑人 | 欧美激情国产日韩精品一区18 | 欧美日本一道 | 久久av一区二区三区 | 伊人日日夜夜 | 国产18照片色桃 | 毛片内射久久久一区 | 亚洲三级电影网站 | 精品视频在线观看免费 | 特黄aaaaaaaaa毛片免 | 开心色婷婷 | 日日干视频 | 黄色大片免费网站 | 给我看高清的视频在线观看 | 亚洲成人激情视频 | 99热这里只有精品在线观看 | 中国老头同性xxxxx | 四虎tv | 一区二区免费播放 | 亚洲伊人网站 | 久久久久久av无码免费网站 | 日韩va在线观看 | 伊人天堂av | 亚洲黄色激情视频 | 日本午夜网 | 夫妻露脸自拍[30p] | 日韩一区二区三区在线免费观看 | 黄色片91 | 久久精品视频免费看 | 中文字幕88| 国产日韩精品一区二区三区在线 | 91黄色免费网站 | 四虎精品视频 | 伦伦影院午夜理论片 | 天天射天天干 | 69超碰 | 啦啦啦免费高清视频在线观看 | 狠狠地日| 亚洲第一色站 | 国产老妇伦国产熟女老妇视频 | 亚洲av无码精品一区二区 | 自拍偷拍福利视频 | 日本裸体xx少妇18在线 | 中出精品 | 久久久久久免费精品 | 国产精品久久国产精麻豆96堂 | 人人插人人干 | 欧美中文日韩 | 国产一二视频 | 91成人国产综合久久精品 | 国产成人av一区二区三区在线观看 | 成人福利一区二区 | 美丽的小蜜桃2:美丽人生 | 天堂在线观看av | 日本人の夫妇交换 | 亚洲影视在线 | 亚洲精品四区 | 欧美激情福利 | 久久黄色片视频 | 久久99热人妻偷产国产 | 游戏涩涩免费网站 | 韩国av在线免费观看 | a级一片| 国产成人一区二区三区影院在线 | 57pao国产精品一区 | 国产在线观看成人 | 黄色片视频免费看 | 91免费在线观看网站 | 性爱视频免费 | 欧美一级片一区 | mm1313亚洲精品 | 男女草比视频 | 午夜h视频 | 国产乱码一区二区三区在线观看 | 手机av免费观看 | 成人av无码一区二区三区 | 爱爱视频网站 | 强行挺进白丝老师里呻吟 | 国产精品天天狠天天看 | 中日韩男男gay无套 人人草人人干 | 国精品无码一区二区三区 | 猫咪av网 | 波多野结衣影院 |