来自闪存设备映像的 Qemu Virt Machine

Qemu Virt Machine from flash device image

我一直在为使用硬件的原型设备开发 OS。不幸的是,每次刷新 OS 然后调试问题是一个非常手动和错误的过程。

我想转而在 QEMU 中开发 OS,这样我就可以确定 OS 正在正确加载,然后再对设备进行真正的编程。这将在以后的持续集成工作中派上用场。

我有从我的构建过程中生成的 NVM 设备的完整副本。这是一个已知的工作图像,我想在 QEMU 中 运行 作为起点。这已准备就绪,可以通过 JTAG 连接到设备上。分区布局为:

P0 - loader - 来自 rockchip loader 二进制文件的 IDBLoader Flash

P1 - Uboot - Uboot的Flash

P2 - trust - Rockchip 特定加载器的 Trust 图像闪现

P3 - / - 具有应用程序所需的基于 Debian 的映像和软件包的根分区

P4 - 数据分区 - 应用程序数据

除了串行控制台设置外,我没有对 Rockchip 分区 (P0 - P2) 进行任何更改。但是,当尝试启动映像时,没有任何反应。根本没有输出,但 VM 显示仍然 运行ning。我使用下面的命令来运行它:

qemu-system-aarch64 -machine virt -cpu cortex-a53 \
            -kernel u-boot-nodtb.bin \
            -drive format=raw,file=image.img \
            -boot c -serial stdio

我没有错误信息可以继续了解它是怎么回事,我在哪里可以获得更多信息或调试?

对于其他试图解决这个问题的人,我在这里找到了很好的资源:

https://translatedcode.wordpress.com/2017/07/24/installing-debian-on-qemus-64-bit-arm-virt-board/

https://azeria-labs.com/emulate-raspberry-pi-with-qemu/

尽管查看信息,您需要从映像中提取内核并将其作为参数提供给 qemu 命令行。您还需要附加一个参数,告诉系统将哪个分区用作根驱动器。

我启动机器的最终命令行如下所示:

qemu-system-aarch64 -machine virt -cpu cortex-a53 \
            -drive format=raw,file=image.img,id=hd \
            -boot c -serial stdio
            -kernel <kernelextracted> -append "root=fe04"

不同的 Arm 板在放置硬件的位置上可能存在显着差异,包括放置启动所需的基本硬件(UART、RAM、中断控制器等)的位置。因此,如果你在一块板上使用像 u-boot 或编译为 运行 的 Linux 内核这样的低级软件并尝试 运行 它在另一个它将无法启动。通常它不会输出任何东西,因为它甚至无法找到 UART。 (Linux 内核可以被编译成通用的,并包含适用于更广泛硬件的驱动程序,所以如果你有那种内核,它可以在不同的板类型上启动:它将使用设备树 blob,前提是由您或由 QEMU 为 'virt' 板自动生成,以确定它 运行 正在使用什么硬件并适应它。但是为特定嵌入式目标编译的内核通常仅使用设备驱动程序构建他们需要,而那种内核无法在不同的系统上启动。)

从广义上讲,您可以选择两条路径:

(1) 为您正在模拟的板构建来宾(此处为 'virt')。 u-boot 和 Linux 都支持 QEMU 的 'virt' 板。这可能对您尝试做的事情有用,也可能没有用——您将能够测试任何用户空间级别的代码,这些代码不关心它 运行 在什么硬件上,但显然不是任何特定于您针对的真实硬件。

(2) 理论上,您可以为您尝试 运行 的硬件向 QEMU 添加仿真支持。然而,这通常是一个相当大的工作量,如果您还不熟悉 QEMU 内部结构,那么这并不是微不足道的。我通常粗略估计它“与将内核移植到硬件所需的工作量差不多”;尽管这在一定程度上取决于 you/your 来宾需要运行多少功能,以及 QEMU 是否已经具有您的硬件正在使用的 SoC 模型。

要回答一般性的“调试不启动的来宾映像的最佳方法是什么”,最好的办法通常是将 arm-aware gdb 连接到 QEMU 的 gdbstub。这为您提供了与实际硬件的 JTAG 调试连接大致相似的调试访问,并且可能足以让您找出来宾崩溃的位置。 QEMU 在“-d”选项下也有一些调试日志记录选项,尽管日志记录的部分目的是帮助调试 QEMU 本身的问题并且解释起来可能有点棘手。

QEMU 不能模拟任意硬件。您必须编译 U-Boot 以匹配 QEMU 模拟的硬件,例如使用 make qemu_arm64_defconfig。 OS 还必须为 QEMU 的模拟硬件提供驱动程序。

如果你想模拟完整的硬件来调试驱动程序,Renode(https://renode.io/)是一个不错的选择。