Skip to content

Instantly share code, notes, and snippets.

@beyond2002
Forked from ecliptik/aarch64qemu.md
Last active December 21, 2020 02:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beyond2002/4f10f0ffff66ae37bf825f08a9a767bc to your computer and use it in GitHub Desktop.
Save beyond2002/4f10f0ffff66ae37bf825f08a9a767bc to your computer and use it in GitHub Desktop.
Ubuntu 16.04 arm64 Port QEMU Configuration

Setting up a Ubuntu 16.04 arm64 VM

This is mainly a notes dump and should be used for reference. This guide assumes:

  • Ubuntu 16.04 hypervisor/host with bridge networking
  • Knowledge of qemu
  • Knowledge of debootstrap

Install required packages

sudo apt-get install debootstrap qemu-utils qemu qemu-user-static flex bison

Install build deps for qemu (apt-src must be enabled in sources.list)

sudo apt-get build-dep qemu

Download the latest qemu source and build for a target of aarch64

git clone git://git.qemu.org/qemu.git qemu.git
cd qemu.git
./configure --target-list=aarch64-softmmu --enable-fdt --enable-vhost-net --enable-kvm
make -j4
sudo make install

Binary installs to

/usr/local/bin/qemu-system-aarch64

Create a 10GB qcow2 image that the VM will use as /

qemu-img create -f qcow2 /srv/chroots/trusty.qcow2 10G

Mount qcow as nbd device so we can use deboostrap on it and as a chroot later

modprobe -av nbd
qemu-nbd -c /dev/nbd0 /srv/chroots/xenial.qcow2

Create partition on ndb0 with cmd 'n' and set the type to linux. Optionally you can also setup a swap partition.

fdisk /dev/nbd0

Create an ext4 filesystem on new partition

mkfs.ext4 /dev/nbd0p1

Mount partition on /mnt

mount -t ext4 /dev/nbd0p1 /mnt

Run first-stage debootstrap for arm64

debootstrap --arch=arm64 --keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg --verbose --foreign xenial /mnt/

Copy arm64 qemu binary into chroot (qemu-aarch64-static was installed by qemu-user-static package)

cp /usr/bin/qemu-aarch64-static /mnt/usr/bin/

Go into chroot

chroot /mnt/ /bin/bash

Run second stage of debootstrap while in chroot

/debootstrap/debootstrap --second-stage

Add xenial arm64 ports to sources.list to install kernel in chroot

deb http://ports.ubuntu.com/ubuntu-ports/ xenial main universe multiverse restricted
deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main universe multiverse restricted
deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main universe multiverse restricted
deb http://ports.ubuntu.com/ubuntu-ports/ xenial-proposed main universe multiverse restricted

deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main universe multiverse restricted
deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main universe multiverse restricted
deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main universe multiverse restricted
deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-proposed main universe multiverse restricted

update apt sources

apt-get update

Install kernel and headers

  • Ubuntu

    apt-get install linux-generic linux-headers-generic
    

Exit chroot

Copy linux kernel and initrd from chroot to /srv/chroots/ on hypervisor

cp /mnt/boot/vmlinux* /srv/chroots/
cp /mnt/boot/initrd* /srv/chroots/

Umount chroot

umount /mnt

Start up the VM in ro mode first without an initrd so we can get to a rescue shell to finish configuration

/usr/local/bin/qemu-system-aarch64 -cpu cortex-a57 -machine type=virt -nographic -smp 1 -m 8192 -kernel /srv/chroots/vmlinuz-3.13.0-34-generic -drive file=/srv/chroots/trusty.qcow2,if=none,id=blk -device virtio-blk-device,drive=blk -device virtio-net-device,netdev=net0,mac=00:00:00:00:00:00 -netdev tap,id=net0 --append "root=/dev/vda1 ro console=ttyAMA0 --"

The boot will halt with an error about not being about to mount filesystems, choose continue to drop to a rescue shell and

remount / as rw
mount -o remount,rw /

Set hostname to something unique

hostname NEWHOSTNAME

Setup networking with DHCP

dhclient eth0

Setup a swap file so we don't run out of memory

dd if=/dev/zero of=/swapfile bs=1M count=1024
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

Install ssh and other packages

  • Ubuntu

    apt-get install ssh openssh-server perl netcat netcat6 bind9utils dnsutils libio-socket-ssl-perl libnet-ssleay-perl ldap-utils libtime-modules-perl lsb sysv-rc-conf dkms linux-headers-generic make bzip2 git curl build-essential
    

Test sshd starts and enable on boot

sudo service ssh start
update-rc.d ssh defaults

Change ssh config and enable login with root

Edit /etc/ssh/sshd_config
#PermitRootLogin prohibit-password
PermitRootLogin yes

Additional Configuration

  • add swap to /etc/fstab if desired
  • set root password and user if desired
  • set networking to static if desired

halt VM

halt -p

Start VM with 1GB of memory, bridge networking, initrd, and rw / which will fully boot (tap mode not working for arm64)

sudo qemu-system-aarch64 -cpu cortex-a57 -machine type=virt -nographic -smp 1 -m 1024 -kernel vmlinuz-4.4.0-104-generic -initrd initrd.img-4.4.0-104-generic -drive file=xenial.qcow2,if=none,id=blk -device virtio-blk-device,drive=blk -device virtio-net-device,netdev=net0,mac=00:00:00:00:00:00 -netdev user,id=net0,hostfwd=tcp::2222-:22 --append "root=/dev/vda1 rw console=ttyAMA0 --"

Log in via ssh as root or user and use system normally

on GUEST: dhclient eth0
on HOST: ssh -p 2222 root@localhost

autorun dhclient eth0

To configure your server to use DHCP for dynamic address assignment, add the dhcp method to the inet address family statement for the appropriate interface in the file /etc/network/interfaces. The example below assumes you are configuring your first Ethernet interface identified as eth0.
auto eth0    
iface eth0 inet dhcp    

References

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