Skip to content

Instantly share code, notes, and snippets.

@stefanozanella
Last active June 12, 2023 23:05
Show Gist options
  • Save stefanozanella/4608873 to your computer and use it in GitHub Desktop.
Save stefanozanella/4608873 to your computer and use it in GitHub Desktop.
Emulate a Raspberry Pi with Qemu+ KVM

Booting with CNXSoft image

Reference: http://www.cnx-software.com/2012/07/31/84-mb-minimal-raspbian-armhf-image-for-raspberry-pi/

curl -O https://dl.dropbox.com/u/45842273/2012-07-15-wheezy-raspian-minimal.img.7z

yum install p7zip
7za e 2012-07-15-wheezy-raspian-minimal.img.7z

qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" -hda 2012-07-15-wheezy-raspian-minimal.img -net nic -net user -vnc :0 -net tap,ifname=vnet0,script=no,downscript=no

Running with custom Raspbian installation

Prepare installer image

yum install makebootfat dosfstools

dd if=/dev/zero of=rpi_installer.img bs=1M count=2048
losetup /dev/loop0 rpi_installer.img
kpartx -av /dev/loop0
fdisk /dev/loop0
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-261, default 1): 
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-261, default 261): 
Using default value 261

Command (m for help): a
Partition number (1-4): 1

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 22: Invalid argument.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.
kpartx -av /dev/loop0
mkfs.vfat /dev/mapper/loop0p1
mkdir /tmp/x
mount -o loop rpi_installer.img /tmp/x
cd /tmp/x
unzip /root/rpi_installer_08-19-12.zip
cd && umount /tmp/x
losetup -d /dev/loop0

qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda1 panic=1" -hda rpi_installer.img -net nic -net user -vnc :1 -net tap,ifname=vnet1,script=no,downscript=no

VM doesn't boot for lack of init script.

Running with offical Raspberry Pi Raspbian image

References

Install guest machine

virt-install --name=owen --ram=1024 --vcpus=1   --cdrom=/media/CentOS-6.3-x86_64-minimal.iso  --os-type=linux --os-variant=rhel6   --disk pool=vmstorage,size=20 --network bridge=br0,model=e1000   --video=vga --vnc --connect qemu:///system

Installation options: (copy params from post and adapt) /dev/vda1 500 /boot /dev/vda2 19979 os root 17960 /root ext4 swap 2016 - swap (copy default tasks from post)

Prepare environment

curl -O http://ftp.snt.utwente.nl/pub/software/rpi/images/raspbian/2012-12-16-wheezy-raspbian/2012-12-16-wheezy-raspbian.zip
curl -O http://xecdesign.com/downloads/linux-qemu/kernel-qemu

yum install unzip
unzip  2012-12-16-wheezy-raspbian.zip
yum install http://www.opencomputingsolutions.com/pub/rpms/over/centos/6/x86_64/qemu-1.1.0-1.x86_64.rpm http://www.opencomputingsolutions.com/pub/rpms/over/centos/6/x86_64/qemu-arm-1.1.0-1.x86_64.rpm

Expand official image and convert to qcow

qemu-img convert -f raw -O qcow2 2012-12-16-wheezy-raspbian.img raspbian.qcow
qemu-img resize raspbian.qcow +6G

qemu-img info raspbian.qcow 
image: raspbian.qcow
file format: qcow2
virtual size: 7.8G (8382316544 bytes)
disk size: 1.6G
cluster_size: 65536

Launch Raspberry Pi Emulation

screen -dmS rpi qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" -hda 2012-12-16-wheezy-raspbian.img -net nic -net user -vnc :0 -net tap,ifname=vnet0,script=no,downscript=no

Configurator:

  • change_locale -> en_GB.UTF-8
  • change_timezone -> Europe/Rome
  • ssh -> Enable
  • boot_behaviour -> Boot straight to desktop? Yes

Setup bridge on host VM:

vi /etc/sysconfig/network-script/ifcfg-virbr0
DEVICE=virbr0
TYPE=Bridge
IPADDR=172.16.32.6
NETMASK=255.255.255.0
GATEWAY=172.16.32.254
ONBOOT=yes
BOOTPROTO=static
IPV6INIT=no
IPV6_AUTOCONF=no
STP=no
vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
BOOTPROTO="none"
HWADDR="52:54:00:70:79:B3"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE="Ethernet"
UUID="e2d7181d-be2d-496f-aa2f-d4c49832c393"
BRIDGE="virbr0"
PROMISC="yes"

Add raspberry interface to bridge:

brctl addif virbr0 vnet0
ip link set vnet0 up

Configure address on RPi interface:

sudo vi /etc/network/interfaces
iface eth0 inet static
address 172.16.32.7
netmask 255.255.255.0
gateway 172.16.32.254
sudo vi /etc/resolv.conf
nameserver 8.8.8.8

Update packages and install puppet:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install puppet

Configure server:

sudo vi /etc/puppet/puppet.conf
...
[agent]
server = puppet.derecom.it

First run:

sudo puppet agent --test --verbose

On the master:

puppet ca sign raspberrypi

Resize RPi Root Partition

sudo fdisk /dev/sda
Command (m for help): d
Partition number (1-4): 2
Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (1-4, default 2): 2
First sector (2048-16371711, default 2048): 122880
Last sector, +sectors or +size{K,M,G} (122880-16371711, default 16371711): 
Using default value 16371711

Command (m for help): p

Disk /dev/sda: 8382 MB, 8382316544 bytes
64 heads, 32 sectors/track, 7994 cylinders, total 16371712 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00017b69

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1            8192      122879       57344    c  W95 FAT32 (LBA)
/dev/sda2          122880    16371711     8124416   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.

Reboot??? (I needed to do so, even after running partprobe).

sudo resize2fs /dev/sda2 
resize2fs 1.42.5 (29-Jul-2012)
Filesystem at /dev/sda2 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/sda2 is now 2031104 blocks long.

pi@raspberrypi ~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs          7.7G  1.6G  5.8G  22% /
/dev/root       7.7G  1.6G  5.8G  22% /
devtmpfs        124M     0  124M   0% /dev
tmpfs            25M  180K   25M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            50M     0   50M   0% /run/shm

Booting with UBoot for Raspberry

curl -O http://people.freebsd.org/~gonzo/arm/rpi/raspberry-pi-uboot-20120621.tar.gz

yum install makebootfat dosfstools

dd if=/dev/zero of=uboot.img bs=1M count=2048
losetup /dev/loop1 uboot.img
kpartx -av /dev/loop1
fdisk /dev/loop1
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-261, default 1): 
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-261, default 261): 
Using default value 261

Command (m for help): a
Partition number (1-4): 1

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 22: Invalid argument.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.
kpartx -av /dev/loop1
mkfs.vfat /dev/mapper/loop1p1
mkdir /tmp/x
mount -o loop /dev/mapper/loop1p1 /tmp/x
cd /tmp/x
tar zxvf /root/raspberry-pi-uboot-20120621.tar.gz
cd && umount /tmp/x
losetup -d /dev/loop0

qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda1 panic=1" -hda uboot.img -net nic -net user -vnc :1 -net tap,ifname=vnet1,script=no,downscript=no

Same failure as with installer...

@hydrian
Copy link

hydrian commented Jul 16, 2020

@Darkn3ssF4lls I agree. Downloading a binary tarball on dropbox with a date that goes back to 2012 doesn't promote trust.

@Marietto2008
Copy link

I don't like these parameters :

m 256 -M versatilepb

I tried to do something like this :

virt-install
--name pi
--machine raspi3
--cpu arm1176
--memory 1024
--import \ --disk /root/Desktop/zi/Work/Android/Raspy/Debian/2019-09-26-raspbian-buster-lite.img,format=raw,bus=virtio
--network user,model=virtio
--video vga
--graphics spice
--rng device=/dev/urandom,model=virtio
--boot 'uefi=RPI_EFI.fd,dtb=bcm2710-rpi-3-b-plus.dtb,kernel=kernel8.img,kernel_args=root=/dev/vda2 rootwait panic=1 dwc_otg.fiq_fsm_enable=0'
--events on_reboot=destroy

But I get this error :

ERROR internal error: Unexpected enum value 0 for virDomainDeviceAddressType

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment