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).
相关推荐
GeW2 小时前
超详细!RHCE10版通用备考策略,内含评分细则解读
linux
用户041328465132 小时前
Linux 服务开机自启动怎么配置?systemctl enable 原理详解
linux
Freak嵌入式3 小时前
PIO 入门:手把手实现板载 LED 闪烁,原理与代码全解析
嵌入式
Freak嵌入式9 小时前
一文搞懂树莓派 Pico 任务调度器:基于定时器的 MicroPython 多任务实现
嵌入式
草莓熊Lotso11 小时前
【Redis 初阶】Set 类型深度解析:去重集合的运算能力与实战场景
linux·网络·数据库·windows·redis·tcp/ip·缓存
张文君11 小时前
ubuntu26.04坏道坏块分区隔离急速版260831-V0.12
linux·python
AOI小白新手上路20 小时前
江科协51单片机 17-2 红外遥控电机调速实验调试总结
单片机·嵌入式硬件·51单片机
贝锐20 小时前
从国产化信创设备到商用安卓终端,向日葵如何帮助企业实现统一运维管理?
linux·运维·远程控制
Julien200421 小时前
调查和解决 SELinux 问题
linux·运维·服务器·网络·学习方法
oshan20121 天前
零基础STM32入门教程--10-PWM 呼吸灯
stm32·单片机·嵌入式硬件