qemu 是一个硬件虚拟化程序(hypervisor that performs hardware virtualization),与传统的 VMware / VirtualBox 之类的虚拟机不同,它可以通过 binary translation 模拟各种硬件平台(比如在 x86 机器上模拟 ARM 处理器)。而 VirtualBox 等更多是通过虚拟化来进行资源隔离,以便在其上运行多个 guest os。
基于 qemu 的硬件模拟能力,我们可以轻松搭建指定硬件平台的运行实验环境。

qemu 是一款支持多个 CPU 架构的虚拟机,支持如如 Alpha, ARM, Cris, i386, M68K, PPC, Sparc, Mips, Xtensa等;以及大部分的硬件设备,也就可以模拟出不同的目标系统。

Qemu 有两种运行模式,一种是全系统模拟(system mode),一种是用户态模拟(user mode)。从名字就可以看出来 system mode 肯定是模拟全了,可以直接跑操作系统之类的。user mode肯定就弱一点,跑个进程之类的。

1、安装依赖

$ sudo apt-get install -y git python3 python3-pip build-essential ninja-build pkg-config  libglib2.0-dev  libpixman-1-dev libslirp-dev

2、下载qemu源码

qemu当前正式发布版本为 v8.0.0

$ git clone https://github.com/qemu/qemu
$ git checkout v8.0.0
$ git submodule update --init --recursive

包内文件较多,下载需要较长时间,需要耐心等待下载完成。

3、编译

  • 获取支持的参数
$ ./configure --help
Using './build' as the directory for build output

Usage: configure [options]
Options: [defaults in brackets after descriptions]

Standard options:
  --help                   print this message
  --prefix=PREFIX          install in PREFIX [/usr/local]
  --target-list=LIST       set target list (default: build all)
                           Available targets: aarch64-softmmu alpha-softmmu 
                           arm-softmmu avr-softmmu cris-softmmu hppa-softmmu 
                           i386-softmmu loongarch64-softmmu m68k-softmmu 
                           microblaze-softmmu microblazeel-softmmu mips-softmmu 
                           mips64-softmmu mips64el-softmmu mipsel-softmmu 
                           nios2-softmmu or1k-softmmu ppc-softmmu ppc64-softmmu 
                           riscv32-softmmu riscv64-softmmu rx-softmmu 
                           s390x-softmmu sh4-softmmu sh4eb-softmmu 
                           sparc-softmmu sparc64-softmmu tricore-softmmu 
                           x86_64-softmmu xtensa-softmmu xtensaeb-softmmu 
                           aarch64-linux-user aarch64_be-linux-user 
                           alpha-linux-user arm-linux-user armeb-linux-user 
                           cris-linux-user hexagon-linux-user hppa-linux-user 
                           i386-linux-user loongarch64-linux-user 
                           m68k-linux-user microblaze-linux-user 
                           microblazeel-linux-user mips-linux-user 
                           mips64-linux-user mips64el-linux-user 
                           mipsel-linux-user mipsn32-linux-user 
                           mipsn32el-linux-user nios2-linux-user 
                           or1k-linux-user ppc-linux-user ppc64-linux-user 
                           ppc64le-linux-user riscv32-linux-user 
                           riscv64-linux-user s390x-linux-user sh4-linux-user 
                           sh4eb-linux-user sparc-linux-user 
                           sparc32plus-linux-user sparc64-linux-user 
                           x86_64-linux-user xtensa-linux-user 
                           xtensaeb-linux-user
  --target-list-exclude=LIST exclude a set of targets from the default target-list

Advanced options (experts only):
  --cross-prefix=PREFIX    use PREFIX for compile tools, PREFIX can be blank []
  --cc=CC                  use C compiler CC [cc]
  --host-cc=CC             use C compiler CC [cc] for code run at
                           build time
...

默认编译参数下,configure 会编译所有 ISA 的 QEMU,全量编译会耗时 20 分钟左右,其实很多时候我们不需要绝大多数 ISA,比如 Mips Sparc 的 QEMU 我是不关心的就可以不编译。configure --help 可以看到有个 --target-list 选项,可以用这个选项来指定需要的平台,平台名称之间用逗号分隔。

这次编译我们只编译 aarch64armriscv64riscv32 4个常用的平台。

$ ./configure --prefix=/opt/qemu --target-list=aarch64-softmmu,arm-softmmu,riscv32-softmmu,riscv64-softmmu
$ make -j8
$ make install

其中:

  • aarch64-softmmu:ARM64指令集
  • arm-softmmu:ARMv7指令集
  • riscv32-softmmu:RISC-V的32bit指令集
  • riscv64-softmmu:RISC-V的64bit指令集

编译完成后,目标文件在 /opt/qemu 目录下

