`
haoningabc
  • 浏览: 1466023 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

qemu

阅读更多


这个文章不错
https://github.com/prife/documents/blob/master/qemu-linux.txt




转载
http://blog.csdn.net/yearn520/article/details/6602182
这个不错

http://blog.sina.com.cn/s/blog_7a77356b01012j6f.html

前言:本文主要概括了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 Manager v7.0 (April 2010) with Qemu 0.11.1 and KQEMU Support

    Qemu Manager v7.0 (April 2010) with Qemu 0.11.1 and KQEMU Support ------ windows下的qemu模拟器 QEMU是一套由Fabrice Bellard所编写的模拟处理器的自由软件。它与Bochs,PearPC近似,但其具有某些后两者所不...

    Qemu使用手册中文版

    QEMU(Quick Emulator)是一款强大的开源虚拟化软件,它能够模拟各种计算机硬件,使得用户可以在同一台物理机器上运行多种操作系统。QEMU的核心功能包括系统级虚拟化和用户级虚拟化,支持Linux、Windows以及其他多种...

    linux qemu离线安装包

    Linux QEMU(Quick Emulator)是一款强大的开源模拟器和虚拟机监控程序,它允许你在同一台计算机上运行多个操作系统,而无需物理硬件。QEMU支持多种架构,包括x86、ARM、MIPS等,因此它在软件开发、测试、教学和虚拟...

    qemu-img windows工具

    QEMU(Quick Emulator)是一款强大的开源虚拟化软件,它提供了多种虚拟化功能,包括硬件模拟和半虚拟化。QEMU-img是QEMU项目的一部分,专门用于管理和转换虚拟机镜像文件。在Windows环境中,QEMU-img工具允许用户对...

    QEMU for windows+安装说明

    QEMU(Quick Emulator)是一款强大的开源模拟器和虚拟化工具,它允许用户在一台机器上运行多种操作系统,而无需重启或拥有多个物理系统。QEMU适用于Windows平台,为用户提供了一个方便的界面来管理和操作虚拟机。在...

    Qemu安装使用手册中文版

    ### QEMU安装与使用详解 #### 一、引言 QEMU是一款开源的指令级虚拟化软件,能够模拟多种处理器架构及操作系统环境,为开发者提供了一个灵活且强大的虚拟化平台。本文将详细介绍QEMU的安装步骤、基本使用方法以及...

    qemu代码分析.pdf

    ### QEMU代码分析 #### QEMU简介 QEMU(Quick Emulator)是一个开源的机器模拟器,它通过使用动态二进制翻译技术来提高性能。它支持两种主要的运行模式:全系统模拟和用户态模拟。 1. **全系统模拟**:在此模式下...

    QEMU虚拟机网卡及网络配置

    ### QEMU虚拟机网卡及网络配置详解 #### 基本概念 QEMU是一款开源的虚拟机模拟器,能够模拟完整的系统环境,包括处理器、内存、存储设备以及网络设备等。为了使虚拟机能够正常地与其他物理或虚拟机进行通信,QEMU...

    Qemu模拟器运行AIX 7.2 系统.docx

    ### QEMU模拟器运行AIX 7.2系统的详细指南 #### AIX操作系统简介 AIX(Advanced Interactive Executive)是IBM公司开发的一款基于AT&T Unix System V的类UNIX操作系统,主要用于IBM Power架构的服务器和工作站上。...

    银河麒麟QEMUARM架构虚拟机

    下载qemu5.x D:\software\QEMU\qemu-system-aarch64.exe -m 6333 -cpu cortex-a72 -smp 2,cores=2,threads=1,sockets=1 -M virt -bios D:\software\QEMU\bios\QEMU_EFI_desktop.fd -net nic,model=pcnet -device nec...

    qemu-w64-setup-20220831.exe

    QEMU(Quick Emulator)是一款强大的开源模拟器和虚拟化软件,它允许用户在一台计算机上运行多种操作系统,而无需实际硬件。QEMU-w64-setup-20220831.exe 是QEMU针对64位Windows系统的安装程序,发布于2022年8月31日...

    QEMU 1.2.0 windows 可执行程序

    QEMU 1.2.0 编译好的可执行程序,可以直接运行于windows平台,可以模拟各种硬件平台,例如ARM,X86,Sparc,PPC,MIPS等等。下面是文件列表 2012-09-20 00:18 3,211 bamboo.dtb 2012-09-20 00:18 131,072 bios.bin ...

    QEMU+SPICE+USBredir详细编译步骤

    "QEMU+SPICE+USBredir详细编译步骤" 本文将详细介绍如何在 Linux 系统(包括 CentOS、Ubuntu 等)下编译 QEMU 和 SPICE 协议,使其支持 USB 重定向。 一、编译 libusb libusb 是一个开源的 USB 库,提供了访问 ...

    qemu虚拟机 bios源码

    QEMU(Quick Emulator)是一款强大的开源虚拟化软件,它允许用户在一台计算机上模拟运行多种不同的硬件系统。BIOS(基本输入输出系统)是计算机启动时加载的第一个软件,负责初始化硬件并提供基本的系统功能。在QEMU...

    qemu-0.13.0(编译过全处理器支持)

    QEmu虚拟机 做嵌入式开发的朋友试试 调试内核很方便 QEMU emulator version 0.13.0, Copyright (c) 2003-2008 Fabrice Bellard usage: qemu [options] [disk_image] 'disk_image' is a raw hard disk image for ...

    QEMU在Windows上模拟ARM硬件平台并安装国产操作系统麒麟高级服务器版V10(基于OpenEuler)

    QEMU(Quick Emulator)是一款强大的开源虚拟化软件,它能够在不同的硬件平台上模拟各种处理器架构,包括ARM。在Windows系统中使用QEMU可以为开发者提供一个便捷的环境,用于测试和开发针对ARM架构的应用程序,而...

    Qemu KVM and Libvirt

    Qemu KVM and Libvirt Qemu KVM 和 Libvirt 是虚拟化领域中的三个重要概念,分别是虚拟机监控器、内核模块和虚拟机管理工具。本文将对这三个概念进行解析,并探讨它们之间的关系。 虚拟化的基本类型 虚拟化可以...

    Qemu-windows.rar_qemu_qemu arm windows_qemu arm 仿真_qemu windows

    "Qemu-windows.rar_qemu_qemu arm windows_qemu arm 仿真_qemu windows"这个标题表明我们讨论的是如何在Windows系统上安装和使用Qemu来模拟ARM架构和Windows系统。Qemu的跨平台特性使得它能在Windows这样的非Linux...

    qemu-0.9.0-windows

    QEMU(Quick Emulator)是一款强大的开源虚拟化软件,它由法籍软件工程师Fabrice Bellard于2005年创建。QEMU这个名字是“快速模拟器”(Quick Emulator)的缩写,其设计目标是在不同的硬件平台上提供高性能的系统级...

    qemu下u-boot+kernel+rootfs完整启动移植手册

    在嵌入式开发中,QEMU 是一个非常流行的虚拟开发平台,它允许开发者在本地机器上模拟各种硬件环境,如 ARM 架构。本篇文章主要讲述了如何在 QEMU 下完成 u-boot、Linux 内核以及 rootfs 的完整启动移植过程。 首先...

Global site tag (gtag.js) - Google Analytics