侧边栏壁纸
博主头像
landery博主等级

行李箱里装不下我想去的远方

  • 累计撰写 42 篇文章
  • 累计创建 24 个标签
  • 累计收到 6 条评论

目 录CONTENT

文章目录

可信计算_Qemu01_VMWare上使用Qemu7.0.0 实现X86_64系统上运行ARM架构虚拟机

landery
2022-05-17 / 2 评论 / 5 点赞 / 223 阅读 / 5,117 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-05-23,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1 计划

Qemu就算不用KVM,也有自己的一套虚拟化逻辑,我们就利用Qemu来实现在X86_64架构的服务器上利用Qemu跑起来ARM架构虚拟机。顺便学习Qemu。
最终目的,实现Qemu+KVM的虚拟机中添加vTPM支持。

  • 利用Qemu实现X86_64系统上运行ARM虚拟机,学习Qemu
  • 使用Qemu-KVM同样的搭建虚拟机,学习KVM
  • 添加vTPM支持,实现可信虚拟机

2 实验前准备

本实验用的是Win11上的WMware,在其中创建了CentOS 7的虚拟机,然后再在虚拟机里面使用Qemu再创建虚拟机。采用的最新版的Qemu 7.0.0

采用VMWare实现,需要开启虚拟化功能:
image-1652759080095

进入CentOS 7后查看CPU架构等信息 lscpu

[root@centos7 ~]# lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    1
Core(s) per socket:    1
座:                 4
NUMA 节点:         1
厂商 ID:           GenuineIntel
CPU 系列:          6
型号:              158
型号名称:        Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
步进:              10
CPU MHz:             2808.002
BogoMIPS:            5616.00
虚拟化:           VT-x
超管理器厂商:  VMware
虚拟化类型:     完全
L1d 缓存:          32K
L1i 缓存:          32K
L2 缓存:           256K
L3 缓存:           9216K
NUMA 节点0 CPU:    0-3

3 Qemu下载

我们将所有东西放在 /opt 目录下

cd /opt
wget https://download.qemu.org/qemu-7.0.0.tar.xz
tar -xvJf qemu-7.0.0.tar.xz #解压

其中wget 使用的下载的链接可在官方下载地址查找 https://download.qemu.org/

4 编译运行

4.1先安装依赖

`yum install zlib-devel glib* automake libtool pixman-devel`

这里说一下源码编译的过程,可以查看Qemu编译过程中的信息,一般通过源码编译安装软件包都要运行下面三条命令:

  • ./configure
  • make
  • make install

./configure 是一个脚本会自动检查系统环境,比如编译构建工具是否齐全,源码目录,依赖库目录,安装目录等,系统平台和架构信息,其他编译选项等。这些信息可以保持默认或通过参数传递给 configure。然后configure会根据这些信息生成一个 Makefile文件。./configure -h 可以查看它的帮助文档。
make 命令会根据Makefile中的信息真正开始编译过程。make有一个重要的参数-j可以用来指定编译过程可以同时并行多少任务,一般多核 CPU 可以将该参数指定为 CPU 核数来加快编译。
make install 是将编译好的二进制文件安装到系统上。

编译Qemu之前我们可以查看一下Qemu可以配置的参数:

cd  /opt/qemu-7.0.0
./configure -h
[root@centos7 qemu-7.0.0]# ./configure -h
Standard options:
  --help                   print this message
  --prefix=PREFIX          install in PREFIX [/usr/local]
  --interp-prefix=PREFIX   where to find shared libraries, etc.
                           use %M for cpu name [/usr/gnemul/qemu-%M]
  --target-list=LIST       set target list (default: build all)
                           Available targets: aarch64-softmmu alpha-softmmu
                           i386-softmmu m68k-softmmu microblazeel-softmmu
							......
  --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]
  --iasl=IASL              use ACPI compiler IASL [iasl]
  --host-cc=CC             use C compiler CC [cc] for code run at
  .......

Optional features, enabled with --enable-FEATURE and
disabled with --disable-FEATURE, default is enabled if available
(unless built with --without-default-features):
  .....
  kvm             KVM acceleration support
  sdl             SDL user interface
  tpm             TPM support
  vnc             VNC server
  vnc-jpeg        JPEG lossy compression for VNC server
  vnc-png         PNG compression for VNC server
  vnc-sasl        SASL authentication for VNC server
  vte             vte support for the gtk UI
  ......

我们只列出了一部分参数,我大致可以知道我们能指定要生成 QEMU 的平台版本,比如 x86 和 arm。还可以指定需要附加功能,其中比较重要的是 sdl、vnc,还可以启用TPM支持kvm等这些在后面都会使用到。

