I'm trying to emulate a Raspberry Pi with the Raspian OS using QEMU. I've tried several approaches described on the internet but without any success.
I figured out that I need to patch a Linux Kernel fitting the desired OS. In my case I chose Rasbian Lite with Kernel 4.4:
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
Next I load a Kernel from 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
Now cross compiling the Kernel:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
cd linux-4.4.16
make vexpress_defconfig
make all
cd ..
Now I can copy the boot image, that is a compressed kernel image that auto-extracts in RAM, to my workspace:
cp linux-4.4.16/arch/arm/boot/zImage zImage
and run 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"
But all I see is a black filled QEMU-window. :(
I think that the problem is to get the right Kernel. Copying some of the Kernels from the Internet never led to success because they are not fit for the OS.
How can I build/patch a Kernel fitting the OS (without downloading an existing one) and how to run QEMU properly?
Thanks in advance
Alex
2nd approach
I load a kernel-qemu from here https://www.dropbox.com/s/g8u93xblz1v1ly0/kernel-qemu?dl=0 and run QEMU with it:
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
This brings me the following output:
And it makes sense to me because the Kernel is 3.10.25 and older than Raspbian Jessie with Kernel 4.4.16.
With the qemu-kernel from https://github.com/dhruvvyas90/qemu-rpi-kernel/blob/master/kernel-qemu-4.4.12-jessie
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
I got this similar result:
A new try with a new kernel-qemu 4.4.16:
Copy build-kernel-qemu from https://github.com/dhruvvyas90/qemu-rpi-kernel/tree/master/tools and add the following line to checkout the version for Kernel 4.4.16:
git checkout b05965f284db3e086022f4e318e46cb5bffb1376
Run build-kernel-qemu to build the kernel
sh build-kernel-qemu
Run 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
The result:
You should expand the Raspbian Image file before starting
Mount the Raspbian Image file with kpartx (might have to install 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
Modify the /etc/fstab and comment out the MMCBLK mounts
$ 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
Modify /etc/ld.so.preload and comment out lines ...
$ sudo nano etc/ld.so.preload
#/usr/lib/arm-linux-gnueabihf/libarmmem.so
Unmount and destroy loops from kpartx
$ sudo umount /mnt/img1
$ sudo kpartx -d your-image.img
Get the Qemu kernel matching the Raspbian image here...
https://github.com/dhruvvyas90/qemu-rpi-kernel
I used this command to successfully emulate 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
You need a modified kernel in order to run in QEMU, because the raspberry PI board hardware is not available in QEMU. That is why your first approach failed.
Your second approach uses a kernel properly patched to run on the versatile board (supported by QEMU), so that is good, but the kernel 3.x is too old for a modern Raspbian. In principle your last approach should have worked.
I recommend this updated guide (feb 2017), I tested it with a 4.4 kernel and it works straight away.
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
I had to use format=raw,file=$IMG option to avoid a QEMU warning.
You don't need to comment out /etc/fstab, you can add to /etc/udev/rules.d/90-qemu.rules
KERNEL=="sda", SYMLINK+="mmcblk0"
KERNEL=="sda?", SYMLINK+="mmcblk0p%n"
KERNEL=="sda2", SYMLINK+="root"
Also, The ld.so.preload thing is old and does not apply anymore
The script provided on the mentioned guide does all this for you, and also provides network access to your raspbian by sharing your network interface with raspbian.
Ubuntu 16.04 host, QEMU 2.9.0 -M raspi2, Raspbian 2016-05-27, vanilla kernel
Advantages:
with -M raspi2, we can use the vanilla kernel, so the system is more representative
Limitations:
-M raspi2 was 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.
the GUI shows but is not responding to the mouse / keyboard, tested on both SDL and VNC. But CLI works perfectly however. So you might as well use the Lite image which has go GUI for now.
no networking
Steps:
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.:
/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
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 \
;
You can then login on the terminal that shows on your host terminal.
[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: https://raspberrypi.stackexchange.com/questions/34733/how-to-do-qemu-emulation-for-bare-metal-raspberry-pi-images/85135#85135
I had a similar problem with a custom ubuntu image.
I also applied the modifications as described in #Michael Connors' answer, then I see the system booting.
You can add the following in -append="" to see what happens in your case:
qemu-system-arm ... -serial stdio -append="... console=ttyAMA0,115200 loglevel=8"
Related
I want to simulate an arm environment for arm ubuntu 20.04 LTS.
The host is also ubuntu 20.04 LTS but not arm.
First I created an image like this:
qemu-img create -f qcow2 ubuntu.img 3G
then I ran this command:
sudo qemu-system-aarch64 -m 2048 -cpu cortex-a57 -M virt -nographic \
-bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd -drive \
file=ubuntu.img,if=none,id=hd0 -device virtio-blk-device,drive=hd0 \
-cdrom ubuntu.iso -boot d -netdev user,id=net0,hostfwd=tcp::5555-:22 \
-device virtio-net-device,netdev=net0
I installed the ubuntu on the qemu successfully and everything is working untill I reboot the guest or close the qemu.
After I close the qemu I tried to use the same command to boot the ubuntu without reinstalling it. But this doesn't worked and reinstall the ubuntu again.
I am stack about this problem for a while, and I would love to get some help.
I tried to remove the -cdrom ubuntu.iso but that boot the UEFI because the boot loader didn't find any OS.
Also I tried this command:
sudo qemu-system-aarch64 -m 1024 -cpu cortex-a57 -M virt -nographic \
-drive file=flash0.img,format=raw,if=pflash \
-drive file=flash1.img,format=raw,if=pflash \
-drive file=user-data.img,format=raw \
-drive if=none,file=ubuntu.img,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-device virtio-net-device,netdev=net0,mac=$randmac \
-netdev type=tap,id=net0
That I took from the ubuntu website and again the boot loader didn't find any OS.
Thanks in advance!
Problem
I try to run a qcow image with the following configuration:
:~$ sudo ~/Downloads/qemu-7.1.0/bin/debug/native/x86_64-softmmu/qemu-system-x86_64
-L -enable-kvm -cpu host -s -kernel bzImage -m 2048
-hda rootfs.qcow2-append "root=/dev/sda rw
nokaslr" -net nic,model=virtio -net user,hostfwd=tcp::5555-:22
Error Message:
qemu-system-x86_64: CPU model 'host' requires KVM or HVF
But kvm should be fine:
:~$ kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used
What I did:
I'd like to use qemu in version 7.1.0 and installed it following the wiki by using the tar archive.
# Switch to the QEMU root directory.
cd qemu
# Prepare a native debug build.
mkdir -p bin/debug/native
cd bin/debug/native
# Configure QEMU and start the build.
../../../configure --enable-debug
make
# Return to the QEMU root directory.
cd ../../..
The simple test from the wiki works fine.
bin/debug/native/x86_64-softmmu/qemu-system-x86_64 -L pc-bios
The "-L" option needs an argument (a path to the BIOS and other binary files), but you haven't given it one. QEMU's command line parser therefore thinks that you are asking it to look in a directory named "-enable-kvm", and that you haven't given '-enable-kvm' as an option at all. So it's running in TCG, where '-cpu host' is not valid.
You need to fix your command line: either specify the -L option correctly, or if you don't need it then just drop it.
You are also missing a space before '-append'.
If you got this command line from a tutorial, re-check it carefully and make sure you've got it exactly right, including any necessary pieces to add in and that all the spaces and punctuation are matching.
I have a FreeBSD image that contains /boot/loader* and /boot/kernel and more. It boots fine under an EC2 instance but I would like to boot it with Qemu. I have tried various methods, but they have not worked. See below.
qemu-system-x86_64 -kernel kernel -nographic -append 'console=ttyS0' disk.img
qemu-system-x86_64 -kernel loader -nographic -append disk.img
This boots on Ubuntu 20.04 amd64 host, QEMU 4.2.1:
wget https://download.freebsd.org/ftp/releases/VM-IMAGES/12.1-RELEASE/amd64/Latest/FreeBSD-12.1-RELEASE-amd64.qcow2.xz
unxz FreeBSD-12.1-RELEASE-amd64.qcow2.xz
sudo apt install qemu-system-x86
qemu-system-x86_64 -drive file=FreeBSD-12.1-RELEASE-amd64.qcow2,format=qcow2 -enable-kvm
The username is root with empty password:
The download page for that image is: https://www.freebsd.org/where.html
Unfortunately, trying to add:
-serial mon:stdio -nographic
to get rid of the GUI only shows the bootloader images on the terminal, but not the rest of boot. https://lists.freebsd.org/pipermail/freebsd-hackers/2005-March/011051.html mentions how to fix that by modifying the image, which is annoying, but worked. On the GUI boot, I did:
echo 'console="comconsole"' > /boot/loader.conf
and then the next nographic boot worked fully on my terminal.
You can quit QEMU -nographic with Ctrl-A X as shown at: https://superuser.com/questions/1087859/how-to-quit-the-qemu-monitor-when-not-using-a-gui/1211516#1211516
The next issue is that the disk is full, I have to learn to increase its size. From interactive df -Th inspection, the image appears to contain a single raw UFS partition. I tried:
qemu-img resize FreeBSD-12.1-RELEASE-amd64.qcow2 +1G
but that is not enough presumably because the partition itself was not resized to fit the disk. Likely this can be achieved with gpart as shown at: https://www.freebsd.org/doc/handbook/disks-growing.html but I don't have the patience right now.
The FreeBSD wiki has some recipes how to run FreeBSD inside Qemu
https://wiki.freebsd.org/QemuRecipes
I have 32bit ubuntu OS. On it I download lubuntu OS iso (64 bit). Then I ran qemu command
qemu-system-x86_64 -boot d -cdrom image.iso -m 512
After choosing live CD option I can access terminal.
What path do I use to access files on my original harddisk?
I don't see anything under /media/
also no directories of the type /dev/sda are shown under / in the live CD session.
Warning: this can unrecoverable destroy your data! Concurrent writing access to a disk is dangerous.
It is better to transfer files via nfs or ssh.
That said, it can be done this way (where '/dev/sdX' is '/dev/sdb' or alike):
qemu-system-x86_64 -boot d -cdrom image.iso -m 512 -hda /dev/sdX
I am trying to set up an Arch image and use qemu in order to cross-compile some stuff before I load the image onto the Pi. I thought the easiest way to do it would be to qemu the latest starter image, prepare it with whatever I needed, and then dd it onto the Pi when I was done.
I downloaded the Arch image from http://downloads.raspberrypi.org/arch_latest, and wanted to run it under Qemu similar to http://xecdesign.com/qemu-emulating-raspberry-pi-the-easy-way/.
I tried many variations on the qemu command line they gave
qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" -hda 2013-05-25-wheezy-raspbian.img
substituting the archlinux-hf-2013-07-22.img. But this eventually led to "Kernel panic - not syncing: No init found. Try passing init= option to kernel"
I'm sure this means the kernel-qemu I downloaded won't work with the Arch image, but I'm not sure the right way to fix the issue.
Edit:
Even the latest Raspbian image kernel panics when I use the command line above with it. Which I guess shouldn't have surprised me, since it's most likely an old kernel.
So I guess my real question is, how can I use whatever kernel is included in the image, rather than having to build my own kernel?
In case archlinux-hf-2013-07-22.img
Here there 3 partion are made.
you can check by using
fdisk -l archlinux-hf-2013-07-22.img
rootfs is in sd5 i.e 5th partion.
So pass this parameter "root=/dev/sda5 panic=1" , it will boot perfectly.
In 2013-05-25-wheezy-raspbian.img
You can use same kernel for both image.
Here you have to comment ld.so.preload which will load some shared-library,which will unable login. so kernel panic.
Note:-"root=/dev/sda2 panic=1" pass this parameter only.
You can comment it by doing below.
sudo kpartx -av 2013-05-25-wheezy-raspbian.img
mkdir tmp
sudo mount /dev/mapper/loop0p2 tmp/
cd tmp/etc
sudo vi ld.so.preload
/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
comment
#/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
umount /dev/mapper/loop0p2
kpartx -d 2013-05-25-wheezy-raspbian.img
Then run qemu
qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" -hda 2013-05-25-wheezy-raspbian.img
this will perfectly boot without any trouble