【问题标题】:qemu-x86_64 on RPi 4B 4G 32-bit OSRPi 4B 4G 32 位操作系统上的 qemu-x86_64
【发布时间】:2021-01-19 18:28:39
【问题描述】:

我正在尝试使用 qemu-x86_64 在我的 RPi 4B 上运行 x86_64 playonlinux。我在 32 位操作系统上。这是运行时的错误:

(xenial-amd64)pi@raspberrypi44g:~/chroots/64-bit-x86 $ playonlinux        
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
Looking for python... 2.7.12 - wxversion(s): 3.0-gtk2
selected
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
[main] Message: PlayOnLinux (4.2.10) is starting
[clean_tmp] Message: Cleaning temp directory
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
[Check_OpenGL] Warning: check_dd_x86 missing, test skipped
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
[Check_OpenGL] Warning: check_dd_amd64 missing, test skipped
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
[POL_System_CheckFS] Message: Checking filesystem for /home/pi/.PlayOnLinux/
[main] Message: Filesystem is compatible
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)

(mainwindow.py:12318): Gdk-WARNING **: shmat failed: error 22 (Invalid argument)
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
/usr/share/playonlinux/playonlinux: line 126: 12318 Bus error               "$POL_PYTHON"             mainwindow.py "$@"
(xenial-amd64)pi@raspberrypi44g:~/chroots/64-bit-x86 $ [update_check] Message: List is up     to date
[install_plugins] Message: Checking plugin: ScreenCap...
[install_plugins] Message: Checking plugin: PlayOnLinux Vault...

(xenial-amd64)pi@raspberrypi44g:~/chroots/64-bit-x86 $ 

是什么导致了这个错误?

【问题讨论】:

    标签: x86-64 qemu raspberry-pi4 bus-error


    【解决方案1】:

    这里有几个可能的原因,但总的来说 QEMU 的用户模式仿真远非完美,最好不要期望它能够运行大型和复杂的软件,尤其是像 PlayOnLinux 之类的 AFAICT基于葡萄酒。 (用户模式仿真在 QEMU 开发者社区的有效优先级列表中不是很高,因为没有多少开发者要么有偿从事该部分代码的工作,要么出于个人目的而工作与其他领域(如系统仿真或 KVM 支持)相比。)

    我将从第 0 项开始,即您没有说明您使用的是哪个 QEMU 版本。如果不是最新版本,您可以尝试更新的 QEMU 看看是否有帮助。

    首先列出可能的原因:QEMU 的用户模式不支持 32 位主机上的 64 位客户机。我们尽最大努力,这适用于简单的程序,但对于更复杂的程序可能会失败。您可以通过查看程序是否在 x86-64-on-aarch64 这样的 64-on-64 组合上运行来测试这是否是问题所在。

    其次,我们的 x86-64 仿真不涵盖 x86 指令集(如 AVX)的最新添加;如果来宾程序假设它可以使用它们,那么它在 QEMU 下运行时会崩溃或行为不端。 (这里的错误看起来可能不是这个。)

    第三,我们可能在特定系统调用或 Linux ABI 的其他功能的实现中遗漏或存在错误。

    第四,x86 内存模型比 Arm 更严格,QEMU 的仿真并没有试图弥补这一点。所以如果你运气不好,多线程来宾程序可能会在这里遇到问题。

    要跟踪此特定来宾二进制文件中可能出现的情况,需要一个扩展的调试会话,您可以在其中查看来宾在失败时正在做什么(例如,为什么 shmat() 失败?总线错误的直接原因是什么?)然后尝试使用客户机源、客户机二进制文件的反汇编/逆向工程和 QEMU 源的组合来追溯发生的事情。 (如果您觉得这是一个艰难而漫长的过程,那么您并没有错 :-))

    旁注:图形程序上的“shmat失败”加上“总线错误”的组合让我想知道您的设置是否使用远程X会话(DISPLAY设置为本地X服务器以外的其他内容)和来宾程序本身有问题,无法成功回退到不使用 X 共享内存扩展的代码路径。您可以通过在具有非本地 DISPLAY 设置的 x86-64 主机上本地运行来宾来测试这一点,或者在您的 Arm 主机上安排本地 X 服务器。

    【讨论】:

    • 就像我说的,我使用的是 32 位操作系统,而 apt repos 中的 QEMU 已经很久没有为此更新了。我已经编译了一个较新的版本,并会尝试。我正在使用schroot -c xenial-amd64 -p 通过 QEMU 进入 chroot。它也适用于我的 x86-64 主机。希望这能缩小范围!
    • 只是为了帮助缩小这种情况,Ubuntu 可以在没有 AVX 的机器上运行(包括带有 Silvermont 系列 CPU 的现代低功耗上网本,不幸的是,还有当前一代 Pentium/Celeron 品牌的 CPU。例如 Skylake Pentium 仍然只有 SSE4.2)。不过,感谢您发布此内容。记忆排序的东西有点令人震惊。很容易导致内核或多线程用户空间的重大破坏。但修复起来并不便宜:只有机器代码,你不知道哪些商店应该是“发布”的,哪些只是私有的。
    • 我认为您将 QEMU 的系统仿真与那里的用户模式仿真混淆了。对于系统仿真,QEMU 可以正确处理内存排序,因为它可以回退到“在一个主机线程上仿真所有来宾 CPU”,因此运行内核总是没问题的。它只是我们必须并行运行多个线程的用户空间。是的,Ubuntu 和其他广泛使用的发行版通常构建为不需要更新的 CPU 扩展——但在这种情况下,想法似乎是最终运行 Windows 游戏二进制文件或类似的东西,它们更有可能坚持新的 CPU 支持。跨度>
    • 正如我所说,当前一代 Intel Pentium/Celeron 品牌的 CPU 没有 AVX,所以我认为游戏通常将自己限制在不包括该基准的基准。 SSSE3 可能是当今游戏的基准; AMD Phenom II 曾经阻止游戏要求这样做,但现在它已经完全过时了。所以可能是所有新 CPU 都支持的 SSE4.2,并且已经支持了好几年。
    • Re:内存排序:大多数操作系统允许将所有线程固定到同一个内核。当然 Linux 使用sched_setaffinity。这当然对性能不利,但不如其他实现正确性的方法那么糟糕,因此 qemu-user 可能想要这样做。不过,它必须随机(?)选择一个核心,如果这很容易找到的话,可能是它当前所在的核心。
    【解决方案2】:

    它有效,但不是很好。如果可以,请使用 x86_64 主机系统。

    【讨论】:

      猜你喜欢
      • 2015-09-26
      • 2013-08-29
      • 2011-12-18
      • 1970-01-01
      • 2011-02-20
      • 2013-08-24
      • 2011-05-04
      • 2012-07-26
      • 1970-01-01
      相关资源
      最近更新 更多