4.2 configure

QEMU 默认编译生成所有平台的版本,为了加快编译速度,我们只选择我们要用到的ARM64: aarch64-softmmu,使用--target-list 指示。

编译命令如下:

./configure --target-list=aarch64-softmmu --enable-vnc --enable-sdl

参数讲解 :
--target-list=aarch64-softmmu,我们最终要运行的虚拟机的架构ARM64
--enable-sdl,用户接口用生成的 QEMU 创建的虚拟机没有画面。启动虚拟机时只会显示一行:VNC server running on127.0.0.1:5900,这样你就只能通过 VNC 访问虚拟机了。下面介绍VNC连接
--enable-vnc, VNC Server,虚拟机启动后可以用VNC连接

报错:python版本必须大于3.6

[root@centos7 qemu-7.0.0]# ./configure --target-list=aarch64-softmmu --enable-vnc --enable-sdl
Using './build' as the directory for build output

ERROR: Cannot use '/usr/bin/python', Python >= 3.6 is required.
       Use --python=/path/to/python to specify a supported Python.

继续修改命令,发现本地安装有python3.6.8 指定python版本--python=/usr/bin/python3

[root@centos7 qemu-7.0.0]# ./configure --target-list=aarch64-softmmu --enable-vnc --enable-sdl --python=/usr/bin/python3
Using './build' as the directory for build output

ERROR: Cannot find Ninja

原因:新版本的qemu编译依赖ninja,所以需要先安装ninja,如果不安装ninja

4.2.1 安装ninja

  1. 安装编译依赖
    yum -y install git automake gcc+ gcc-c++ libtool

  2. 获取源码、并编译安装

    git clone https://github.com/skvadrik/re2c.git re2c 
    cd re2c
    mkdir -p m4
    ./autogen.sh && ./configure --prefix=/usr && make
    sudo make install
    

    git clone https://github.com/skvadrik/re2c.git re2c 可能报错:

    [root@centos7 opt]# wget  https://github.com/skvadrik/re2c.git
     --2022-05-17 16:07:13--  https://github.com/skvadrik/re2c.git
     正在解析主机 github.com (github.com)... 20.205.243.166
     正在连接 github.com (github.com)|20.205.243.166|:443... 失败:拒绝连接。
    

    因为github在国内访问受限,我能访问官网并下载zip,但是不能通过clone的方式,
    所以这里我们就直接下载zip上传到虚拟机中解压即可。

  3. 检查是否安装成功
    re2c -v

    [root@centos7 re2c]# re2c -v
    re2c 3.0
    

    官方安装文档:http://re2c.org/install/install.html

  4. 安装ninja,ninja官网地址:https://ninja-build.org/,github仓库地址:https://github.com/ninja-build/ninja,可以从github仓库克隆项目切换到release分支或者下载release包,目前最新版是1.11.0,安装同样先下载到本地在上传至虚拟机,统一放到opt目录:

    unzip ninja-1.11.0.zip
    cd ninja-1.11.0
    ./configure.py --bootstrap
    cp ninja /usr/bin/
    
  5. 验证ninja是否安装成功
    ninja -h 查看帮助文档

现在我们已经安装好了ninja,继续qemu安装

cd /opt/qemu-7.0.0
./configure --target-list=aarch64-softmmu --enable-vnc --enable-sdl --python=/usr/bin/python3

报错,由于安装的qemu版本太高了,他需要GCC至少7.4版本

[root@centos7 qemu-7.0.0]# ./configure --target-list=aarch64-softmmu --enable-vnc --enable-sdl --python=/usr/bin/python3
Using './build' as the directory for build output

ERROR: You need at least GCC v7.4 or Clang v6.0 (or XCode Clang v10.0)

查看gcc版本:4.8.5
image-1652776522710

4.2.2 升级gcc版本

