实验平台信息:

首先编译X86版本和ARM版本两个平台的QEMU
1.获取代码:
wget https://download.qemu.org/qemu-4.1.0.tar.bz2
2.安装依赖:
sudo apt-get install build-essential pkg-config zlib1g-dev libglib2.0-0 libglib2.0-dev libsdl1.2-dev libpixman-1-dev libfdt-dev autoconf automake libtool librbd-dev libaio-dev flex bison libattr1-dev libcap-ng-dev libcap-dev
3.编译
./configure --target-list=arm-softmmu --audio-drv-list=alsa,pa --prefix=/home/caozilong/Workspace/qemu/install
接着执行 make -j4

4.生成DEB包
sudo apt-get install checkinstall
sudo checkinstall make install


5.安装结果

6.分析
由于HOST机是X86架构,所以这里的tcg-target.inc.c一定是X86目录下的tcg-target.inc.c文件。



ARM平台上:
arm平台上会使用arm目录的tcg-target.inc.c

原理方面,Qemu采用动态二进制翻译(Binary Translation)技术,能够支持多源(HOST)多目标(target)的跨平台仿真执行异构指令集,如下图所示,在有限的几个基础架构上,支持运行了远远超过基础架构数量的目标ISA架构。



如何判断target 目录和tcg目录各自的角色,可以根据const TranslatorOps对象的位置判断,此对象注册了对目标架构的指令ISA的翻译函数指针,它定义在target目录,自然也就是TARGE目录描述的是被模拟的目标指令架构:

也可以通过TCI目录的所在位置判断那个目录是HOST机(源机),因为它是通用目标ISA的解释器。TCI目录在tcg/tci下,自然和tci目录平级的架构目录都是源机目录。
helper和TCG的分派

TCG翻译引擎
KVM加速虚拟化过程虽然执行很快,但是要求目标平台和HOST平台为同一架构才有可能,而TCG引擎没有这个要求,TCG可以将目标机架构的二进制指令翻译为HOST指令,放到一片预先分配好的code_gen_buffer中,code_gen_buffer具有可执行权限,CPU可以执行放在其中的指令,用这种方式实现本地CPU加速。
带有可执行属性MAP的CODE_GEN_BUFFER分配过程:


可执行匿名区映射的例子:
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#define FILE_SIZE 0x4000
int add(int a, int b)
{
return a+b;
}
typedef int (*ptrfunc)(int, int);
int main(void)
{
int i;
unsigned int *maddr;
ptrfunc ptrf;
#if 0
maddr = mmap(NULL, FILE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
#else
maddr = mmap(NULL, FILE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
#endif
if(maddr == (void*)-1) {
printf("%s line %d, faild to map buffer, error %s.\n", __func__, __LINE__, strerror(errno));
return -1;
}
printf("%s line %d maddr = %p errno %s.\n", __func__, __LINE__, maddr, strerror(errno));
memcpy(maddr, add, 64);
ptrf = (ptrfunc)maddr;
printf("%s line %d, maddr = %p, maddr(5,6) = %d.\n", __func__, __LINE__, maddr, ptrf(5, 6));
for(i = 0; i < 16; i ++) {
maddr[i] = i;
printf("0x%02x ", maddr[i]);
}
printf("\n");
munmap((void *)maddr, FILE_SIZE);
return 0;
}

如果不支持KVM,则可以使能TCI,它会启动一个虚拟机解释器,这样可以兼容所有的架构:

当不配置--enable-tcg-interpreter时,TCG的后端是native x86_64.意思是说,将TARGET的指令集翻译为本地的x86_64指令,再交给本地CPU执行。

支持TCI的编译选项,当添加--enable-tcg-interpreter支持后,TCG的实现后端就发生了变化,此时的TCG后端成为了TCG with bytecode interpreter,也就是TARGET的指令依赖主机纯解释执行,解释器的效率是很低的,效率肯定打了折扣。
$ ./configure --target-list=arm-softmmu,aarch64-softmmu,i386-sof

本文详细介绍了Qemu在ARM和X86平台上的运行机制,特别是TCG(Tiny Code Generator)翻译引擎的工作原理。通过编译DEBUG版本的QEMU,分析了如何判断TCI是否开启,以及QEMU在不同后端模式下的表现。内容涵盖QEMU的编译、调试、VNC终端和虚拟机运行时的信息交互,同时讨论了软MMU的实现和GDB调试内核的方法。
最低0.47元/天 解锁文章
2121

被折叠的 条评论
为什么被折叠?