$ cd /opt/qemu/bin
$ ls
qemu-edid  qemu-ga  qemu-img  qemu-io  qemu-nbd  qemu-pr-helper  qemu-storage-daemon  qemu-system-aarch64  qemu-system-arm  qemu-system-riscv32  qemu-system-riscv64

$ ./qemu-system-riscv64 --version
QEMU emulator version 8.0.0 (v8.0.0)
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers

4、运行

  1. 如果你不是自己编译qemu, 用的是别人编译好的目标文件,在运行中可能会出现依赖未安装的情况,执行一下命令:
$ sudo apt-get install -y libsnappy-dev libpixman-1-dev libpixman-1-dev libjpeg-dev libdaxctl-dev libvdeplug-dev libpmem-dev libgbm-dev libepoxy-dev libgtk-3-0 libaio1 libslirp-dev
  1. 添加环境变量
$ sudo apt-get install vim
$ vim ~/.bashrc

# 加入qemu位置
export PATH=$PATH:/opt/qemu/bin

$ source ~/.bash
$ qemu-system-riscv64 --version
QEMU emulator version 8.0.0 (v8.0.0)
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
  1. 运行qemu
qemu-system-aarch64 -m 2048 -cpu cortex-a57 -smp 2 -M virt -bios QEMU_EFI.fd -nographic \
-drive if=none,file=ubuntu-16.04.3-server-arm64.iso,id=cdrom,media=cdrom \
-device virtio-scsi-device \
-device scsi-cd,drive=cdrom \
-drive if=none,file=ubuntu16.04-arm64.img,id=hd0 \
-device virtio-blk-device,drive=hd0

退出当前运行的 qemu,使用组合键,CTRL + X,然后再按 A 键。

5、qemu参数

  1. 通过下面的命令获取对应 qemu 支持的参数:
$ qemu-system-riscv64 --help
QEMU emulator version 8.0.0 (v8.0.0)
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
usage: qemu-system-riscv64 [options] [disk_image]

'disk_image' is a raw hard disk image for IDE hard disk 0

Standard options:
-h or -help     display this help and exit
-version        display version information and exit

...

  • 开发板列表
    每个参数都可以获取对应的详细支持型号。如通过下面的命令操作可以看到当前版本的 Qemu 工具支持的开发板列表:
$ qemu-system-riscv64 -M help
Supported machines are:
microchip-icicle-kit Microchip PolarFire SoC Icicle Kit
none                 empty machine
shakti_c             RISC-V Board compatible with Shakti SDK
sifive_e             RISC-V Board compatible with SiFive E SDK
sifive_u             RISC-V Board compatible with SiFive U SDK
spike                RISC-V Spike board (default)
virt                 RISC-V VirtIO board

$ qemu-system-riscv32 -machine help
Supported machines are:
dummyh               THEAD dummyh
none                 empty machine
opentitan            RISC-V Board compatible with OpenTitan
sifive_e             RISC-V Board compatible with SiFive E SDK
sifive_u             RISC-V Board compatible with SiFive U SDK
smartl               RISC-V smartl
spike                RISC-V Spike board (default)
virt                 RISC-V VirtIO board
  1. qemu 常用参数
  • -M: 指定设备类型
  • -m: 指定内存大小; 如:-m 512M
  • -kernel: 指定内核文件; 如:-kernel linux-5.10.181/arch/riscv/boot/Image
  • -bios: 指定bios文件
  • -smp: 指定虚拟机核心数
  • -S: 冻结 CPU 直到远程 GDB 输入相应命令
  • -s: 启动 GDB 服务,在 1234 端口接受gdb调试; 如:-s -S-gdb tcp::1234 -S 选项用于启动 gdb 服务,启动后 qemu 不立即运行 guest,而是等待主机 gdb 发起连接,此时使用 gdb 输入 target remote:1234 可以进行相关调试,与真机调试无异。
  • -initrd:指定启动文件
  • -dtb: 指定dtb文件
  • -nographic: 指定不需要图形界面
  • -append:指定扩展显示界面,串口或者LCD,"console=ttyS0"和-nographic配合后,使得启动后的串口重定向到宿主机终端,能在宿主机的终端看到调试信息。如: -append “root=/dev/vda rw console=ttyS0”
  • -device:常用于指定guest上总线挂载的外部设备,例如virtio-mmio、usb、pci等总线
  • -netdev:配置网络设备

如:

#!/bin/sh

qemu-system-riscv64 \
-M virt \
-bios opensbi/build/platform/generic/firmware/fw_jump.elf \
-kernel linux-5.10.181/arch/riscv/boot/Image \
-append "rootwait root=/dev/vda ro" \
-drive file=buildroot-2023.02.1/output/images/rootfs.ext2,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-netdev user,id=net0 -device virtio-net-device,netdev=net0 \
-nographic
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