TinyEMU编译与使用(一)

TinyEMU编译与使用(一)

  • [1 介绍](#1 介绍)
  • [2 准备工作](#2 准备工作)
  • [3 编译TinyEMU](#3 编译TinyEMU)
    • [3.1 安装依赖库](#3.1 安装依赖库)
    • [3.2 编译](#3.2 编译)
  • [4 运行TinyEMU](#4 运行TinyEMU)
    • [4.1 在线运行](#4.1 在线运行)
    • [4.2 离线运行](#4.2 离线运行)
  • [5 共享目录](#5 共享目录)
    • [5.1 修改root_9p-riscv64.cfg](#5.1 修改root_9p-riscv64.cfg)
    • [5.2 启动TinyEMU](#5.2 启动TinyEMU)
    • [5.3 执行挂载命令](#5.3 执行挂载命令)
  • [6 TinyEMU命令帮助](#6 TinyEMU命令帮助)

1 介绍

原名为riscvemu,于2018-09-23,改为TinyEMU。

TinyEMU是Fabrice Bellard写的一个RISC-V和X86模拟器,它的目的是小而简单,同时又完整。Fabrice Bellard正是开发鼎鼎大名QEMU的作者。

官网:https://bellard.org/tinyemu/

主要特点:

  • 支持RV128IMAFDQC基本ISA(用户级ISA版本2.2,特权架构版本1.10)的RISC-V系统仿真器包括:
  • 32/64/128位整数寄存器
  • 32/64/128位浮点指令(使用SoftFP库)
  • 压缩指令
  • 动态XLEN变化
  • 基于KVM的x86系统仿真器
  • 虚拟控制台、网络、块设备、输入和9P文件系统
  • 带SDL的图形显示
  • JSON配置文件
  • 远程HTTP块设备和文件系统
  • 代码小,易于修改,外部依赖性少
  • Javascript版本运行Linux和Windows 2000。

2 准备工作

通过官网,下载以下内容。

3 编译TinyEMU

本文环境为Ubuntu 20.04。

3.1 安装依赖库

需要安装 libcurl、OpenSSL 和 SDL 库,TinyEMU源码对这些库函数有依赖。

以下为,其他情况,可忽略。

  • 如果环境中实在缺少这些库,也可以通过注释掉Makefile中的CONFIG_FS_NET或CONFIG_SDL,来编译TinyEMU。
  • 如果在32位主机上编译,可以通过编辑Makefile,以禁止编译为128位目标(对于生成128位RISCV目标,编译器必须支持__int128 C扩展)。

3.2 编译

进入源码目录tinyemu-2019-12-21中,编译TinyEMU源码:

cpp 复制代码
make

编译成功,可执行程序为temu。

也可以选择,通过以下命令,将temu程序,安装到 /usr/local/bin 系统路径下:

cpp 复制代码
make install

编译时,若报错:"fatal error: curl/multi.h: No such file or directory"

原因:缺少libcurl库

解决办法:sudo apt-get install libcurl4-openssl-dev,安装libcurl。

4 运行TinyEMU

根据RISC-V boot loader、Linux kernel、filesystem文件获取方式的不同,TinyEMU可以有2种运行方式:

  • 在线运行(无需下载);
  • 离线运行。

4.1 在线运行

在官网https://bellard.org/jslinux/index.html,有如下OS镜像:

图中标识,表示在riscv64 CPU运行的,不带图形界面的Linux Kernel系统,这样环境的TinyEMU配置文件,在"TEMU Config"列的"url"链接处。打开后,如下所示:

buildroot-riscv64.cfg文件中,记录了RISC-V boot loader、Linux kernel、filesystem这些文件的名称及路径配置。

因此,我们可通过如下命令,在线加载相关文件:

cpp 复制代码
./temu https://bellard.org/jslinux/buildroot-riscv64.cfg

需要等待几分钟,加载快慢,取决于网络环境。

linux内核加载,并启动完成,如下所示:

打印Welcome信息,当前目录下有hello.c,我们使用gcc hello.c -o hello编译,可能也需要等一会。

编译与执行成功,说明linux内核,已经在TinyEMU上成功跑起来了。

上述列表中,其他OS也可以通过这样的方式,运行起来,这里不再赘述。

4.2 离线运行

在准备工作中,我们下载的diskimage-linux-riscv-2018-09-23.tar.gz文件,这里才发挥作用。

解压后,如下内容:

该目录下,有RISC-V boot loader、Linux kernel、filesystem等文件,这次,我们使用root-riscv64.cfg配置文件。

将可执行程序temu,拷贝至diskimage-linux-riscv-2018-09-23目录下,然后执行:

cpp 复制代码
./temu -ctrlc root-riscv64.cfg

-ctrlc,参数表示可以使用Ctrl+C快捷键,退出模拟器;未加此选项的话,Ctrl+C无效。

非常快,秒进OS,如下所示:

随便执行几条命令,如下所示:

说明linux内核,已经在TinyEMU上成功运行。

5 共享目录

TinyEMU中运行的linux虚拟机,如何与TinyEMU所在的主机,进行文件共享和传输呢?

TinyEMU也是支持的,主要有以下三个步骤。

5.1 修改root_9p-riscv64.cfg

官方提供的root_9p-riscv64.cfg,文件内容,如下:

cpp 复制代码
/* VM configuration file */
{
    version: 1,
    machine: "riscv64",
    memory_size: 128,
    bios: "bbl64.bin",
    cmdline: "console=hvc0 root=/dev/vda rw",
    drive0: { file: "root-riscv64.bin" },

    /* Also access to the /tmp directory. Use 
       mount -t 9p /dev/root /mnt
       to access it. */
    
    fs0: { tag: "/dev/root", file: "/tmp" },

    eth0: { driver: "user" },
}

需在bios行后,添加内容kernel: "kernel-riscv64.bin",

5.2 启动TinyEMU

然后,再启动TinyEMU:

cpp 复制代码
./temu -ctrlc root_9p-riscv64.cfg

如果未按上述要求,修改cfg文件,则启动时,会报如下错误:

5.3 执行挂载命令

在TinyEMU中执行的linux虚拟机(Guest)上,执行挂载命令:

cpp 复制代码
mount -t 9p /dev/root /mnt

到此,主机(Host)上的 /tmp 目录下内容,在linux虚拟机的 /mnt 中已经可见了。

基于此功能,可在Host和Guest之间,传输文件。

6 TinyEMU命令帮助

TinyEMU命令使用形式,如下所示:

cpp 复制代码
temu [options] config_file

其各项参数含义,如下所示:

  • options可为以下任一或多个选项。
    • -m ram_size:设置内存大小,单位为MB
    • -rw:允许对磁盘镜像(default=snapshot)进行写访问,打开之后,在虚拟机中对文件系统做的修改,可以被保存(比如,保存到root-riscv64.bin中),下次启动后,该修改依然存在。
    • -ctrlc:拦截Ctrl+C按键,以便退出TinyEMU模拟器
    • -append cmdline:将cmdline附加到内核命令行
    • -no-accel:禁用虚拟机加速(仅限KVM、x86机器)
    • -h:打印帮助信息
  • config_file为*.cfg文件名。