如何用 QEMU 模拟 Raspberry Pi Raspbian?

How to emulate Raspberry Pi Raspbian with QEMU?

我正在尝试使用 QEMU 用 Raspian OS 模拟 Raspberry Pi。我尝试了网上描述的几种方法,但都没有成功。

我发现我需要修补适合所需 OS 的 Linux 内核。在我的例子中,我选择了带有内核 4.4 的 Rasbian Lite:

wget https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2016-05-31/2016-05-27-raspbian-jessie-lite.zip
unzip 2016-05-27-raspbian-jessie-lite.zip
rm 2016-05-27-raspbian-jessie-lite.zip

接下来我从 https://www.kernel.org/:

加载内核
wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.4.16.tar.gz
tar -xzf linux-4.4.16.tar.gz
rm linux-4.4.16.tar.gz

现在交叉编译内核:

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
cd linux-4.4.16
make vexpress_defconfig
make all
cd ..

现在我可以将引导映像(即在 RAM 中自动提取的压缩内核映像)复制到我的工作区:

cp linux-4.4.16/arch/arm/boot/zImage zImage

和运行 QEMU

qemu-system-arm -kernel zImage -M vexpress-a9 -m 1024 -cpu cortex-a9 -no-reboot -serial stdio -hda 016-05-27-raspbian-jessie-lite.img -append "root=/dev/sda2 rootfstype=ext4"

