Qemu在ARM和X86平台上的运行机制初探

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验平台信息:

首先编译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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

papaofdoudou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值