Running Debian on a QEMU emulated arm machine
Tags: qemu, debian, arm
Published: 2022-12-12 05:21:20

Here are the steps I followed to play with QEMU to get myself acquainted with it. My host is Ubuntu 20.04.1.

## 1. Building QEMU

There are several ways to download and build QEMU. You can install the pre-packaged version on Ubuntu with `apt` or download and build the latest release from the [QEMU website](https://www.qemu.org/download/). 

But to have the latest release and stay up to date, you can clone the git repository which is the way I'm doing.

Install the required additional packages as instructed [here](https://wiki.qemu.org/Hosts/Linux). I also installed the recommended additional packaged as well.

`sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-build`

Clone the source code:

`git clone git://git.qemu-project.org/qemu.git`

Initialize and update the submodules.

```
cd qemu
git submodule init
git submodule update --recursive
```

Create a new build directory:

```
mkdir build
cd build
```

Configure and build. If you want to build for a specific target(s) only which is faster, just add a `--target-list` option. Run `../configure --help` to see the list of available targets and other configuration options.
```
../configure
../configure --target-list=arm-softmmu
```

Build and if necessary, test which takes a lot of time.
```
make
make check
make install
```

## 2. Installing Debian

Download the arm disk image from [Debian](https://www.debian.org/devel/debian-installer/) or using `wget` from the server as shown below. It's the current version of Debian that will run on ARM machines. At the time of this post, the current version was codenamed `bullseye`.

```
wget http://ftp.debian.org/debian/dists/stable/main/installer-arm64/current/images/netboot/mini.iso
```

Download also the `vmlinux` kernel and `initrd.gz` initramfs.

```
wget http://ftp.debian.org/debian/dists/stable/main/installer-arm64/current/images/netboot/debian-installer/arm64/initrd.gz
wget http://ftp.debian.org/dget http://ftp.debian.org/debian/dists/stable/main/installer-arm64/current/images/netboot/mini.iebian/dists/stable/main/installer-arm64/current/images/netboot/debian-installer/arm64/linux
```

There are 3 different arm ports available: arm64, armhf and armel which are explained [here](https://www.debian.org/ports/arm/#:~:text=The%20newer%20ARM%20hard%2Dfloat,%2Dbit%20ARM%2Dpowered%20devices.) in detail. Basically, armel (arm EABI) is for older architecture versions (4T, 5T and 6), armhf (arm hard float) is for floating point support and arm64 for 64-bit ARMv8 architecture which I'll use. 

`qemu-system-` executables built in the previous step are for simulating different machines. `qemu-system-aarch64` will simulate arm64 machine.
The version used here is as shown below.

```
$ qemu-system-aarch64 --version
QEMU emulator version 7.1.93 (v7.2.0-rc3)
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developersurl
```

Create a hard disk image for our system by running `qemu-img` command. `qcow2` (QEMU copy on write) is a disk image file format native to the QEMU.

`qemu-img create -f qcow2 debian-arm.sda.qcow2 5G`

Start the installation process:

```
../qemu/build/qemu-system-aarch64 -M virt -cpu cortex-a53 -m 1G -kernel ./linux -initrd ./initrd.gz -hda debian-arm.sda.qcow2 -append "console=ttyAMA0" -drive file=./mini.iso,id=cdrom,if=none,media=cdrom -device virtio-scsi-device -device scsi-cd,drive=cdrom -nographic
```

After a few seconds, the kernel boots and Debian installer will start. You can just jump through the screens to configure your language, location, locale, keymap etc.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ob4f57id1ao13vtuky1.png)

But I encountered a network set-up problem and therefore couldn't access the Debian archive mirror. I'll look into it and post again.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ttwwgafybxg3aa2hb5da.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tupmys8gkmx92elq86nb.png)

Small tip: I didn't know how to exit the installer. Going back and choosing "Aborting the installer" option only reboot and restarted the installer. Instead you can choose "Execute a shell" and then type `poweroff`.

### Update

After a bit of research, it looks like setting up network on Debian is tricky. It could be a missing [device driver/firmware](https://wiki.debian.org/Firmware) since most of the firmware images are non-free, they are not included in the official Debian installation images. Unofficial images including non-free firmware are available, but there were none available for arm. 

Therefore I decided to use the DVD image that doesn't require network during the installation. I loosely followed the instructions this [blog](https://www.willhaley.com/blog/debian-arm-qemu/). 

Again, download the necessary files.

```
  curl -O http://ftp.us.debian.org/debian/dists/stable/main/installer-arm64/current/images/cdrom/initrd.gz
  curl -O http://ftp.us.debian.org/debian/dists/stable/main/installer-arm64/current/images/cdrom/vmlinuz
  curl -O -L https://cdimage.debian.org/debian-cd/current/arm64/iso-dvd/debian-11.6.0-arm64-DVD-1.iso
```

Boot the VM to install Debian.
debian-arm.sda.qcow2
```
qemu-system-aarch64 -m 4G -machine type=virt -cpu cortex-a53 -initrd "./initrd.gz" \
  -kernel "./vmlinuz" -append "console=ttyAMA0" \
  -drive file="./debian-11.6.0-arm64-DVD-1.iso", id=cdrom,if=none,media=cdrom \
    -device virtio-scsi-device \
    -device scsi-cd,drive=cdrom \
  -drive file="./debian-arm.sda.qcow2", id=hd,if=none,media=disk \
    -device virtio-scsi-device \
    -device scsi-hd,drive=hd \
  -nographic
```
The network setup will fail again, but you can choose `Do not configure the network at this time` and the installation will run smoothly after that. 

When prompted about the bootloader, you can just choose `Continue`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5cwozsjgxtir08vhmhr.png)

After installation finishes, don't click on the `Continue` because it'll start the installer all over again. Rather, choose `Go back`, `Execute a shell` and then type `poweroff`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fjeg3hbxohcu3fqfhc5d.png)