# QEMU模拟器源码中文注释 **Repository Path**: langcai1943/qemu ## Basic Information - **Project Name**: QEMU模拟器源码中文注释 - **Description**: 这个仓库的目的是使用中文对QEMU源码进行注释,并编写中文技术文档。 ~~~~ QEMU是一套由Fabrice Bellard所编写的模拟处理器的自由软件。它与Bochs,PearPC近似,但其具有某些后两者所不具备的特性,如高速度及跨平台的特性。经由kqemu这个开源的加速器,QEMU能模拟至接近真实电脑的速度。 - **Primary Language**: C - **License**: GPL-2.0 - **Default Branch**: comments_by_zj - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 62 - **Created**: 2025-05-29 - **Last Updated**: 2025-07-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README QEMU-v8.2.4源码中文注释与架构讲解 === *文档会不定期更新* |注释作者|将狼才鲸| |---|---| |创建日期|2025-05-30| |更新日期|2025-06-17| * CSDN阅读地址:[QEMU源码中文注释与架构讲解](https://blog.csdn.net/qq582880551/article/details/148346613) * Gitee源码仓库地址:[才鲸嵌入式/qemu](https://gitee.com/langcai1943/qemu) --- ## 一、前言 * 其它参考教程的网址: * [QEMU 源码目录简介](https://blog.csdn.net/BruceBaoZhiqiang/article/details/17912769):部分目录介绍,函数入口,主循环 * [qemu基本架构](https://blog.csdn.net/weixin_45774557/article/details/118574379):架构 * [[Basic] 01.QEMU 编译与启动](https://blog.csdn.net/weixin_44781249/article/details/147224176):各子模块详细讲解 * 共13篇 * [[TriCore] 01.QEMU 虚拟化 TriCore 架构中的寄存器 & 指令](https://blog.csdn.net/weixin_44781249/article/details/148224042) * [qemu 学习(一)————qemu整体流程解读](https://blog.csdn.net/robinblog/article/details/8876599):架构,重要的源文件,翻译,反汇编,移植,大小端 * 共6篇文章 * [qemu学习(四)————tcg操作码 分析](https://blog.csdn.net/robinblog/article/details/8911459) * [QEMU虚拟机关键源代码学习](https://blog.csdn.net/sdulibh/article/details/52106024):指令翻译过程,寻址转换,数据结构 * [QEMU源码分析系列(一)](https://blog.csdn.net/ustc_dylan/article/details/6784876):系列文章:QEMU简介,翻译过程,内存模型 * [qemu源码分析系列(二)](https://blog.csdn.net/ustc_dylan/article/details/6807731) * [QEMU源码分析系列(三)](https://blog.csdn.net/ustc_dylan/article/details/6827663) * [qemu源码分析之五-- TCG动态翻译技术](https://blog.csdn.net/ustc_dylan/article/details/6868050) * [qemu 内存模型(内存仿真概念)](https://blog.csdn.net/ustc_dylan/article/details/7326900) * [qemu用户态仿真代码分析](https://blog.csdn.net/ustc_dylan/article/details/7100439) * [qemu中ELF文件的加载](https://blog.csdn.net/ustc_dylan/article/details/7068190) * [qemu指令翻译过程(1)-- ADD指令](https://blog.csdn.net/ustc_dylan/article/details/7085200) * [qemu源码分析之Makefile](https://blog.csdn.net/ustc_dylan/article/details/6963256) * [Qemu快照(snapshot)机制原理及关键技术理解](https://blog.csdn.net/ustc_dylan/article/details/8807247) * [QEMU虚拟机(一)、源码分析概论](https://blog.csdn.net/weixin_38387929/article/details/120121636):系列文章:QEMU简述,KVM虚拟化 * [Linux虚拟化KVM-Qemu分析(一)虚拟化框架综述](https://blog.csdn.net/weixin_38387929/article/details/119938335) * 共10篇 * [Linux虚拟化KVM-Qemu分析(八)之virtio初探](https://blog.csdn.net/weixin_38387929/article/details/120656701) * [KVM学习笔记](https://www.bookstack.cn/read/learn-kvm/README.md):该教程里内容很多 * [Qemu架构解析(二)](https://blog.csdn.net/2401_84132496/article/details/138481259):流程简介 * [Qemu源码分析(1)—Apple的学习笔记](https://blog.51cto.com/AppleCai/7402306):系列教程 * [大总结:qemu第二轮源码学习--Apple的学习笔记](https://blog.51cto.com/AppleCai/7835439):文章目录 * 共11篇 * [Qemu源码分析(11)—Apple的学习笔记](https://blog.51cto.com/AppleCai/7701587) * [qemu源码解析一](https://blog.csdn.net/weixin_54452942/article/details/137627996):简介,初始化过程 * [qemu源码解析二](https://blog.csdn.net/weixin_54452942/article/details/137665403) * [qemu源码分析(一)-- QOM类创建流程](https://zhuanlan.zhihu.com/p/636763565):系列教程:初始化,函数调用,终端,寄存器,外设,参数,设备,编译,面向对象QOM * 共7篇 * [qemu源码分析(七)-- 中断处理之PPC系列](https://zhuanlan.zhihu.com/p/13748668988) * [QEMU 3.1.0 源码学习](https://abelsu7.top/2019/06/04/qemu-src-notes/):迁移,重要的源文件 * [《QEMU/KVM源码分析与应用》读书笔记1 —— 第1章 QEMU与KVM概述](https://phmatthaus.blog.csdn.net/article/details/127530240):要钱!系列文章,共174篇;简介,安装,参数,QOM,机器,外设,内存、CPU、设备虚拟化。 * [qemu学习笔记:QOM](https://blog.csdn.net/qq_44742941/article/details/147657297):抽象层,面向对象 * [菜鸡读QEMU源码](https://www.cnblogs.com/from-zero/p/12383652.html):架构,调用过程 * 书籍《QEMU&KVM源码解析与应用》 ## 二、整体介绍 ### 1、源码文件夹结构与简述 ```shell jim@virtual-pc:~/qemu$ tree -a -L 1 . ├── accel # 硬件加速器、纯软件翻译:kvm、xen、tcg ├── audio # 音频设备模拟 ├── authz # 授权框架,限制虚拟机对设备、API 或特定操作的访问权限 ├── backends # 后端实现:主机内存管理、TPM 后端 ├── BAK_README.rst # 原本仓库的readme文件 ├── block # 块设备:导出、IO、任务管理 ├── block.c ├── blockdev.c ├── blockdev-nbd.c ├── blockjob.c ├── bsd-user # BSD 用户模式模拟 ├── chardev # 字符设备模拟 ├── common-user # 用户模式公共代码 ├── configs # 编译相关 ├── configure # 配置脚本 ├── contrib # 社区贡献的辅助工具、脚本或第三方库 ├── COPYING # 开源信息 ├── COPYING.LIB # 开源信息相关 ├── cpu-common.c # 核心组件之一,主要负责 CPU 虚拟化的通用逻辑和基础功能实现 ├── cpu-target.c # 针对特定目标架构的 CPU 模型实现代码 ├── crypto # 加解密,数字签名 ├── .dir-locals.el # Emacs 编辑器 的本地目录变量配置文件 ├── disas # 反汇编器支持 ├── docs # 技术文档,英文的,而且对新手没什么用 ├── docs_中文 # 字节写的一些中文文档 ├── dump # 系统崩溃情况下调试用 ├── ebpf # 增强 QEMU 的调试、性能分析或安全监控能力 ├── .editorconfig # 配置文件,主要用于统一代码风格和编辑器设置 ├── event-loop-base.c # 实现事件循环基础框架的核心文件 ├── .exrc # Vi/Vim 编辑器的配置文件 ├── fpu # 浮点运算库 ├── fsdev # 文件系统设备 ├── .gdbinit # 调试器相关 ├── gdbstub # GDB 调试支持 ├── gdb-xml # # 调试器相关 ├── .git # git代码管理仓库 ├── .gitattributes # git代码管理对比工具配置 ├── .git-blame-ignore-revs # git代码管理相关 ├── gitdm.config # git代码管理相关 ├── .github # git代码管理服务器相关 ├── .gitignore # git代码管理忽略的文件信息配置 ├── .gitlab # git代码管理服务器相关 ├── .gitlab-ci.d # git代码管理服务器自动测试相关 ├── .gitlab-ci.yml # git代码管理服务器自动测试相关 ├── .gitmodules # git代码管理相关 ├── .gitpublish # git代码管理相关 ├── hmp-commands.hx # 定义HMP命令的源码。HMP是一种交互式监控接口 ├── hmp-commands-info.hx # 交互式监控接口相关 ├── host # 临时构建目录 ├── hw # 所有支持的硬件设备,硬件设备模拟的核心目录,按架构与设备类型分类 ├── include # 公用头文件:硬件、核心、C标准库 ├── io # IO通道实现 ├── iothread.c # IO线程的核心实现 ├── job.c # QEMU任务的核心实现 ├── job-qmp.c # 异步任务管理的QMP接口 ├── Kconfig # 源码编译相关 ├── Kconfig.host # 源码编译相关 ├── libdecnumber # 十进制浮点数运算库 ├── LICENSE # 开源信息相关 ├── linux-headers # Linux 内核相关的头文件 ├── linux-user # Linux 用户模式模拟 ├── .mailmap # git版本管理相关 ├── MAINTAINERS # 记录代码维护者信息 ├── Makefile # 编译参数相关,顶层构建文件 ├── memory_ldst.c.inc # 内存访问操作的实现 ├── meson.build # Meson构建系统的核心配置文件 ├── meson_options.txt # 系统构建相关 ├── migration # 虚拟机迁移相关 ├── module-common.c # 模块化系统的核心实现 ├── monitor # QEMU监控器 ├── nbd # 网络块设备支持 ├── net # 网络设备模拟 ├── os-posix.c # POSIX 操作系统兼容层的实现 ├── os-win32.c # 专门为 Windows 平台实现的辅助功能模块 ├── page-vary-common.c # 动态页面大小处理 相关的核心文件 ├── page-vary-target.c # 动态页面大小处理相关 ├── .patchew.yml # 与 Patchew 系统集成的配置文件 ├── pc-bios # BIOS和固件镜像 ├── plugins # 插件支持 ├── po # 国际化i18n支持 ├── python # Python 脚本和工具 ├── pythondeps.toml # Python相关 ├── qapi # QAPI 代码生成器 ├── qemu-bridge-helper.c # 实现用户态网络桥接助手的功能 ├── qemu-edid.c ├── qemu-img.c ├── qemu-img-cmds.hx ├── qemu-io.c ├── qemu-io-cmds.c ├── qemu-keymap.c ├── qemu-nbd.c ├── qemu.nsi ├── qemu-options.hx ├── qemu.sasl ├── qga # 宿主机-虚拟机通信 ├── qobject # 基础的面向对象组件 ├── qom # QEMU 对象模型,用C语言实现面向对象 ├── readme.md # 本仓库新增的主页说明文件 ├── .readthedocs.yml # 配置RTD在线文档托管服务的配置文件 ├── replay # 执行记录和回放 ├── replication.c # 块设备复制功能的实现核心 ├── roms # ROM 镜像 ├── scripts # 源码编译相关,构建和维护脚本 ├── scsi # SCSI磁盘等设备模拟 ├── semihosting # 半主机机制 ├── stats # 代码统计和性能分析相关工具 ├── storage-daemon # 存储守护进程 ├── stubs # 桩函数 ├── subprojects # 依赖的子项目 ├── system # 系统级虚拟化(全系统模拟),也是源码主入口(main函数所在位置) ├── target # QEMU目前所支持guset端的处理器架构,将该guest架构的指令翻译成TCG OP代码,里面的目录占源码总目的很大一部分 ├── tcg # 动态翻译工具tcg的源码部分,主要是将TCG OP转化为host binary的部分;也就是俗称的软件加速,而我们一般装Ubuntu这种大系统时需要选KVM、WHPX等硬件加速 ├── tests # 测试代码 ├── tools # 辅助工具 ├── trace # 跟踪支持 ├── trace-events # 跟踪相关 ├── .travis.yml # 配置 Travis CI(持续集成服务)的配置文件 ├── ui # 用户界面 (GTK, SDL, Cocoa 等) ├── util # 实用工具函数 ├── VERSION # 开源信息相关 ├── version.rc # 开源信息相关 └── .vscode # 编辑器相关 60 directories, 61 files jim@virtual-pc:~/qemu$ ``` ### 2、源码入口 * 第一行执行的代码,也就是main函数所在的位置 * qemu-system-xxx虚拟机/模拟器程序(如-arm、-x86_64)执行的第一行代码在源码 system/main.c 中的main()函数里 * 这是系统模式(模拟器、虚拟机),main() 函数会初始化虚拟硬件,然后开始启动虚拟 CPU 处理进程 * 主线程的创建与启动在虚拟 CPU 初始化函数中:target/i386/cpu.c(x86平台)、target/arm/cpu.c * qemu-xxx用户模式模拟器(如qemu-arm,直接运行Linux的应用程序)执行的第一行代码在linux-user/main.c的main()函数里面 * 参考:所有包含了main.c文件 + main()函数的位置: ```shell jim@virtual-pc:~/qemu$ find . -name main.c ./contrib/ivshmem-client/main.c # contrib是第三方库所在的文件,不算 ./contrib/elf2dmp/main.c ./contrib/vhost-user-input/main.c ./contrib/rdmacm-mux/main.c ./contrib/ivshmem-server/main.c ./system/main.c # QEMU 系统模式如qemu-system-arm程序的主入口点,负责初始化虚拟机的核心逻辑。它是模拟完整物理机器(如x86、ARM)时的关键组成部分。 ./pc-bios/vof/main.c # PowerPC(ppc64)架构相关 ./pc-bios/s390-ccw/main.c ./linux-user/main.c # 用户模式的启动入口。当运行命令如qemu- ./binary 时,程序从这里开始初始化,加载并执行目标架构的二进制文件(例如在x86主机上运行ARM程序) ./qga/main.c # 实现客户机代理功能,即用于与宿主机端的QEMU监控程序进行通信 ./bsd-user/main.c # BSD用户模式模拟的入口点,针对的是BSD类操作系统(如FreeBSD、NetBSD、OpenBSD等) jim@virtual-pc:~/qemu$ ``` * 在 system/main.c 中,main() 函数是一个简单的封装,调用 qemu_main() 函数,而后者负责实际的循环工作 * qemu_init():负责全局初始化(如设备注册、内存管理、加速器配置等),并启动CPU线程。 * qemu_main_loop():进入主事件循环,处理各种用户或输入触发的事件。 * qemu_cleanup():在退出时执行清理工作。 * 解析命令行参数(如 -machine、-kernel 等),调用初始化函数 * system/vl.c 承担核心工作:初始化、启动主线程 * 源码的层级调用关系,详见子文档: * [103_函数调用关系.md](https://gitee.com/langcai1943/qemu/blob/comments_by_zj/docs_中文/103_函数调用关系.md) * 简述如下: ```c main() system\main.c qemu_init() system\vl.c qemu_create_machine() system\vl.c current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class))); 没找到MACHINE的实现 system\vl.c object_new_with_class() or object_new() or object_new_with_props()/object_new_with_propv() qom\object.c object_new_with_type() qom\object.c object_initialize_with_type() qom\object.c type_initialize() ti->class_init(ti->class, ti->class_data); qom/object.c arm_cpu_register_types() 只是把结构体加到Class里 type_register_static(&arm_cpu_type_info); target\arm\cpu.c struct TypeInfo arm_cpu_type_info: .class_init = arm_cpu_class_init, target\arm\cpu.c arm_cpu_class_init() target\arm\cpu.c arm_cpu_realizefn() target\arm\cpu.c qemu_init_vcpu() cpus_accel->create_vcpu_thread(cpu); system\cpus.c tcg_accel_ops_init(): 只是赋值函数指针 ops->create_vcpu_thread = rr_start_vcpu_thread; accel\tcg\tcg-accel-ops.c rr_start_vcpu_thread() accel\tcg\tcg-accel-ops-rr.c qemu_thread_create(rr_cpu_thread_fn) accel\tcg\tcg-accel-ops-rr.c pthread_create() 启动主线程 //pthread线程库 object_initialize_with_type() qom\object.c object_class_property_init_all() 调用ObjectProperty *prop->init(obj, prop); 其中ARM开发板下这个init()函数是arm_cpu_register_types target\arm\cpu.c 执行的->init初始化模拟器/开发板 qemu_main() system\main.c qemu_default_main() system\main.c qemu_main_loop() system\runstate.c // 响应用户操作 qemu_cleanup ``` * 要弄清楚源码的结构,严重依赖于对QOM(C语言实现的面向对象的基础组件)的理解 * 先要对面向对象有一个模糊的概念: * 本仓库子文档:[C++相比于C语言增加了哪些概念?](https://gitee.com/langcai1943/qemu/tree/comments_by_zj/demo_代码示例/02_C++_Class/00_C++相比于C语言增加了哪些概念.md) * 其中的代码示例:[demo_代码示例/02_C++_Class](https://gitee.com/langcai1943/qemu/tree/comments_by_zj/demo_代码示例/02_C++_Class) ## 三、编译与使用 ### 1、源码编译 * 参考网址: * [ubuntu20.04源码编译安装qemu(qemu8.2)](https://blog.csdn.net/qq_38393271/article/details/141347415) * 本机系统: ```shell jim@virtual-pc:~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.6 LTS Release: 20.04 Codename: focal jim@virtual-pc:~$ ``` * 本机源码: * 截止到2025-06-01时的稳定版分支v8.2.4的源码 * 如果你不介意版本是否稳定,也可以直接在v9.0.0 tag的基础上进行修改; * QEMU官网虽然已经能下载v10.0.2和v9.2.4的软件了,但是源码仓库里还没有这2个标签,并且官网源码的最后上传时间是一年前。 ```2024-05-13 08:29 +0300 Michael Tokarev o─{origin/stable-8.2} {origin/staging-8.2} Update version for 8.2.4 release``` * 编译过程: * 1、提前修改编译过程中需要联网拉取的gitlab.com网站中的子git仓库的国内Gitee源(本仓库内我已修改好了,请在本文章最上方的Gitee源码链接下拉取改好的QEMU仓库) * 如果你能登上gitlab.com,则请忽略此步骤; * 如果你没使用梯子,则编译配置时需要拉取源码,然后因为gitlab网站被墙导致失败; * 具体需要的子仓库是:gitlab.com/qemu-project/seabios.git SLOF.git ipxe.git openbios.git qemu-palcode.git u-boot.git skiboot.git QemuMacDrivers.git seabios-hppa.git u-boot-sam460ex.git edk2.git opensbi.git qboot.git vbootrom.git libvirt-ci.git * 自行修改的方法1: * 把QEMU仓库里的所有 https://gitlab.com/qemu-project/ 字符串替换为 https://gitee.com/tinylab/qemu- * 自行修改的方法2: * 主要是.gitmodules文件中、subprojects/ 文件夹下、tests/文件夹下的非gitlab.com/qemu-project/qemu.git 部分不替换会出错(编译时qemu.git源码我们肯定已经拉取了,是其它仓库造成的编译时预配置不通过),子模块拉不下来; * 将 .gitmodules 文件中所有 gitlab.com/qemu-project/ 替换成 gitee.com/tinylab/qemu- * 将 subprojects\ 文件夹下所有 .wrap 文件中的 gitlab.com/qemu-project/ 替换成 gitee.com/tinylab/qemu- * 具体包括: * subprojects\keycodemapdb.wrap * subprojects\berkeley-softfloat-3.wrap * subprojects\dtc.wrap * subprojects\libvfio-user.wrap * 将 tests\ 文件夹下所有 .wrap 文件中的 gitlab.com/qemu-project/ 替换成 gitee.com/tinylab/qemu- * 具体包括: * tests\avocado\acpi-bits.py * tests\qtest\fuzz-lsi53c895a-test.c * tests\qtest\fuzz-megasas-test.c * tests\qtest\fuzz-sdcard-test.c * tests\qtest\intel-hda-test.c * tests\tcg\aarch64\mte-7.c * tests\tcg\aarch64\test-2150.c * tests\tcg\aarch64\test-2248.c * 如果上述国内镜像仓库也失效的话,则在Gitee网站搜索 qemu-project ,再换一个好心人提供的国内源 * 你也可以试着先把全部代码拉下来,或者找到完整的国内镜像源,预先从外网拉取全量代码的步骤如下: * git clone https://gitlab.com/qemu-project/qemu.git * cd qemu * git submodule init * git submodule update --recursive * 2、因少数非关键国内源子仓库版本不匹配,编译不通过,需要修改 tests\fp\meson.build 文件 * (本仓库内我已修改好了,请在本文章最上方的Gitee源码链接下拉取改好的QEMU仓库) * 如果你能登上gitlab.com,则请忽略此步骤; * 国内镜像子仓库里源码版本的同步时间不是我当前时间,和qemu-project中的实际仓库的内容不同步,我这里遇到的是berkeley-testfloat-3.git编译报错 * 将 tests\fp\meson.build 文件中第32行到35行、第47到52行、第108到源码最后的143行前面加上#井号来屏蔽脚本 * 这部分内容本来也是测试用例,删掉不影响实际使用 * 3、更新软件包索引 * ```sudo apt update``` * 4、安装编译时依赖的软件和库(必须要先装) * ```sudo apt install gcc make python3-venv python3-pip ninja-build libglib2.0-dev flex bison libcapstone-dev libfdt-dev device-tree-compiler``` * 5、使用python环境安装软件包 * ```pip3 install Sphinx sphinx_rtd_theme``` * 6、进行编译前的配置: * ```cd ~/qemu``` # 进入源码目录 * ```mkdir build``` * ```cd build``` * ```../configure``` # 配置为全部目标进行编译 * 以下是执行过程: ```shell jim@virtual-pc:~$ cd ~/qemu jim@virtual-pc:~/qemu$ mkdir build jim@virtual-pc:~/qemu$ cd build jim@virtual-pc:~/qemu/build$ ../configure python determined to be '/usr/bin/python3' python version: Python 3.8.10 mkvenv: Creating non-isolated virtual environment at 'pyvenv' mkvenv: checking for tomli>=1.2.0 mkvenv: installing tomli>=1.2.0 mkvenv: checking for meson>=0.63.0 mkvenv: installing meson==1.2.3 mkvenv: checking for sphinx>=1.6 mkvenv: checking for sphinx_rtd_theme>=0.5 The Meson build system …… Subprojects berkeley-softfloat-3 : YES keycodemapdb : YES libvduse : YES libvhost-user : YES User defined options Native files : config-meson.cross docs : enabled plugins : true Found ninja-1.10.0 at /usr/bin/ninja Running postconf script '/home/jim/qemu/build/pyvenv/bin/python3 /home/jim/qemu/scripts/symlink-install-tree.py' jim@virtual-pc:~/qemu/build$ ``` * 因为我只需要32位ARM平台的工具,所以我实际使用的命令是:```../configure --target-list=arm-softmmu,arm-linux-user``` * 7、编译: * ```make -j4``` # 使用4进程编译;你的电脑是几核就配成几,也可以多配 ```shell jim@virtual-pc:~/qemu/build$ make -j4 [1/52] Generating tests/include/QAPI test (include) with a custom command [2/20] Generating qemu-version.h with a custom command (wrapped by meson to capture output) jim@virtual-pc:~/qemu/build$ ``` * 8、将编译好的 qemu-system-arm 等应用程序安装到Ubuntu系统内: * ```sudo make install``` ```shell jim@virtual-pc:~/qemu/build$ sudo make install [1/20] Generating qemu-version.h with a custom command (wrapped by meson to capture output) [1/2] Installing files. Installing subdir /home/jim/qemu/build/docs/manual to /usr/local/share/doc/qemu …… Installing /home/jim/qemu/pc-bios/keymaps/sv to /usr/local/share/qemu/keymaps jim@virtual-pc:~/qemu/build$ ``` * 9、测试程序的使用(查看版本号): * ```qemu-system-arm --version``` ```shell jim@virtual-pc:~/qemu/build$ qemu-system-arm --version QEMU emulator version 8.2.4 (v8.2.4-9-g953cc60a63-dirty) Copyright (c) 2003-2023 Fabrice Bellard and the QEMU Project developers jim@virtual-pc:~/qemu/build$ ``` ### 2、使用1:QEMU安装并运行虚拟机 * 步骤详见: * [Windows10下使用QEMU安装Ubuntu20.04虚拟机,并启用硬件加速](https://gitee.com/langcai1943/qemu/blob/comments_by_zj/docs_中文/101_Windows10下使用QEMU安装Ubuntu20.04虚拟机.md) ### 3、使用2:直接运行目标平台程序 * 我编译生成的是32位ARM平台的QEMU,所以我不能直接在Ubuntu上使用GCC编译程序后再在QEMU中运行运行,而需要使用ARM交叉编译工具编完后再用qemu-system-arm来运行; * ARM交叉编译工具介绍: |交叉编译工具名|目的| |---|---| |arm-none-eabi-gcc|供裸机如Cortex-M3板子使用,不能使用fork()等系统类函数,不能编Linux应用| |arm-linux-gnueabi-gcc|用于编译u-boot、Linux内核、linux应用,支持armel软浮点,32位| |arm-linux-gnueabihf-gcc|支持armhf硬浮点,64位| |arm-eabi-gcc|Android ARM 编译器| |armcc|供Keil使用,编译裸机程序,不能编译Linux应用| |arm-none-uclinuxeabi-gcc|用于其它系统:uCLinux| |arm-none-symbianelf-gcc|用于其它系统:symbian| |带芯片厂商名字或由芯片厂商单独提供|芯片原厂基于上述源码定制的交叉编译工具| * 1)安装32位ARM交叉编译工具: * ```sudo apt install gcc-arm-linux-gnueabi``` * 2)查看安装结果 * ```arm-linux-gnueabi-gcc --version``` ```shell jim@virtual-pc:~/qemu$ arm-linux-gnueabi-gcc --version arm-linux-gnueabi-gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. jim@virtual-pc:~/qemu$ ``` * 3)编译要测试的程序 * ```cd ~/qemu``` # 进入源码目录 * ```mkdir demo``` * ```cd demo``` * ```touch main.c``` # 创建源码文件 * ```gedit main.c``` * main.c文件中加入内容: ```c #include int main() { printf("Hello World!\n"); fflush(stdout); while(1); return 0; } ``` * 继续: * ``` arm-linux-gnueabi-gcc -o hello main.c -static``` # 编译生成hello程序(必须使用静态库) * ```file hello``` # 查看架构是否正确 * ```jim@virtual-pc:~/qemu/demo$ file hello``` * ```hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, BuildID[sha1]=e02cd9a7928171b8c7631f7ef83182807a45ccf4, for GNU/Linux 3.2.0, not stripped``` * ```qemu-arm hello``` # 使用qemu运行程序 * ```jim@virtual-pc:~/qemu/demo$ qemu-arm hello``` * ```Hello World!``` * 不能使用运行操作系统镜像的qemu-system-arm程序: ```shell jim@virtual-pc:~/qemu/demo$ qemu-system-arm -machine raspi2b hello WARNING: Image format was not specified for 'hello' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. qemu-system-arm: Invalid SD card size: 509 KiB SD card size has to be a power of 2, e.g. 512 KiB. You can resize disk images with 'qemu-img resize ' (note that this will lose data if you make the image smaller than it currently is). ``` ### 4、修改源码,并查看是否生效 * 1)在system/main.c文件的main()函数中加入一行: * ```printf("(build time: %s %s, for system)main entry: file: %s, line: %d\n", __DATE__, __TIME__, __FILE__, __LINE__);``` * 2)进入qemu/build目录执行make命令 ```shell jim@virtual-pc:~/qemu/build$ make /home/jim/qemu/build/pyvenv/bin/meson introspect --targets --tests --benchmarks | /home/jim/qemu/build/pyvenv/bin/python3 -B scripts/mtest2make.py > Makefile.mtest [1/53] Generating qemu-version.h with a custom command (wrapped by meson to capture output) [2/50] Compiling C object qemu-system-arm.p/system_main.c.o [3/50] Linking target qemu-system-arm [4/50] Compiling C object libqemu-arm-linux-user.fa.p/linux-user_main.c.o [5/50] Linking target qemu-arm [6/50] Compiling C object qga/qemu-ga.p/main.c.o [7/50] Linking target qga/qemu-ga [8/50] Compiling C object qemu-img.p/qemu-img.c.o [9/50] Linking target qemu-img [10/50] Compiling C object qemu-io.p/qemu-io.c.o [11/50] Linking target qemu-io [12/50] Compiling C object qemu-nbd.p/qemu-nbd.c.o [13/50] Linking target qemu-nbd [14/50] Compiling C object storage-daemon/qemu-storage-daemon.p/qemu-storage-daemon.c.o [15/50] Linking target storage-daemon/qemu-storage-daemon [16/50] Compiling C object qemu-pr-helper.p/scsi_qemu-pr-helper.c.o [17/50] Linking target qemu-pr-helper [18/50] Generating tests/include/QAPI test (include) with a custom command jim@virtual-pc:~/qemu/build$ jim@virtual-pc:~/qemu/build$ find . -name qemu-system-arm ./arm-softmmu/qemu-system-arm ./qemu-system-arm ./qemu-bundle/usr/local/bin/qemu-system-arm jim@virtual-pc:~/qemu/build$ ls ./arm-softmmu/qemu-system-arm -l lrwxrwxrwx 1 jim jim 18 6月 1 20:16 ./arm-softmmu/qemu-system-arm -> ../qemu-system-arm jim@virtual-pc:~/qemu/build$ ls ./qemu-bundle/usr/local/bin/qemu-system-arm -l lrwxrwxrwx 1 jim jim 36 6月 1 00:16 ./qemu-bundle/usr/local/bin/qemu-system-arm -> /home/jim/qemu/build/qemu-system-arm jim@virtual-pc:~/qemu/build$ ls -l ./qemu-system-arm -rwxrwxr-x 1 jim jim 115438744 6月 2 13:21 ./qemu-system-arm jim@virtual-pc:~/qemu/build$ ``` * 3)运行你刚刚生成的```./qemu-system-arm --version```查看效果 * 这一行命令的执行需要在qemu/build目录下 * 这一行内容的实际信息也能防止你改完源码后没运行到刚刚编译的程序,实际运行了已安装在系统中的旧程序; ```shell jim@virtual-pc:~/qemu/build$ ./qemu-system-arm --version (Jun 2 2025 13:21:18)main entry: file: ../system/main.c, line: 53 QEMU emulator version 8.2.4 (v8.2.4-13-g8fdc46628f-dirty) Copyright (c) 2003-2023 Fabrice Bellard and the QEMU Project developers jim@virtual-pc:~/qemu/build$ ``` * 4)或者修改linux-user/main.c文件,之后用qemu-arm --version来验证是否生效 ```shell jim@virtual-pc:~/qemu/build$ make [1/19] Generating qemu-version.h with a custom command (wrapped by meson to capture output) [2/3] Compiling C object libqemu-arm-linux-user.fa.p/linux-user_main.c.o [3/3] Linking target qemu-arm jim@virtual-pc:~/qemu/build$ ls -l qemu-arm -rwxrwxr-x 1 jim jim 25443984 6月 2 13:41 qemu-arm jim@virtual-pc:~/qemu/build$ ./qemu-arm --version (build time: Jun 2 2025 13:41:49, for user bin)main entry: file: ../linux-user/main.c, line: 689 qemu-arm version 8.2.4 (v8.2.4-13-g8fdc46628f-dirty) Copyright (c) 2003-2023 Fabrice Bellard and the QEMU Project developers jim@virtual-pc:~/qemu/build$ ``` ## 四、源码整体框架讲解 ## 五、各子模块讲解 ### 1、TCG动态翻译生成器 * QEMU 的核心组件,负责将客户机(Guest)的CPU指令动态翻译为主机(Host)可执行的CPU指令; * 参考网址: * [[TCG] 01.QEMU TCG 概览](https://blog.csdn.net/weixin_44781249/article/details/148122805) ## 六、自行添加其它模块代码 ### 1、添加调试打印信息输出控制模块 ## 七、实战:加入一款芯片的模拟器功能