01 Ubuntu20.04下编译QEMU8.2.4,交叉编译32位ARM程序,运行ARM程序的方法

Ubuntu20.04下编译QEMU8.2.4,交叉编译32位ARM程序,运行ARM程序的方法

作者 将狼才鲸
创建日期 2025-06-02

一、编译与使用

1、源码编译

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} <v8.2.4> 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:
    • 自行修改的方法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 ,再换一个好心人提供的国内源
  • 你也可以试着先把全部代码拉下来,或者找到完整的国内镜像源,预先从外网拉取全量代码的步骤如下:

  • 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安装并运行虚拟机

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 <stdio.h>

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 <imagefile> <new-size>'
(note that this will lose data if you make the image smaller than it currently is).
相关推荐
小李做物联网10 分钟前
【物联网毕设】60.1基于单片机物联网嵌入式项目程序开发之智能家庭安防感应报警
stm32·单片机·嵌入式硬件·物联网
嵌入式郑工10 分钟前
UBUNTU开发环境下的一些实用的工具
linux·运维·ubuntu
洛克大航海11 分钟前
Ubuntu 安装 Docker
linux·docker·ubuntu24.04
沉在嵌入式的鱼16 分钟前
STM32--BH1750光敏传感器
stm32·单片机·嵌入式硬件·bh1750·光敏模块
zore_c16 分钟前
【C语言】文件操作详解3(文件的随机读写和其他补充)
c语言·开发语言·数据结构·笔记·算法
bai54593617 分钟前
STM32 单片机 按键控制led灯亮灭
stm32·单片机·嵌入式硬件
梦仔生信进阶21 分钟前
【Linux】使用小细节之删除软链接的正确方法Linux删除软连接的正确姿势:别让一个斜杠毁掉你的心血!
linux
Less is moree23 分钟前
2.C语言文件操作(一):fgetc(),fgets(),fread的区别
c语言·开发语言·算法
_lst_33 分钟前
linux进程控制
linux·运维·服务器
松涛和鸣34 分钟前
24、数据结构核心:队列与栈的原理、实现与应用
c语言·开发语言·数据结构·学习·算法