升级gcc版本:参考CentOS系统升级gcc/c++到7.5/10.2版本

  • 下载高版本gcc

    cd /opt
    wget https://gcc.gnu.org/pub/gcc/releases/gcc-7.5.0/gcc-7.5.0.tar.gz --no-check-certificate
    tar -zxvf /opt/gcc-7.5.0.tar.gz -C /usr/local/src
    cd /usr/local/src/gcc-7.5.0/
    
  • 安装编译所需要的依赖环境
    ./contrib/download_prerequisites

    报错:缺少bzip2

    tar (child): lbzip2:无法 exec: 没有那个文件或目录
    tar (child): Error is not recoverable: exiting now
    tar: Child returned status 2
    tar: Error is not recoverable: exiting now
    error: Cannot extract package from gmp-6.1.0.tar.bz2
    

    解决:yum install bzip2

    image-1652777447355

  • 建立临时文件夹并进行编译安装

    mkdir gcc-7.5-build
    cd gcc-7.5-build
    ../configure -enable-checking=release  -enable-languages=c,c++  -disable-multilib 
    make -j4 # 这一步需要很久的时间
    make  install
    
    #备份旧gcc二进制文件,并进行替换
    mv /usr/bin/gcc /usr/bin/gcc.bckup
    ln -s /usr/local/bin/gcc /usr/bin/gcc
    reboot   ##重启
    gcc  -v    ##查看gcc/c++版本
    

    image-1652784219103

    可以看到已经是7.5.0版本的了,但是还没结束。

  • 替换老版本gcc的动态库

    1、首先检查动态库是否为老版本的
    strings /usr/lib64/libstdc++.so.6 | grep GLIBC
    升级gcc的时候,新版的gcc动态库并没有替换老版本gcc的动态库,所以这里我们需要手动进行替换升级!
    2、先查找新版gcc生成的动态库位置
    find / -name "libstdc++.so*"

    image-1652784498654

    3、将新版gcc动态库libstdc++.so.6.0.24复制到/usr/lib64目录下

    cd /usr/lib64/
    cp /usr/local/src/gcc-7.5.0/gcc-7.5-build/stage1-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.24  ./
    

    4、将旧版动态库备份,然后将默认库的软链接指向最新版的gcc动态库

    mv libstdc++.so.6   libstdc++.so.6.bak
    ln -s libstdc++.so.6.0.24   libstdc++.so.6
    

    5、指完之后再检查动态库
    strings /usr/lib64/libstdc++.so.6 | grep GLIBC

现在我们已经升级完成,再次执行qemu命令

cd /opt/qemu-7.0.0
./configure --target-list=aarch64-softmmu --enable-vnc --enable-sdl --python=/usr/bin/python3

又出现报错:

Run-time dependency sdl2 found: NO (tried pkgconfig and config-tool)
../meson.build:842:2: ERROR: Dependency "sdl2" not found, tried pkgconfig and config-tool
A full log can be found at /opt/qemu-7.0.0/build/meson-logs/meson-log.txt
ERROR: meson setup failed

原因: 缺少sdl2

4.2.3 centos 7 安装 sdl2

  1. wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
  2. 安装以下依赖
    • yum install SDL2_gfx-devel.x86_64
    • yum install SDL2_image-devel.x86_64
    • yum install SDL2_ttf-devel.x86_64
    • yum install SDL2.x86_64

安装成功,继续configure

cd /opt/qemu-7.0.0
./configure --target-list=aarch64-softmmu --enable-vnc --enable-sdl --python=/usr/bin/python3

可以发现已经成功了。

4.3 make编译

make -j4
4核 , -j4加快编译。

4.4 安装

make install

成功了,我们来验证一下。

[root@centos7 qemu-7.0.0]# qemu-img --version
qemu-img version 7.0.0
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
[root@centos7 qemu-7.0.0]# qemu-system-aarch64 --version
QEMU emulator version 7.0.0
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers

5 UEFI下载和操作系统镜像下载

UEFI下载链接:
http://releases.linaro.org/components/kernel/uefi-linaro/16.02/release/qemu64/
这里我们用的是ubuntu 16.04 ARM版本的操作系统
https://old-releases.ubuntu.com/releases/16.04.3/

ubuntu-16.04.2-server-arm64.iso

6 创建虚拟硬盘

利用qemu-img指令可以创建1个空的虚拟硬盘,便于后面安装的时候将系统安装到虚拟硬盘上。
qemu-img create ubuntu16.04-arm64.img 16G

7 虚拟机安装

qemu-system-aarch64 -m 2048 -cpu cortex-a57 -smp 2 -M virt -bios QEMU_EFI.fd -nographic -drive if=none,file=ubuntu-16.04.2-server-arm64.iso,id=cdrom,media=cdrom -device virtio-scsi-device -device  scsi-cd,drive=cdrom -drive if=none,file=ubuntu16.04-arm64.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0

执行上述命令时确保QEMU_EFI.fd、ubuntu-16.04.2-server-arm64.iso、ubuntu16.04-arm64.img文件在当前目录下,否则需要修改成对应的文件路径。

键入命令就会开始安装。

image-1652793369241

安装过程截图:
image-1652793703413
过程会让你选择语言、地区等。

image-1652800803711
可以看到我们已经成功登录进去。

8 qemu参数

关于我们启动的参数,可以参考这个博主的 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.2-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

