如何使用QEMU模拟运行树莓派Raspbian系统?

26

我正在尝试使用QEMU模拟运行带有Raspbian操作系统的树莓派。我尝试了网上描述的几种方法,但都没有成功。

我发现我需要补丁一个适用于所需操作系统的Linux内核。在我的情况下,我选择了带有4.4内核的Raspbian 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窗口. :(

我认为问题在于获取正确的内核。从互联网上复制一些内核从来没有成功过,因为它们不适合这个操作系统。

我应该如何构建/修补与操作系统匹配的内核(而不是下载现有的内核),以及如何正确运行QEMU?

提前感谢
Alex


第二种方法

我从这里加载一个kernel-qemu并用它运行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

我得到了类似的结果:

在此输入图片描述

使用新的kernel-qemu 4.4.16尝试:

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

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

  4. sh build-kernel-qemu
    
  5. 运行 QEMU

  6. 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
    

    结果: enter image description here


在你的第一种尝试中,你在qemu命令中包含了“-m 1024”,但由于qemu的一个bug而无法正常工作。你是否也尝试过使用其他方法中看到的“-m 256”来尝试这种方法? - M.Babcock
暂时还没有,但感谢这个提示。 - Alex44
在树莓派堆栈上:http://raspberrypi.stackexchange.com/questions/165/emulation-on-a-linux-pc/53991#53991 - Ciro Santilli OurBigBook.com
可能是模拟树莓派2的重复问题。 - Ciro Santilli OurBigBook.com
4个回答

13

在开始前,您应该扩展Raspbian映像文件

使用kpartx(可能需要安装kpartx)挂载Raspbian映像文件

$ 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

9
您需要一个修改过的内核才能在QEMU中运行,因为树莓派板硬件在QEMU中不可用。这就是为什么您的第一种方法失败的原因。
您的第二种方法使用了一个经过适当修补以在versatile板上运行的内核(由QEMU支持),所以很好,但是3.x内核对于现代Raspbian来说太旧了。原则上您最后的尝试应该是可以成功的。
我推荐使用这个更新的指南(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

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

您不需要注释掉/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。


你推荐的指南链接似乎无法访问。我从Google搜索缓存中获取了该页面的副本;有没有可能你可以添加一些来自原始帖子的信息,以便将来的人们能够使用你的回答? - rajb245
@rajb245 现在它能够工作了,似乎只是暂时性的停机。 - nachoparker
谢谢,我看到它现在已经恢复在线了。不过,如果您有时间的话,我仍然鼓励您在这里填写一些详细信息,以防这成为一个死链接。 - rajb245
QEMU 2.6.0具有“-M raspi2”选项,可以使用自定义内核:https://dev59.com/QFkT5IYBdhLWcg3wRNet#45893057 - Ciro Santilli OurBigBook.com

5

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

enter image description here

优点:

  • 使用-M raspi2,我们可以使用原始内核,因此系统更具代表性。

限制:

  • -M raspi2是在QEMU 2.6.0中添加的,而Ubuntu 16.04仅有QEMU 2.5.0,因此我们必须从源代码编译QEMU。但这并不难。
  • GUI显示但无法响应鼠标/键盘,在SDL和VNC上进行了测试。但CLI完美运行。因此,您最好现在使用没有GUI的Lite镜像。
  • 没有网络

步骤:

  1. Compile QEMU 2.9.0 from source:

    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. Download image and extract the kernel and dts from it:

    1. Download the image and unzip it:

      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. Mount the second image of the partition. The easiest way is:

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

      This only works with latest losetup on Ubuntu 16.04, other methods at: https://askubuntu.com/questions/69363/mount-single-partition-from-image-of-entire-disk-device/496576#496576

      This prints a loop device, e.g.:

      /dev/loop0
      

      so we do:

      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. Run:

    ./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,vanilla kernel
在这个更新的Ubuntu上,QEMU 2.8.0是默认设置,所以我们不需要为-M raspi2编译QEMU源代码。然而,在显示以下消息后,2.8.0会在启动时挂起:
Console: switching to colour frame buffer device 100x30

这表明-M raspi2仍然非常不稳定。
在这个更新的镜像上,使用与2016-05-27相同的方法,内核在启动时出现崩溃: [失败] Ubuntu 16.04,QEMU 2.9.0 -M raspi2,Raspbian 2017-08-16,vanilla kernel
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 RPI3 bare metal on QEMU

https://github.com/bztsrc/raspi3-tutorial 是一个很好的示例集,可以在 QEMU 上直接运行。快速入门请参考:https://raspberrypi.stackexchange.com/questions/34733/how-to-do-qemu-emulation-for-bare-metal-raspberry-pi-images/85135#85135


3

我曾经遇到一样的问题,使用自定义的ubuntu镜像。按照 @Michael Connors 的回答进行修改后,系统开始启动。

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接