解决 M1 MAC 的 Qemu 使用问题

Posted on Jun 29, 2021

本文可以帮助在M1 MAC上搭建起riscv32-system-qemuriscv64-system-qemu的环境,不过仅适用与5.1.0版本的Qemu。

[2021-11-26] 更新

6.1+ 版本的 Qemu 已解决该问题。

问题重现

M1 Mac拿到手几个月内,因为一些软件的架构适配问题,十分头疼,其中包括Qemu的使用问题。

例如我在Github MIT 的 xv6 仓库提的一个issue, 当使用5.x.0以及6.0.0版本的Qemu会出现这样的情况:qemu-system-riscv64: qemu_mprotect__osdep: mprotect failed: Permission denied, 其原因可能是苹果的内存保护问题。

也尝试了rCore-Tutorial-Book-v3仓库的解决方案(issue), 使用最新的补丁版本Qemu仓库,并对util/osdep.c文件作修改,虽然没有出现上面了情况了,系统启动会卡住。 以及 Qemu-5.2.0 不支持 RustSBI。

解决方案

google 了多方资料,最终发现了一个暂时可行的解决方案,如下方式可以在 M1 Mac上跑起来 Qemu。

  • 下载 5.1.0 版本的 Qemu(6.0.0 打补丁后仍有问题)
  • 下载这个补丁patch(series),将其存放于Qemu的上级目录,patch -p1 < ../patch/v2-tcg-Fix-execution-on-Apple-Silicon.patch安装补丁。
  • 修改util/osdep.c文件的函数
int qemu_mprotect_none(void *addr, size_t size)
 {
#ifdef _WIN32
     return qemu_mprotect__osdep(addr, size, PAGE_NOACCESS);
#elif defined(__APPLE__) && defined(__arm64__)
    /* Workaround mprotect (RWX->NONE) issue on Big Sur 11.2 */
    return 0;
 #else
     return qemu_mprotect__osdep(addr, size, PROT_NONE);
  • 最后安装编译安装Qeme,并将build文件夹与build/riscv64-softmmu文件夹加入环境变量中
mkdir build && cd build
./configure --disable-kvm --disable-werror --target-list="riscv64-softmmu"
make

这样 xv6 系统就可以工作了。

补充

值得一提的是,由于现在的M1 MAC还不支持GDB,因此在使用 riscv64-unknown-elf-gdb 会出现缺少 python 依赖的问题。 从源码编译 GDB 的方式目前还不可行,需要 M1 MAC 支持 GDB。

Docker上支持的ARM镜像也较少。

不过M1 MAC的性能与续航十分优秀,软件生态还正在完善,相信完善度会越来越好。

Reference