可以看我我们这里面用了一些参数:

  • -m:指定内存多少MB
  • -nographic:disable graphical output and redirect serial I/Os to console,除此之外我们可以选择vnc连接 -display vnc

注意: !!第9节中的操作如果跟着做可能出问题导致重新安装,如果不需要实践这一部分建议跳过。

9 VNC连接虚拟机

我们也可以利用VNC进行登录。

qemu-system-aarch64 -m 2048 -cpu cortex-a57 -smp 2 -M virt -bios QEMU_EFI.fd -display vnc=:0 -drive if=none,file=ubuntu-16.04.2-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

报如下警告:

WARNING: Image format was not specified for 'ubuntu16.04-arm64.img' 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.

磁盘格式指定为format=raw ;

qemu-system-aarch64 -m 2048 -cpu cortex-a57 -smp 2 -M virt -bios QEMU_EFI.fd -display vnc=:0 -drive if=none,file=ubuntu-16.04.2-server-arm64.iso,id=cdrom,media=cdrom -device virtio-scsi-device -device  scsi-cd,drive=cdrom -drive if=none,file=ubuntu16.04-arm64.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0

如果这里我们用vnc连接的话,需要我们输入密码,这里我们用的是mobaXterm这个工具来进行VNC连接的,在无外设模式下运行 QEMU 时,它会在端口 5900 上启动本地 VNC 服务器。
我们直接输入宿主机的ip和5900端口,它提示我们需要密码。

  • 设置vnc密码
  1. 我们先进入Qemu监控模式,这个模式可以换软盘或 CD等,在命令行上加入 -monitor stdio

    qemu-system-aarch64 -m 2048 -cpu cortex-a57 -smp 2 -M virt -bios QEMU_EFI.fd -display vnc=:0 -drive if=none,file=ubuntu-16.04.2-server-arm64.iso,id=cdrom,media=cdrom -device virtio-scsi-device -device  scsi-cd,drive=cdrom -drive if=none,file=ubuntu16.04-arm64.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -monitor stdio
    ``
    
  2. 修改vnc密码

    (qemu) change vnc password
    
  3. 修改成功后就可以利用mobaXterm登陆了,当然你可以用其他的VNC客户端登录。

    监控模式和console模式切换:Ctrl+Alt+2Ctrl+Alt+1

进入后发现又需要重新安装server,又要重新安装,但是安装过程磁盘那块划分会提示已经有磁盘划分,那块会一直报错。于是我直接删除原来的镜像,重新装一次,但是这次用的是vnc来装系统。大家可以不要跟着做,因为已经安装好了再安装一次浪费时间。

使用VNC进行安装中…,心累
image-1652845597573

安装成功,并成功登录。
image-1652870229259

10 启动虚拟机

我们关闭VNC重新运行:

qemu-system-aarch64 -m 2048 -cpu cortex-a57 -smp 2 -M virt -bios QEMU_EFI.fd -nographic -drive if=none,file=ubuntu16.04-arm64.img,id=hd0 -device virtio-blk-device,drive=hd0

这个时候启动失败,发现博主也出现了这个问题,

image-1652882541683

我们发现是进了EFI的shell界面,那为什么没有执行grub并引导进入ubuntu系统?说明UEFI固件没有找到ESP分区(EFI system partition,安装过程中就会看见创建了一个ESP分区)或者没有找到ESP分区中的EFI文件,因为系统需要该EFI文件来引导。在该shell下执行exit进入到UEFI的管理界面,并手动选择EFI文件启动系统,如下图所示。

  1. shell界面输入exit退出到下图界面,选择boot maintenance manager:
    image-1652882744715

  2. 选择 boot from file:
    image-1652882794411

  3. 一路enter就行,
    image-1652882841387
    直到找到这个文件,回车即可。
    image-1652882882159

成功进入安装的系统。

image-1652883097277

11 利用virt-manager启动虚拟机

  • 安装virt-manager
    yum install virt-manager

  • 运行virt-manager
    virt-manager

使用mobaXterm ssh连接virt-manager报错:

virt-manager 报Gtk-WARNING **: cannot open display

解决方法: 出现这个问题之后,网上找了很多个博客的解决方法,安装了很多包,最后我也不清楚是安了哪些包才好的,我机器默认的ssh配置没有问题,mobaXterm默认打开X11转发的。反正记得一定要重新启动一个sshd窗口

  1. 安装虚拟化相关工具,包括图形化工具(推荐使用组包安装,不容易遗漏软件包)
 yum groupinstall "Virtualization Hypervisor" "Virutalization Client","Virutalization Platform","Virtualization Tools"
 
 # 下面这个也装上
 yum install -y xorg-x11-xauth xorg-x11-fonts-* xorg-x11-font-utils xorg-x11-fonts-Type1 xclock
  1. 查看sshd服务配置文件
