0x1 Preparation
So in order to install a working debian system on arbitrary qemu arch, you first need to install qemu ofc, I won’t talk about how to install qemu here, I assume you already have qemu-system-* installed.
Here I’ll show an example to install aarch64 debian
So you need 3 other files besides qemu-system-aarch64, which is debian image, vmlinuz and initrd.gz
You first check the following url to get your debian image: https://cdimage.debian.org/debian-cd/current/
NOTE: Download the dvd version!
In my case the download url is : https://cdimage.debian.org/debian-cd/current/arm64/iso-dvd/debian-12.4.0-arm64-DVD-1.iso
The vmlinuz and initrd.gz is essential to boot your system, luckily you can get them easily from here: http://ftp.us.debian.org/debian/dists/stable/main/
Again, choose what arch you want to use, in my case my full url would be: http://ftp.us.debian.org/debian/dists/stable/main/installer-arm64/current/images/cdrom/
NOTE: Download from the cdrom folder!
See that initrd.gz and vmlinuz from above url? Download it and save it with image downloaded before in same folder.
0x2 Installation
Create a hard disk to use first, here’s an example command:
qemu-img create -f qcow2 hda.qcow 100G
The 100G is probably overkill, you can adjust the value yourself.
I feel like the most frustration part is constructing qemu command line arguments, so here’s what I use, please replace the actual filename with yours.
qemu-system-aarch64 \
-m 4G \
-machine type=virt \
-cpu max \
-smp 4 \
-initrd "./initrd.gz" \
-kernel "./vmlinuz" \
-append "console=ttyAMA0" \
-drive file="./debian-12.4.0-arm64-DVD-1.iso",id=cdrom,if=none,media=cdrom \
-device virtio-scsi-device \
-device scsi-cd,drive=cdrom \
-drive file="./hda.qcow",id=hd,if=none,media=disk \
-device virtio-scsi-device \
-device scsi-hd,drive=hd \
-netdev user,id=net0 \
-device virtio-net-device,netdev=net0 \
-monitor null \
-nographic
The first parameter -m indicates the memory guest has, you can adjust it as you wish.
The second and third parameter is quite essential too, they are the machine type and cpu type, so how do you get these values? Boom, qemu documentation!
You can view the documentation from here https://www.qemu.org/docs/master/system/targets.html
You first choose the documentation page matches your arch type, aarch64 is arm64 which is at same page as arm, https://www.qemu.org/docs/master/system/target-arm.html
Now choose your machine type, here I choose virt, so the detail pages is: https://www.qemu.org/docs/master/system/arm/virt.html
And here you go, you can see the max is listed as a cpu type, so here is how we construct the parameters.
After you successfully boot the system, install it as usual.
However you may encounter following screen, please remember the root=/dev/sda2 part. Hit continue.
โโโโโโโโโโโโโโโโโโโค [!] Continue without boot loader โโโโโโโโโโโโโโโโโโโโ
โ โ
โ No boot loader installed โ
โ No boot loader has been installed, either because you chose not to or โ
โ because your specific architecture doesn't support a boot loader yet. โ
โ โ
โ You will need to boot manually with the /vmlinuz kernel on partition โ
โ /dev/sda1 and root=/dev/sda2 passed as a kernel argument. โ
โ โ
โ <Continue> โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
<Tab> moves; <Space> selects; <Enter> activates buttons
0x3 Boot
To boot the installed system normally, you would need to extract the vmlinuz and initrd from the the installed hard drive.
First power off the vm, or just kill the qemu.
Now how do we extract the files from qcow2 hard disk file?
Here is the full command list I used, from mounting to unmounting.
sudo apt-get install qemu-utils
sudo modprobe nbd max_part=8
sudo qemu-nbd --connect=/dev/nbd0 hda.qcow
sudo mount /dev/nbd0p1 /mnt
cp /mnt/boot/initrd.img-* .
cp /mnt/boot/vmlinuz-* .
sudo umount /mnt
sudo qemu-nbd --disconnect /dev/nbd0
NOTE: the initrd img and vmlinuz files probably not in /mnt/boot, maybe they’re in /mnt, check /mnt as well!
Basically this script mounts the hda.qcow file to /mnt, and copy the boot files out, and then unmount it.
And now we have everything ready to boot the newly installed system!
Note: use the same version of initrd-img and vmlinuz!
qemu-system-aarch64 \
-m 4G \
-machine type=virt \
-cpu max \
-smp 4 \
-initrd "./initrd.img-6.1.0-17-arm64" \
-kernel "./vmlinuz-6.1.0-17-arm64" \
-append "console=ttyAMA0, root=/dev/sda2" \
-drive file="./hda.qcow",id=hd,if=none,media=disk \
-device virtio-scsi-device \
-device scsi-hd,drive=hd \
-nic user,model=virtio-net-pci,hostfwd=tcp::2222-:22 \
-monitor null \
-nographic
You may noticed the root=/dev/sda2, that’s from part 2, remember the parameter when it shows the warning!
Also here I forward the ssh port from guest to host port 2222.
PS: Comment out the first line of /etc/apt/sources.list!
#deb cdrom:[Debian GNU/Linux ....
Congratulations! Now you have your first working qemu system!