但我看到的只是一个黑色填充的 QEMU-window。 :(

我认为问题在于获得正确的内核。从 Internet 复制某些内核从未成功,因为它们不适合 OS.

如何 build/patch 适合 OS 的内核(无需下载现有内核)以及如何正确 运行 QEMU?

提前致谢
亚历克斯


第二种方法

我从这里加载一个 kernel-qemu https://www.dropbox.com/s/g8u93xblz1v1ly0/kernel-qemu?dl=0 和 运行 QEMU:

qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2" -hda 2016-05-27-raspbian-jessie-lite.img

这给我带来了以下输出: 这对我来说很有意义,因为内核是 3.10.25 并且比 Raspbian Jessie 和内核 4.4.16.

使用 https://github.com/dhruvvyas90/qemu-rpi-kernel/blob/master/kernel-qemu-4.4.12-jessie

的 qemu 内核
qemu-system-arm -kernel kernel-qemu-4.4.12-jessie -cpu arm1176 -m 256 -M versatilepb -serial stdio -append "root=/dev/sda2 rootfstype=ext4 rw" -hda 2016-05-27-raspbian-jessie-lite.img

我得到了类似的结果:

新内核-qemu 4.4.16 的新尝试:

  1. https://github.com/dhruvvyas90/qemu-rpi-kernel/tree/master/tools 复制 build-kernel-qemu 并添加以下行以检查内核 4.4.16 的版本:

    git checkout b05965f284db3e086022f4e318e46cb5bffb1376
    
  2. 运行 build-kernel-qemu 构建内核

    sh build-kernel-qemu
    
  3. 运行 QEMU

    qemu-system-arm -kernel kernel-qemu -m 256 -M versatilepb -serial stdio -append "root=/dev/sda2 rootfstype=ext4 rw" -hda 2016-05-27-raspbian-jessie-lite.img
    

    结果:

您应该在开始之前展开 Raspbian 图像文件

使用 kpartx 安装 Raspbian 映像文件(可能必须安装 kpartx)

$ sudo kpartx -av your-image.img
add map loop0p1 (252:5): 0 117187 linear /dev/loop0 1
add map loop0p2 (252:6): 0 3493888 linear /dev/loop0 118784

$ sudo mount /dev/mapper/loop0p2 /mnt/img1
$ cd /mnt/img1

修改/etc/fstab并注释掉MMCBLK挂载

$ sudo nano etc/fstab

proc            /proc           proc    defaults          0       0
#/dev/mmcblk0p1  /boot           vfat    defaults          0       2
#/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that

修改/etc/ld.so.preload并注释掉行...

$ sudo nano etc/ld.so.preload

#/usr/lib/arm-linux-gnueabihf/libarmmem.so

从 kpartx

卸载 并销毁循环
$ sudo umount /mnt/img1
$ sudo kpartx -d your-image.img

在此处获取与 Raspbian 图像匹配的 Qemu 内核...

https://github.com/dhruvvyas90/qemu-rpi-kernel

我用这个命令成功模拟了Raspbian Jessie

qemu-system-arm -kernel kernel-qemu-4.4.12-jessie -cpu arm1176 -m 256 -M versatilepb \
-no-reboot -serial stdio -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" \
-redir tcp:5022::22 \
-hda 2016-05-27-raspbian-jessie-lite.img

我在使用自定义 ubuntu 图片时遇到了类似的问题。 我还应用了@Michael Connors 的回答中描述的修改,然后我看到系统启动。

您可以在 -append="" 中添加以下内容以查看您的情况:

qemu-system-arm ... -serial stdio -append="... console=ttyAMA0,115200 loglevel=8"

您需要修改内核才能在 QEMU 中 运行,因为 raspberry PI 板硬件在 QEMU 中不可用。这就是您的第一种方法失败的原因。

您的第二种方法使用在多功能板上正确修补到 运行 的内核(由 QEMU 支持),这很好,但是内核 3.x 对于现代 Raspbian。原则上你最后的方法应该有效。

我推荐 this 更新指南(2017 年 2 月),我使用 4.4 内核对其进行了测试,它可以立即运行。

qemu-system-arm -kernel $KERNEL -cpu arm1176 -m 256 -M versatilepb -net nic,macaddr=$MAC -net tap -no-reboot -append "root=/dev/sda2 panic=1" -drive format=raw,file=$IMG

我不得不使用 format=raw,file=$IMG 选项来避免 QEMU 警告。

不需要注释掉/etc/fstab,可以添加到/etc/udev/rules.d/90-qemu.rules

KERNEL=="sda", SYMLINK+="mmcblk0"
KERNEL=="sda?", SYMLINK+="mmcblk0p%n"
KERNEL=="sda2", SYMLINK+="root"

此外,ld.so.preload 是旧的,不再适用

上述指南中提供的脚本可以为您完成所有这些工作,还可以通过与 raspbian 共享您的网络接口来提供对您的 raspbian 的网络访问。

Ubuntu 16.04 主机,QEMU 2.9.0 -M raspi2,Raspbian 2016-05-27,香草内核

优点:

  • -M raspi2,我们可以使用vanilla内核,所以系统更具代表性

限制:

  • -M raspi2是QEMU 2.6.0加入的,而Ubuntu16.04只有QEMU 2.5.0,所以我们要从源码编译QEMU。但这并不难。
  • GUI 显示但不响应鼠标/键盘,已在 SDL 和 VNC 上测试。但是 CLI 却工作得很好。因此,您不妨暂时使用具有 go GUI 的 Lite 图像。
  • 没有网络

步骤:

  1. 从源代码编译 QEMU 2.9.0:

    sudo apt-get build-dep qemu-system-arm
    git clone --recursive git://git.qemu-project.org/qemu.git
    cd qemu
    git checkout v2.9.0
    ./configure
    make `nproc`
    
  2. 下载镜像并从中提取内核和dts:

    1. 下载图片并解压:

      wget http://downloads.raspberrypi.org/raspbian/images/raspbian-2016-05-31/2016-05-27-raspbian-jessie.zip
      unzip 2016-05-27-raspbian-jessie.zip
      
    2. 挂载分区的第二个映像。最简单的方法是:

      sudo losetup -f --show -P 2016-05-27-raspbian-jessie.img
      

      这仅适用于 Ubuntu 16.04 上的最新 losetup,其他方法位于:https://askubuntu.com/questions/69363/mount-single-partition-from-image-of-entire-disk-device/496576#496576

      这会打印一个循环设备,例如:

      /dev/loop0
      

      所以我们这样做:

      sudo mkdir /mnt/rpi
      sudo mount /dev/loop0p1 /mnt/rpi
      cp /mnt/rpi/kernel7.img bcm2709-rpi-2-b.dtb .
      sudo umount /mnt/rpi
      sudo losetup -d /dev/loop0
      
  3. 运行:

    ./arm-softmmu/qemu-system-arm \
        -M raspi2 \
        -append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2" \
        -cpu arm1176 \
        -dtb bcm2709-rpi-2-b.dtb \
        -sd 2016-05-27-raspbian-jessie.img \
        -kernel kernel7.img \
        -m 1G \
        -smp 4 \
        -serial stdio \
    ;
    

然后您可以在主机终端上显示的终端上登录。

[失败] Ubuntu 17.04,QEMU 2.8.0 -M raspi2,Raspbian 2016-05-27,香草内核

在这个较新的 Ubuntu 上,QEMU 2.8.0 是默认的,因此我们不需要为 -M raspi2 从源代码编译 QEMU。但是,2.8.0 在出现以下消息后在启动时挂起:

Console: switching to colour frame buffer device 100x30

这表明 -M raspi2 仍然不稳定。

[失败] Ubuntu 16.04,QEMU 2.9.0 -M raspi2,Raspbian 2017-08-16,香草内核

在这个较新的映像上,使用与 2016-05-27 相同的方法,内核在启动时出现恐慌:

Please append a correct "root=" boot option; here are the available partitions:
...
[    4.138114] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

bztsrc/raspi3-tutorial QEMU 上的 RPI3 裸机

https://github.com/bztsrc/raspi3-tutorial is a good set of examples that just work on QEMU, ultraquick getting started at: https://raspberrypi.stackexchange.com/questions/34733/how-to-do-qemu-emulation-for-bare-metal-raspberry-pi-images/85135#85135