# vi /etc/ssh/sshd_config
X11Forwarding yes

# systemctl  restart sshd
  1. 关闭当前MobaXterm窗口,重新启动一个mobaXterm(十分重要!)
  2. 可以先用xclock 打开一个时钟看是否成功,如果成功说明显示窗口已经成功了,再用virt-manager如果失败的,就是virt-manager的问题。
    image-1652943503232

继续启动,又报错,查看日志:tailf -n 100 /root/.cache/virt-manager/virt-manager.log 报错:

Libvirt URI is: qemu:///system

Traceback (most recent call last):
  File "/usr/share/virt-manager/virtManager/connection.py", line 1036, in _do_open
    self._backend.open(self._do_creds_password)
  File "/usr/share/virt-manager/virtinst/connection.py", line 144, in open
    open_flags)
  File "/usr/lib64/python2.7/site-packages/libvirt.py", line 104, in openAuth
    if ret is None:raise libvirtError('virConnectOpenAuth() failed')
libvirtError: 将插槽连接到 '/var/run/libvirt/libvirt-sock' 失败: 没有那个文件或目录

解决方法:重启即可 reboot
image-1652943639235

启动这个什么字符,完全看不懂!!我们需要将他转为我们能看懂的!
解决方法,很简单:
命令行执行: Lang=C
重新启动 virt-manager 即可

LANG=“” 是设置系统环境语言编码
当设置LANG=C时,是最早最简单的C语言环境(标准ASCII码)

image-1652944126355

可以看到已经是英文了,如果我们需要将其转换成中文,参考 KVM中打开virt-manager报错或者将其显示为中文界面的办法

我们 Filke->New Virtual Machine->import Existing disk image,browse Local,选择本地镜像后,提示我们权限不足。
image-1652944424470

解决方法:

  1. 修改配置文件 /etc/libvirt/qemu.conf
    # vim /etc/libvirt/qemu.conf
    添加
    user="root"
    group="root"
    
  2. 重启 libvirtd
    # systemctl restart libvirtd.service
    // 或
    # service libvirtd restart
    
  3. 修改 SELinux 配置
    # vim /etc/selinux/config
    SELINUX=permissive
    
  4. 重启OS reboot

继续新建虚拟机,这回权限没问题了。

当我们选择aarch64架构的时候他会报错:
image-1652947356952

解决方法:

cd /etc/yum.repos.d/
wget https://www.kraxel.org/repos/firmware.repo
yum install -y dnf
dnf install edk2.git-aarch64

# 编译/etc/libvirt/qemu.conf文件,添加如下语句

nvram = [
   "/usr/share/edk2.git/aarch64/QEMU_EFI-pflash.raw:/usr/share/edk2.git/aarch64/vars-template-pflash.raw"
]
# 重启
systemctl restart libvirtd

再次启动发现warning不见了。
image-1652947497520

进入了Qemu-efi-pflash,但是一直在闪,无法输出。
image-1652948788252

我们将开始的Qemu-EFI.fd替换这个QEMU_EFI-pflash.raw。

dd if=QEMU_EFI.fd of=/usr/share/edk2.git/aarch64/QEMU_EFI-pflash.raw conv=notrunc

删除原来的虚拟机,别删除了镜像!!,做好保存,快照之类的。
重新创建虚拟机,一样的步骤就行了,成功进入EFI界面,同样选择
image-1652949299503

发现是空的,按照网上的教程,也不行,使用virt-manager,接替已经创建的虚拟机,失败了。
image-1652950949641

按照博主的设置启动内核方式也存在问题,主要是分区表是LVM的,不能够将其中的数据对换出来。这里就先这样吧。目前毕竟只是测试,问题不大。我们也熟悉了virt-manager的运行,后期我们使用KVM的时候,再来仔细解决这些问题。

我们检查一下,虚拟机通过命令行是否正常运行。

qemu-system-aarch64 -m 2048 -cpu cortex-a57 -smp 2 -M virt -bios QEMU_EFI.fd -nographic -drive if=none,file=ubuntu16.04-arm64.img,id=hd0 -device virtio-blk-device,drive=hd0

正常进入问题。
image-1652953218772

12 下一篇

在虚拟机中,我们尝试ping 百度试试,发现ping不通,但是解析ip是成功了,说明网不通,DNS却是正常的。
image-1652953293243

这篇文章已经很长了,我们下一篇主要解决Qemu虚拟网络的联通问题,实现Qemu虚拟机对外网的访问。

参考文献

5

评论区