avatar

Catalog
IOT环境搭建--如何使用qemu运行各种指令架构程序

IOT环境搭建–如何使用qemu运行各种指令架构程序

概述

考虑到性能等因素,IoT设备往往采用arm , mips等指令架构,还有少量采取ppc x86等,在IOT分析中,往往需要使用硬件虚拟化的虚拟机qemu来实现针对不同指令架构程序的仿真模拟.

环境搭建

IoT分析中,一些情况下只需要在用户模式下针对单个的程序进行仿真,另一些情况则需要建立一个完整的对应指令架构的虚拟机.以下是针对性的解决方案.

使用qemu-user运行不同指令架构程序

qemu-user安装

$ sudo apt-get install qemu qemu-user qemu-user-static

qemu-user使用

此时可以运行静态链接的arm程序:

bash
1
2
3
4
$ file ./arm_static
./arm_static: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=211877f58b5a0e8774b8a3a72c83890f8cd38e63, stripped
$ qemu-arm ./arm_static
Hello World

而要运行动态链接的程序,需要安装对应架构的动态链接库方可,例如以下这个arm64程序:

bash
1
2
$ file ./arm64_shared
./arm64_shared: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 3.7.0, BuildID[sha1]=e988eaee79fd41139699d813eac0c375dbddba43, stripped

要首先安装对应架构arm64的汇编器及动态链接库:

bash
1
2
$ sudo apt-get install binutils-aarch64-linux-gnu
$ sudo apt install libc6-arm64-cross

其中具体的汇编器和动态链接库可以通过以下命令进行查找:

bash
1
2
$ sudo apt search binutils| grep aarch64
$ sudo apt-cache search “libc6-” | grep “arm”

然后就可以实现该程序的仿真:

bash
1
2
$ qemu-aarch64 -L /usr/aarch64-linux-gnu ./arm64_shared
Hello World

其它架构处理类似.

使用qemu搭建不同指令架构虚拟机

使用qemu搭建不同指令架构虚拟机可以有两种方式:

  1. 下载对应指令架构的内核和文件系统,然后使用qemu-system建立相应指令架构的虚拟机,但是这种方法需要配置好虚拟机网络
  2. 直接使用docker运行各种指令架构的容器

使用qemu-system建立不同指令架构虚拟机

qemu-system安装

$ sudo apt-get install qemu qemu-user-static qemu-system uml-utilities bridge-utils

使用qemu-system可模拟完整的各种指令架构的linux系统

虚拟机建立步骤
  • 配置虚拟机网络

    安装依赖文件

    sudo apt-get install bridge-utils uml-utilities

    修改 ubuntu主机网络配置,将ubuntu主机系统中的网络接口配置文件 /etc/network/interfaces 修改为如下内容并保存、关闭。

    bash
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    auto lo
    iface lo inet loopback

    auto eth0
    iface eth0 inet dhcp

    #auto br0
    iface br0 inet dhcp
    bridge_ports eth0
    bridge_maxwait 0

    创建QEMU的网络接口启动脚本,重启网络使配置生效。使用如下命令,在 /etc/qemu-ifup的后面加入以下内容。

    sudo gedit /etc/qemu-ifup

    bash
    1
    2
    3
    4
    5
    6
    7
    #!/bin/sh
    echo "Executing /etc/qemu-ifup"
    echo "Bringing $1 for bridged mode..."
    sudo /sbin/ifconfig $1 0.0.0.0 promisc up
    echo "Adding $1 to br0..."
    sudo /sbin/brctl addif br0 $1
    sleep 3

    保存 文件/etc/qemu-ifup 以后,赋予文件/etc/qemu-ifup 可执行权限,然后重启网络使所有的配置生效。

    bash
    1
    2
    3
    4
    $ sudo chmod a+x /etc/qemu-ifup

    # 重启网络使配置生效
    $ sudo /etc/init.d/networking restart

    在本地ubuntu命令行终端,启动桥连网络。

    bash
    1
    2
    sudo ifdown eth0
    sudo ifup br0
  • 下载虚拟机内核文件系统文件

    可以在以下地址下载:

    下载地址:https://people.debian.org/~aurel32/qemu/

    当然也可以自己编译对应架构内核.

  • 各架构虚拟机开启命令

    下载好各种架构的内核文件和系统文件后运行以下命令即可打开对应指令架构的虚拟机

    mips 32位:

    qemu-system-mips -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mips_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic -net tap -nographic

    mips 64位:

    qemu-system-mips64 -M malta -kernel vmlinux-3.2.0-4-5kc-malta -hda debian_wheezy_mips_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic -net tap -nographic

    mipsel 32位:

    qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic -net tap -nographic

    mipsel 64位

    qemu-system-mips64el -M malta -kernel vmlinux-3.2.0-4-5kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic -net tap -nographic

    armel

    qemu-system-arm -M versatilepb -kernel vmlinuz-3.2.0-4-versatile -initrd initrd.img-3.2.0-4-versatile -hda debian_wheezy_armel_standard.qcow2 -append "root=/dev/sda1" -net nic -net tap -nographic

    armhf

    qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -drive if=sd,file=debian_wheezy_armhf_standard.qcow2 -append "root=/dev/mmcblk0p2" -net nic -net tap -nographic

    arm64

    qemu-system-x86_64 -hda debian_wheezy_amd64_standard.qcow2 -net nic -net tap -nographic

docker的兼容性问题

安装了docker后,可能会发现qemu开启的虚拟机无法正常联网了,这是因为docker安装中更改了iptables,可执行一下命令更正一下路由表

iptables -I FORWARD -i br0 -o br0 -j ACCEPT

然而这是临时生效,下次重启还需要重新执行,可按以下方法一劳永逸:

bash
1
2
3
$ sudo apt-get install iptables-persistent
$ sudo netfilter-persistent save
$ sudo netfilter-persistent reload

另外可能还需要修改DNS:

$ cp /etc/resolv.conf /etc/resolv.confbak

/etc/resolv.conf内容更改为以下:

Code
1
2
nameserver 8.8.8.8   #设置首选dns
nameserver 8.8.4.4 #设置备用dns

使用docker建立不同指令架构虚拟机

安装qemu环境
bash
1
$ sudo apt-get install qemu qemu-user-static qemu-system uml-utilities bridge-utils
下载镜像(armhf为例)

$ docker pull ioft/armhf-ubuntu:trusty

其它架构类似,直接search即可

使用docker运行容器(armhf为例)
Code
1
$ docker run -it --privileged -v /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static ioft/armhf-ubuntu:trusty /bin/bash

进入容器查看

bash
1
2
3
4
5
$ sudo docker exec -it 240f58b9b3ba bash
root@240f58b9b3ba:/# uname -a
Linux 240f58b9b3ba 4.4.0-171-generic #200-Ubuntu SMP Tue Dec 3 11:04:55 UTC 2019 armv7l armv7l armv7l GNU/Linux
root@240f58b9b3ba:/# file /bin/ls
/bin/ls: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=74480e1a4f4c0aebebd4db4f5405e720cf4b8de5, stripped

Comment