Project

General

Profile

Support #929

Updated by Daniel Curtis about 2 years ago

This is a guide on virtualizing an ARM based operating system, in this case Raspbian for the Raspberry Pi 3, on an x86_64 Arch Linux system. 

 h2. Prepare the environment 

 * Make sure the system is up to date: 
 <pre> 
 sudo pacman -Syu 
 </pre> 

 * Install a few dependencies: 
 <pre> 
 sudo pacman -S git base-devel wget 
 </pre> 

 h2. Prepare Disk Image 

 * Create the guest drive: 
 <pre> 
 dd if=/dev/zero of=~/raspi.img bs=1M count=16384 
 </pre> 

 * Format the guest drive: 
 <pre> 
 fdisk ~/raspi.img 
 </pre> 
 #* Basic format: 
 <pre> 
 n 
 p 
 1 
 <enter> 
 +200M 
 n 
 p 
 <enter> 
 <enter> 
 <enter> 
 w 
 </pre> 

 * Download the latest raspberry pi OS image: 
 <pre> 
 mkdir ~/raspios && cd ~/raspios 
 wget https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2022-01-28/2022-01-28-raspios-bullseye-armhf-lite.zip 
 unzip 2022-01-28-raspios-bullseye-armhf-lite.zip 
 </pre> 

 * Populate the guest drive: 
 <pre> 
 mkdir ~/src_boot && mkdir ~/src_root && mkdir ~/dst_boot && mkdir dst_root 
 sudo losetup -f --show ~/raspi.img 
 sudo partx -a /dev/loop0 
 sudo mkfs.vfat /dev/loop0p1 
 sudo mkfs.ext4 /dev/loop0p2 
 sudo mount /dev/loop0p1 ~/dst_boot 
 sudo mount /dev/loop0p2 ~/dst_root 
 sudo losetup -f -o 4194304 --show ~/raspbian/2022-01-28-raspios-bullseye-armhf-lite.img 
 sudo mount /dev/loop1 ~/src_boot 
 sudo losetup -f -o 272629760 --show ~/raspios/2022-01-28-raspios-bullseye-armhf-lite.img 
 sudo mount /dev/loop2 ~/src_root 
 sudo cp -r ~/src_boot/*.* ~/dst_boot/ 
 sudo cp -r ~/src_root/* ~/dst_root/ 
 </pre> 

 * Edit the guest drive fstab: 
 <pre> 
 sudo nano ~/root/etc/fstab 
 </pre> 
 #* And change the following: 
 <pre> 
 /dev/sda1    /boot             vfat      defaults            0         2 
 /dev/sda2    /                 ext4      defaults,noatime    0         1 
 </pre> 

 * Unmount the guest drive: 
 <pre> 
 sudo umount ~/src_boot 
 sudo umount ~/src_root 
 sudo umount ~/dst_boot 
 sudo umount ~/dst_root 
 sudo losetup -d /dev/loop2 
 sudo losetup -d /dev/loop1 
 sudo losetup -d /dev/loop1 
 </pre> 

 h2. Install Qemu 

 * Install qemu and the extra architectures: 
 <pre> 
 pacman -S git qemu qemu-arch-extra wget 
 </pre> 

 * Download prebuilt kernels: 
 <pre> 
 mkdir ~/git && cd ~/git 
 git clone https://github.com/dhruvvyas90/qemu-rpi-kernel.git 
 </pre> 

 h3. Run Qemu 

 * Run the newly built kernel with the latest raspbian: 
 <pre> 
 qemu-system-arm -kernel ~/git/qemu-rpi-kernel/kernel-qemu-5.10.63-bullseye -cpu 1176 -m 2048 -M versatilepb -dtb ~/git/qemu-rpi-kernel/versatile-pb-bullseye-5.10.63.dtb -serial stdio -append "root=/dev/sda2 rootfstype=ext4 rw" -hda ~/raspi.img -redir tcp:5022::22 -no-reboot 
 </pre> 

 * Log in as the user *pi* with the password *raspberry* 

 * Configure the pi to your use case: 
 <pre> 
 sudo raspi-config 
 </pre> 
 #* Go to *Interfacing* and enable SSH. 
 #* Change *Localization*. 

 h2. Compiling Latest kernel 

 h3. Install ARM toolchain: 

 * Clone the toolchain repo (using @--depth 1@ will decrease the overall download size by 400MB): 
 <pre> 
 mkdir ~/git && cd ~/git 
 git clone --depth 1 https://github.com/raspberrypi/tools.git 
 </pre> 

 * Add the tools to your path: 
 <pre> 
 echo 'export PATH=$PATH:~/git/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin' >> ~/.bash_profile 
 </pre> 

 * Source the @.bash_profile@: 
 <pre> 
 source ~/.bash_profile 
 </pre> 

 h2. Install Qemu 

 * Install qemu and the extra architectures: 
 <pre> 
 pacman -S git qemu qemu-arch-extra wget 
 </pre> 

 h3. Compile Latest Kernel 

 * Download the qemu-rpi-kernel repo: 
 <pre> 
 cd ~/git 
 git clone https://github.com/dhruvvyas90/qemu-rpi-kernel.git 
 </pre> 

 * Clone the specific kernel version to use: 
 <pre> 
 cd qemu-rpi-kernel/tools 
 git clone -b rpi-5.10.y raspberrypi-kernel_1.20180313-1 --depth 1 https://github.com/raspberrypi/linux.git 
 </pre> 

 * Modify the kernel compile script to use Arch commands: 
 <pre> 
 sed -i.bak -e's/sudo\ apt-get\ update/sudo\ pacman\ -Syu/g' -e's/sudo\ apt-get\ install\ git\ libncurses5-dev\ gcc-arm-linux-gnueabihf/sudo\ pacman\ -S\ git/g' build-kernel-qemu 
 </pre> 

 * Edit the build-kernel-qemu script: 
 <pre> 
 vi build-kernel-qemu 
 </pre> 
 #* And comment out all @COMMIT@ versions except for the desired commit, and also comment out the @exit@ command before the @make@ commands: 
 <pre> 
 #COMMIT=6820d0cbec64cfee481b961833feffec8880111e 
 #COMMIT=raspberrypi-kernel_1.20171029-1 
 #COMMIT="" 
 COMMIT=rpi-5.10.y COMMIT=raspberrypi-kernel_1.20180313-1 

 #exit 
 </pre> 

 * Run the build script: 
 <pre> 
 ./build-kernel-qemu 
 </pre> 

 h2. Prepare Raspbian 

 * Download the latest raspbian image (1.7G): 
 <pre> 
 mkdir ~/raspbian && cd ~/raspbian 
 wget http://downloads.raspberrypi.org/raspbian/images/raspbian-2018-03-14/2018-03-13-raspbian-stretch.zip 
 unzip 2018-03-13-raspbian-stretch.zip 
 </pre> 

 * Show the partition layout of 
 <pre> 
 fdisk -l 2018-03-13-raspbian-stretch.img 
 </pre> 
 #* _Example output_: 
 <pre> 
 Disk 2018-03-13-raspbian-stretch.img: 4.6 GiB, 4949278720 bytes, 9666560 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 
 Disklabel type: dos 
 Disk identifier: 0x15ca46a5 

 Device                             Boot Start       End Sectors    Size Id Type 
 2018-03-13-raspbian-stretch.img1         8192     93802     85611 41.8M    c W95 FAT32 ( 
 2018-03-13-raspbian-stretch.img2        98304 9666559 9568256    4.6G 83 Linux 
 </pre> 

 * Find the sector where the filesystem, 2018-03-13-raspbian-stretch.img2, starts at (sector 98304). Multiply the sector start value by 512, in this case 98304 * 512 = 50331648 bytes.  

 * Mount the rasbian image at offset 50331648: 
 <pre> 
 mkdir -p /media/raspbian 
 mount -v -o offset=50331648 -t ext4 ~/raspbian/2018-03-13-raspbian-stretch.img /media/raspbian 
 </pre> 

 * Edit the ld.so.preload file and comment out all visible lines 
 <pre> 
 nano /media/raspbian/etc/ld.so.preload 
 </pre> 

 h3. Run Qemu 

 * Run the newly built kernel with the latest raspbian: 
 <pre> 
 qemu-system-arm -kernel ~/git/qemu-rpi-kernel/qemu-kernel-4.9.80 -cpu arm1176 -m 256 -M versatilepb -dtb /git/qemu-rpi-kernel/versatile-pb.dtb -serial stdio -append "root=/dev/sda2 rootfstype=ext4 rw" -hda ~/raspbian/2018-03-13-raspbian-stretch.img -redir tcp:5022::22 -no-reboot 
 </pre> 

 * Log in as the user *pi* with the password *raspberry* 

 * Configure the pi to your use case: 
 <pre> 
 sudo raspi-config 
 </pre> 
 #* Go to *Interfacing* and enable SSH. 
 #* Change *Localization*. 

 h2. Resources 

 * https://azeria-labs.com/emulate-raspberry-pi-with-qemu/ 
 * http://graznik.de/posts/emulate-raspberry-pi-with-qemu/ 
 * http://downloads.raspberrypi.org/raspbian/images/raspbian-2018-03-14/ 
 * https://github.com/raspberrypi/linux/releases 
 * https://github.com/dhruvvyas90/qemu-rpi-kernel

Back