-----------------------------------------------------------
Raspberry Pi Zero W to Qemu - Physical to Virtual Migration
-----------------------------------------------------------

April 2022

Prerequisities:

1] Raspberry Pi Zero W (or just any raspberry) on Raspbian
   with sshd running
2] Qemu sources 
   https://github.com/qemu/qemu
   here tested with qemu 6.2.93
3] Linux Computer 
   here Debian 10 we will call it deb
4] good tcp/ip connection between rpi and deb

-----------------------------------------------------------

The process:

0] We will store the data to ~/virtual/rpi

   d# mkdir -p ~/virtual/rpi

a] We will first transfer the boot partition to deb

  1] first ssh to rpi (ssh root@rpi)
     I assume You have:
     /dev/mmcblk0p1 mounted on /boot (cca 256 MB)
  2] We will make binary copy of the boot partition to deb 
     on rpi:
     r# ssh deb "sudo -S dd if=/dev/mmcblk0p1 bs=64k status=progress | gzip -1 -" | dd of=rpi_boot_part.gz bs=64k

b] Now we will prepare the disk for the virtual machine

  1] to create qemu e.g. 32 GB disk
     d# cd ~/virtual/rpi
     d# qemu-img create -f qcow2 sys.qcow2 32G

c] Next we will mount and partition the virtual disk

  1] first mount the disk
     d# qemu-nbd -c /dev/nbd0 sys.qcow2
  2] now we will prepare the same partitions as it is on physical rpi
     d# sudo fdisk /dev/nbd0
  3] For reference use on physical rpi:
     r# fdisk -l /dev/mmcblkp01
     e.g.
     Device         Boot  Start       End   Sectors   Size Id Type
     /dev/mmcblk0p1        8192    532479    524288   256M  c W95 FAT32 (LBA)
     /dev/mmcblk0p2      532480 249737215 249204736 118.8G 83 Linux
  4] With this knowledge prepare virtual hdd on deb
     d# sudo fdisk /dev/ndb0
     i] create boot partition in fdisk e.g.
     enter: n # new partition
     enter: p # primary
     enter: 1 # partition number
     enter: 8192 # first sector (from step 3 the same as on source)
     enter: 532479 # last sector (from step 3 the same as on source)
     ii] change boot partition type
     enter: t # change the type
     enter: 1 # partition number (boot partition)
     enter: c # the same type as in step 3 (W95 FAT32 LBA)     
     iii] prepare the root partition
     enter: n # new partition
     enter: p # primary
     enter: 2 # partition number
     enter: 532480    # first sector (from step 3 the same as on source)
     enter: 249737215 # last sector (from step 3 the same as on source)
     iv] change type of the root partition
     enter: t  # change the type
     enter: 1  # partition number (boot partition)
     enter: 83 # the same type as in step 3 (Linux)     
     v] save virtual disk partitions
     enter: w # writes partition table to virtual disk and exits
  5] Prapare the root filesystem (/dev/nbd0p2)
     d# mkfs.ext4 /dev/nbd0p2
  6] Binary copy the boot partition (/dev/nbd0p1)
     d# gunzip rpi_boot_part.gz
     d# sudo dd if=rpi_boot_part of=/dev/nbd0p1
  7] Now mount the root partition 
     d# mkdir /mnt/rpiroot
     d# mount /dev/nbd0p2 /mnt/rpiroot
  8] Copy files from the rpi to mounted virtual partition on deb
     p# rsync -aAXv / --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} root@deb:/mnt/rpiroot
  9] We will copy current physical dtb and kernel from the boot to use it in emulation
     d# mkdir /mnt/rpiboot 
     d# mount /dev/nbd0p1 /mnt/rpiboot
     d# cp /mnt/rpiboot/bcm2709-rpi-2-b.dtb ~/virtual/rpi
     d# cp /mnt/rpiboot/kernel7.img ~/virtual/rpi
  10] Now on deb unmount the root partition and virtual disk
     d# umount /dev/nbd0p2
     d# sudo qemu-nbd -d /dev/nbd0

d] Prepare the newest qemu (we need only qemu-system-arm

  1] get the qemu sources
     # git clone https://github.com/qemu/qemu.git
  2] build it 
     # cd qemu
     # mkdir build
     # cd build
     # ../configure
     # make
  3] get the qemu-system-arm and put it to the virtual rpi folder
     # cp qemu-system-arm ~/virtual/rpi

e] Boot the virtual machine (with usb networking)
  
  1] now we will boot the machine using:
     # cd ~/virtual/rpi
     # prepare run.sh with following content:
     ./qemu-system-arm \
     -M raspi2b \
     -dtb bcm2709-rpi-2-b.dtb \
     -kernel kernel7.img \
     -append 'rw earlycon=pl011,0x3f201000 console=ttyAMA0 loglevel=2 root=/dev/mmcblk0p2 fsck.repair=yes net.ifnames=0 rootwait memtest=1 dwc_otg.fiq_fsm_enable=0' \
     -m 1024 \
     -smp 4 \
     -serial stdio \
     -hda sys.qcow2 \
     -usb \
     -device usb-kbd \
     -device usb-tablet \
     -device usb-net,netdev=ulan \
     -netdev user,id=ulan,hostfwd=tcp::2222-:22 \
     -display none \
     -no-reboot
  2] boot the virtualized rpi:
     # ./run.sh

-----------------------------------------------------------