How can I connect an SD card containing a Raspberry Pi OS to my Linux PC, and boot the OS in an emulator?
Why won't VMWare work?
What are the limitations of this method?
Related: Emulation on a Windows PC
Raspberry Pi Stack Exchange is a question and answer site for users and developers of hardware and software for Raspberry Pi. It only takes a minute to sign up.Sign up to join this community
Yes this is completely possible. However, in reality it's a little bit different to how you are thinking.
The SD card contains an image of the operating system. And works by inflating this image when the device is powered on.
As I expect you already know, you flash this image onto the SD card in order to create a working system. However, what you can do before you flash the image is have a play around with it using QEMU, which is a processor emulator, and allows us to emulate the ARM instruction set.
In this way, any changes you make to the image (installing, compiling etc) will still be there after you flash it to the SD card.
I'll now talk you through how to use QEMU to load the image. I will be demonstrating with the Arch Linux image, but the process should be the same regardless.
You will need to acquire QEMU for your system. QEMU should only have one requirement, in order in input devices to work you need to have the SDL development package installed, which should be available from your package manager.
I recommend downloading the package using your regular package manager:
sudo pacman -S sdl qemu
More recent versions (since 14.04) have a package for it:
sudo apt-get install qemu-system-arm
For older versions:
sudo apt-get install libsdl-dev sudo add-apt-repository ppa:linaro-maintainers/tools sudo apt-get update sudo apt-get install qemu-system
Building QEMU yourself
Alternatively, you can build QEMU yourself. This is great if you want to try a new version, but it can be slow and be prepared for lots of errors during compilation! Note that if building QEMU from their website it must be compiled for ARM support. So check your distro repositories first. This can be done like so;
mkdir rpi-emu && cd rpi-emu wget http://wiki.qemu.org/download/qemu-1.1.0-1.tar.bz2 tar xvjf qemu-1.1.0-1.tar.bz2 cd qemu-1.1.0-1 ./configure –target-list=arm-softmmu,arm-linux-user make sudo make install
Verify that you have ARM support with:
qemu-system-arm --version QEMU emulator version 1.0,1, Copyright (c) 2003-2008 Fabrice Bellard
We're working with Arch Linux, so will be using the Arch Arm image. But replace this with whatever you wish to work with, or perhaps you already have an image. In which case, skip this step.
wget http://anorien.csc.warwick.ac.uk/mirrors/raspberrypi.org/images/archlinuxarm/archlinuxarm-29-04-2012/archlinuxarm-29-04-2012.zip unzip archlinuxarm-29-04-2012.zip
For QEMU to work we also need the kernel image (which would be inside the .img file).
Note: I don't think this step is necessary for Debian. Someone please confirm.
TODO: Demonstrate how to compile a kernel image here?
You should now have:
The Virtual Machine can now be started using the following long-winded command:
qemu-system-arm -kernel zImage -cpu arm1176 -M versatilepb -serial stdio -append "root=/dev/sda2" -hda archlinuxarm-29-04-2012.img -clock dynticks
Note that you will only have several hundred megabytes of storage using this method (whatever is spare on the image). A virtual hard disk can be created by following the QEMU user guide.
Ubuntu 16.04, QEMU 2.9.0 -M raspi2, Raspbian 2016-05-27, vanilla kernel
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`
Download image and extract the kernel and dts from it:
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
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.:
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
./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 \ ;
You can then login on the terminal that shows on your host terminal.
-M raspi2was added in QEMU 2.6.0, and Ubuntu 16.04 only has QEMU 2.5.0, so we have to compile QEMU from source. But this is not hard.
Ubuntu 16.04, QEMU 2.5.0, Raspbian 2016-05-27, modified kernel
This method uses
-M versatilepb which is present on the QEMU 2.5.0 of Ubuntu 16.04.
The downside is that you have to download a modified kernel (see Emulating with Qemu: why the extra kernel?), and modify the image, so it is less representative of the real system.
4.4.12 since that is the kernel version in the Raspbian image.
The process to generate that kernel blob is described at in the repository at: https://github.com/dhruvvyas90/qemu-rpi-kernel/tree/36ede073f4ccb64f60200ede36c231afe9502070/tools
Why this extra kernel image is needed: Emulating with Qemu: why the extra kernel?
Modify the Raspbian image as mentioned at: https://github.com/dhruvvyas90/qemu-rpi-kernel/wiki/Emulating-Jessie-image-with-4.x.xx-kernel/0068f0c21d942b0f331e18014ff8e22c20cada5c
Mount the image just as we did for the
-M raspi2, but use the second partition instead of the first:
sudo mount /dev/loop0p2 /mnt/rpi
Edit the image:
# Comment out the line present there with # sudo vim /mnt/rpi/etc/ld.so.preload # Comment out the lines of type: "/dev/mmcblk*" sudo vim /mnt/rpi/etc/fstab
sudo apt-get install qemu-system-arm 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" \ -hda 2016-05-27-raspbian-jessie.img
[failed] Ubuntu 17.04, QEMU 2.8.0 -M raspi2, Raspbian 2016-05-27, vanilla kernel
On this newer Ubuntu, QEMU 2.8.0 is the default, so we don't need to compile QEMU from source for
-M raspi2. However, 2.8.0 hangs on boot after the message:
Console: switching to colour frame buffer device 100x30
This goes to show how unstable
-M raspi2 still is.
[failed] Ubuntu 16.04, QEMU 2.9.0 -M raspi2, Raspbian 2017-08-16, vanilla kernel
On this newer image, using the same method for 2016-05-27, the kernel panics at boot with:
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 is a good set of examples that just work on QEMU, ultraquick getting started at: How to do QEMU emulation for bare metal Raspberry Pi images
You cannot do what you're suggesting, because Raspberry Pi has a different processor architecture than most PCs. While most PCs are x86-based, RPi is an ARM-based computer.
This is the same reason as why you cannot run, for example, Microsoft Windows on RPi.
VmWare won't work, because it can only virtualize x86-based operating systems (32-bit and 64-bit). There are other emulators that can virtualize ARM, such as QEMU, but those are running full software emulation without native CPU virtualizaton support, so you can expect them to be quite slow.
You could easily try a Raspberry Pi simulator included with sensor, command line and file editor at iotify.io. Check out our documentation at https://docs.iotify.io/ to get started with the different projects, OS and make yourself familiar with Raspberry Pi working environment.