Skip to content

Instantly share code, notes, and snippets.

@brianredbeard
Forked from george-hawkins/arm64.md
Created September 26, 2018 00:58
Show Gist options
  • Select an option

  • Save brianredbeard/36f5bc52f8e8602b8ac0fcbd8bacc4e3 to your computer and use it in GitHub Desktop.

Select an option

Save brianredbeard/36f5bc52f8e8602b8ac0fcbd8bacc4e3 to your computer and use it in GitHub Desktop.

Revisions

  1. @george-hawkins george-hawkins revised this gist Jan 22, 2017. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions ubuntu-cloud-image-with-qemu.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,6 @@
    QEMU x86_64 cloud server virtualization
    =======================================

    Get a cloud image from:

    <https://cloud-images.ubuntu.com/releases/>
  2. @george-hawkins george-hawkins revised this gist Jan 22, 2017. 2 changed files with 9 additions and 7 deletions.
    13 changes: 7 additions & 6 deletions arm64.md
    Original file line number Diff line number Diff line change
    @@ -28,6 +28,7 @@ users:
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash
    EOF
    ```

    Important: the `#cloud-config` line above is not a comment and things will fail silently without it.
    @@ -42,7 +43,7 @@ Backup your image:

    $ cp ubuntu-16.04-server-cloudimg-arm64-disk1.img ubuntu-16.04-server-cloudimg-arm64-disk1.img.orig

    The QEMU launch command is somewhat more complex that for e.g. a fully virtualized, rather than emulated, setup with an x86_64 guest running on an x86_64 host.
    The QEMU launch command is somewhat more complex than for e.g. a fully virtualized, rather than emulated, setup with an x86_64 guest running on an x86_64 host.

    Here is the command first:

    @@ -63,7 +64,7 @@ $ qemu-system-aarch64 \
    -redir tcp:2222::22
    ```

    You'll have to change `ubuntu-16.04-server-cloudimg-arm64-uefi1.img` is you downloaded a later image with a different name.
    You'll have to change `ubuntu-16.04-server-cloudimg-arm64-uefi1.img` if you downloaded a later image with a different name.

    Now let's look at the arguments that configure our system:

    @@ -72,7 +73,7 @@ Now let's look at the arguments that configure our system:
    * `-M virt` - emulate a generic QEMU ARM machine.
    * `-cpu cortex-a57` - the CPU model to emulate.
    * `-bios QEMU_EFI.fd` - the BIOS firmware file to use.
    * `-nographic` - output goes to terminal (rather than opening a graphics capable window).
    * `-nographic` - output goes to the terminal (rather than opening a graphics capable window).
    * `-device virtio-blk-device,drive=image` - create a Virtio block device called "image".
    * `-drive if=none,id=image,file=ubuntu-16.04-server-cloudimg-arm64-uefi1.img` - create a drive using the "image" device and our cloud server disk image.
    * `-device virtio-blk-device,drive=cloud` - create another Virtio block device called "cloud".
    @@ -112,19 +113,19 @@ EFI stub: Exiting boot services and installing virtual address map...
    [ 0.000000] Initializing cgroup subsys cpuset
    ```

    The initial error can be ignored - we specifically set `-nographic`.
    The initial error, about "no suitable video mode found", can be ignored - we specifically set `-nographic`.

    Eventually a login prompt will appear - which cannot be used as in our cloud-config file we only specified key based ssh login.

    Depending on how fast various jobs, kicked off during the boot process, run further output will appear after the login prompt appears.
    Depending on how fast various jobs (kicked off during the boot process) run further output will appear after the login prompt appears.

    The first time you launch a given system you should see output confirming that the ssh key specified up above has been installed.

    And eventually you should see something like:

    [ 220.784509] cloud-init[1358]: Cloud-init v. 0.7.8 finished at ...

    Now in another terminal you can login to newly launched cloud server:
    Now in another terminal you can log in to the newly launched cloud server:

    $ ssh -p 2222 ghawkins@localhost

    3 changes: 2 additions & 1 deletion ubuntu-cloud-image-with-qemu.md
    Original file line number Diff line number Diff line change
    @@ -20,6 +20,7 @@ users:
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash
    EOF
    $ cloud-localds cloud.img cloud.txt
    ```

    @@ -51,7 +52,7 @@ The command line arguments:
    * `-enable-kvm` - full virtualization (rather than emulation).
    * `-smp 2` - two (virtual) processors (as we'll confirm later).
    * `-m 1024` - 1024MB of system memory.
    * `-nographic` - output goes to terminal (rather than opening a graphics capable window).
    * `-nographic` - output goes to the terminal (rather than opening a graphics capable window).
    * `-hda ubuntu-16.10-server-cloudimg-amd64.img` - use our Ubuntu cloud image as the primary drive.
    * `-hdb cloud.img` - use the image we created from `cloud.txt` as the secondary drive.
    * `-redir tcp:2222::22` - map port 2222 on the host to port 22 (the standard ssh port) on the guest.
  3. @george-hawkins george-hawkins revised this gist Jan 22, 2017. No changes.
  4. @george-hawkins george-hawkins revised this gist Jan 22, 2017. 1 changed file with 180 additions and 0 deletions.
    180 changes: 180 additions & 0 deletions arm64.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,180 @@
    QEMU arm64 cloud server emulation
    =================================

    This is basically a rehash of an original [post on CNXSoft](http://www.cnx-software.com/2016/05/10/how-to-run-ubuntu-16-04-aarch64-64-bit-arm-cloud-images-on-your-intelamd-linux-computer/) - all credit (particularly for the Virtio device arguments used below) belongs to the author of that piece.

    Download the latest `uefi1.img` image. E.g. [`ubuntu-16.04-server-cloudimg-arm64-uefi1.img`](https://cloud-images.ubuntu.com/releases/16.04/release/ubuntu-16.04-server-cloudimg-arm64-uefi1.img) from <https://cloud-images.ubuntu.com/releases/16.04/release/>

    Download the UEFI firmware image `QEMU_EFI.fd` from <https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/>

    Determine your current username and get your current ssh public key:

    ```text
    $ whoami
    ghawkins
    $ cat ~/.ssh/id_rsa.pub
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...
    ```

    Use these values to create a `cloud.txt` file replacing the username, here shown as `ghawkins`, and the `ssh-rsa` value with the values appropriate for you:

    ```text
    $ cat > cloud.txt << EOF
    #cloud-config
    users:
    - name: ghawkins
    ssh-authorized-keys:
    - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash
    ```

    Important: the `#cloud-config` line above is not a comment and things will fail silently without it.

    Cread a cloud-config disk image:

    $ cloud-localds --disk-format qcow2 cloud.img cloud.txt

    Note: by default `cloud-localds` creates a raw image and QEMU now complains at having to guess about such an image so use `--disk-format qcow2` to specify a well defined format that QEMU can easily consume.

    Backup your image:

    $ cp ubuntu-16.04-server-cloudimg-arm64-disk1.img ubuntu-16.04-server-cloudimg-arm64-disk1.img.orig

    The QEMU launch command is somewhat more complex that for e.g. a fully virtualized, rather than emulated, setup with an x86_64 guest running on an x86_64 host.

    Here is the command first:

    ```text
    $ qemu-system-aarch64 \
    -smp 2 \
    -m 1024 \
    -M virt \
    -cpu cortex-a57 \
    -bios QEMU_EFI.fd \
    -nographic \
    -device virtio-blk-device,drive=image \
    -drive if=none,id=image,file=ubuntu-16.04-server-cloudimg-arm64-uefi1.img \
    -device virtio-blk-device,drive=cloud \
    -drive if=none,id=cloud,file=cloud.img \
    -device virtio-net-device,netdev=user0 \
    -netdev user,id=user0 \
    -redir tcp:2222::22
    ```

    You'll have to change `ubuntu-16.04-server-cloudimg-arm64-uefi1.img` is you downloaded a later image with a different name.

    Now let's look at the arguments that configure our system:

    * `-smp 2` - 2 (virtual) cores.
    * `-m 1024` - 1024MB of system memory.
    * `-M virt` - emulate a generic QEMU ARM machine.
    * `-cpu cortex-a57` - the CPU model to emulate.
    * `-bios QEMU_EFI.fd` - the BIOS firmware file to use.
    * `-nographic` - output goes to terminal (rather than opening a graphics capable window).
    * `-device virtio-blk-device,drive=image` - create a Virtio block device called "image".
    * `-drive if=none,id=image,file=ubuntu-16.04-server-cloudimg-arm64-uefi1.img` - create a drive using the "image" device and our cloud server disk image.
    * `-device virtio-blk-device,drive=cloud` - create another Virtio block device called "cloud".
    * `-drive if=none,id=cloud,file=cloud.img` - create a drive using the "cloud" device and our cloud-config disk image.
    * `-device virtio-net-device,netdev=user0` - create a Virtio network device called "user0"
    * `-netdev user,id=user0` - create a user mode network stack using device "user0"
    * `-redir tcp:2222::22` - map port 2222 on the host to port 22 (the standard ssh port) on the guest.

    Here we create a generic QEMU ARM machine. You can see a complete list of possible ARM machines like so:

    ```text
    $ qemu-system-aarch64 -M help
    akita Sharp SL-C1000 (Akita) PDA (PXA270)
    ...
    z2 Zipit Z2 (PXA27x)
    ```

    This list seems to include all ARM machines, not just 64-bit ones. The latest versions of QEMU (but not the one that currently comes with Ubuntu 16.04 LTS) include the well know Raspberry Pi 2 (but not the 3).

    For a given machine you can then see the supported processors:

    ```text
    $ qemu-system-aarch64 -M virt -cpu help
    arm1026
    ...
    ti925t
    ```

    Once you run the command up above to launch an emulated ARM64 machine it will take a few minutes to boot and will output something like the following:

    ```text
    error: no suitable video mode found.
    EFI stub: Booting Linux Kernel...
    EFI stub: Using DTB from configuration table
    EFI stub: Exiting boot services and installing virtual address map...
    [ 0.000000] Booting Linux on physical CPU 0x0
    [ 0.000000] Initializing cgroup subsys cpuset
    ```

    The initial error can be ignored - we specifically set `-nographic`.

    Eventually a login prompt will appear - which cannot be used as in our cloud-config file we only specified key based ssh login.

    Depending on how fast various jobs, kicked off during the boot process, run further output will appear after the login prompt appears.

    The first time you launch a given system you should see output confirming that the ssh key specified up above has been installed.

    And eventually you should see something like:

    [ 220.784509] cloud-init[1358]: Cloud-init v. 0.7.8 finished at ...

    Now in another terminal you can login to newly launched cloud server:

    $ ssh -p 2222 ghawkins@localhost

    If all goes well you'll log straight in without any username or password.

    If you've started previous QEMU images in a similar manner then ssh may issue a dire warning like so (and refuse to login):

    ```text
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
    ```

    To resolve this and remove previous details:

    $ ssh-keygen -f ~/.ssh/known_hosts -R '[localhost]:2222'

    When logged into the cloud server you can...

    * Confirm that it's an `aarch64` system:

    ```text
    $ uname -a
    Linux ubuntu 4.4.0-59-generic #80-Ubuntu SMP Fri Jan 6 17:37:14 UTC 2017 aarch64 aarch64 aarch64 GNU/Linux
    ```

    * Has two cores:

    ```text
    $ cat /proc/cpuinfo
    processor : 0
    ...
    processor : 1
    ...
    ```

    * Shut it down:

    ```text
    $ sudo shutdown now
    ```

    In the original terminal (where you launched `qemu-system-aarch64`) you can follow the shutdown process.

    Note: when running `sudo shutdown now` the shutdown succeeds but the following error appears:

    sudo: unable to resolve host ubuntu

    You'll see this anytime you run `sudo` - to resolve it (as per [Ask Ubuntu](http://askubuntu.com/q/59458)) just edit `/etc/hosts` and add `ubuntu` at the end of the existing line for the address `127.0.0.1` so you end up with something like:

    127.0.0.1 localhost ubuntu
  5. @george-hawkins george-hawkins revised this gist Jan 22, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ubuntu-cloud-image-with-qemu.md
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@ users:
    $ cloud-localds cloud.img cloud.txt
    ```

    Copy the line contained in `id_rsa.pub` into the `ssh-authorized-keys` section.
    Copy the line contained in `id_rsa.pub` into the `ssh-authorized-keys` section and replace the username specified by `name` with your username.

    **Important:** I thought `#cloud-config` was a comment and left it out - but without it no error is reported but you cannot login later.

  6. @george-hawkins george-hawkins revised this gist Jan 22, 2017. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion ubuntu-cloud-image-with-qemu.md
    Original file line number Diff line number Diff line change
    @@ -4,9 +4,11 @@ Get a cloud image from:

    E.g. <https://cloud-images.ubuntu.com/releases/16.10/release/ubuntu-16.10-server-cloudimg-amd64.img>

    Create the cloud-config, which defines who can login etc., and create a disk image from it:
    Create a cloud-config called `cloud.txt`, which defines who can login etc. to the virtual cloud server, and create a disk image from it. For this you need your login name on your current system, along with the public part of your current ssh key:

    ```text
    $ whoami
    ghawkins
    $ cat ~/.ssh/id_rsa.pub
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...
    $ cat > cloud.txt << EOF
  7. @george-hawkins george-hawkins revised this gist Nov 25, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ubuntu-cloud-image-with-qemu.md
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@ Get a cloud image from:

    E.g. <https://cloud-images.ubuntu.com/releases/16.10/release/ubuntu-16.10-server-cloudimg-amd64.img>

    Create the cloud-config, that defines who can login etc., and create a disk image from it:
    Create the cloud-config, which defines who can login etc., and create a disk image from it:

    ```text
    $ cat ~/.ssh/id_rsa.pub
  8. @george-hawkins george-hawkins revised this gist Nov 25, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ubuntu-cloud-image-with-qemu.md
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@ Get a cloud image from:

    E.g. <https://cloud-images.ubuntu.com/releases/16.10/release/ubuntu-16.10-server-cloudimg-amd64.img>

    Create the cloud-config, that defines who can login, and create a disk image from it:
    Create the cloud-config, that defines who can login etc., and create a disk image from it:

    ```text
    $ cat ~/.ssh/id_rsa.pub
  9. @george-hawkins george-hawkins revised this gist Nov 25, 2016. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions ubuntu-cloud-image-with-qemu.md
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@ Get a cloud image from:

    E.g. <https://cloud-images.ubuntu.com/releases/16.10/release/ubuntu-16.10-server-cloudimg-amd64.img>

    Create the cloud image that defines who can login:
    Create the cloud-config, that defines who can login, and create a disk image from it:

    ```text
    $ cat ~/.ssh/id_rsa.pub
    @@ -29,7 +29,7 @@ Backup your image:

    $ cp ubuntu-16.10-server-cloudimg-amd64.img ubuntu-16.10-server-cloudimg-amd64.img.orig

    Note: this is a compressed qcow2 image - while it's about 320MB the guest, when running, sees it as 2GB (as we'll confirm later).
    Note: this is a compressed qcow2 image - while it's about 320MB the running guest will see it as 2GB (as we'll confirm later).

    Now start the cloud guest:

    @@ -50,7 +50,7 @@ The command line arguments:
    * `-smp 2` - two (virtual) processors (as we'll confirm later).
    * `-m 1024` - 1024MB of system memory.
    * `-nographic` - output goes to terminal (rather than opening a graphics capable window).
    * `-hda ubuntu-16.10-server-cloudimg-amd64.img` - use our image as the primary drive.
    * `-hda ubuntu-16.10-server-cloudimg-amd64.img` - use our Ubuntu cloud image as the primary drive.
    * `-hdb cloud.img` - use the image we created from `cloud.txt` as the secondary drive.
    * `-redir tcp:2222::22` - map port 2222 on the host to port 22 (the standard ssh port) on the guest.

    @@ -88,13 +88,13 @@ So above using `df -h` we can see that the disk appears to be 2GB and with `cat

    TODO: see how changing the number of virtual CPUs affects the performance of the guest.

    If you redo everything from scratch again with a copy of the original disk image then the guest will generate a new key to identify itself which will cause ssh to refuse to allow you to connect due to the change in key. To remove the old key from `known_hosts` do:
    If you redo everything from scratch again with a copy of the original disk image then the guest will generate a new key to identify itself which will cause ssh to refuse to allow you to reconnect due to the change in key. To remove the old key from `known_hosts` do:

    $ ssh-keygen -f ~/.ssh/known_hosts -R '[localhost]:2222'

    Working out how to get this far was down to:

    * <http://www.cnx-software.com/2016/05/10/how-to-run-ubuntu-16-04-aarch64-64-bit-arm-cloud-images-on-your-intelamd-linux-computer/> - yes even though it's about running an emulated ARM guest it was helpful in working out how to get everything going.
    * <http://www.cnx-software.com/2016/05/10/how-to-run-ubuntu-16-04-aarch64-64-bit-arm-cloud-images-on-your-intelamd-linux-computer/> - yes, even though it's about running an emulated ARM guest it was helpful in working out how to get everything going.
    * <https://www.digitalocean.com/community/tutorials/how-to-use-cloud-config-for-your-initial-server-setup> - goes into the cloud config in more detail (and convinced me to finally add `#cloud-config` at the start of the file).

    The Ubuntu cloud images page wasn't as helpful as it should be:
  10. @george-hawkins george-hawkins created this gist Nov 25, 2016.
    104 changes: 104 additions & 0 deletions ubuntu-cloud-image-with-qemu.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,104 @@
    Get a cloud image from:

    <https://cloud-images.ubuntu.com/releases/>

    E.g. <https://cloud-images.ubuntu.com/releases/16.10/release/ubuntu-16.10-server-cloudimg-amd64.img>

    Create the cloud image that defines who can login:

    ```text
    $ cat ~/.ssh/id_rsa.pub
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...
    $ cat > cloud.txt << EOF
    #cloud-config
    users:
    - name: ghawkins
    ssh-authorized-keys:
    - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash
    $ cloud-localds cloud.img cloud.txt
    ```

    Copy the line contained in `id_rsa.pub` into the `ssh-authorized-keys` section.

    **Important:** I thought `#cloud-config` was a comment and left it out - but without it no error is reported but you cannot login later.

    Backup your image:

    $ cp ubuntu-16.10-server-cloudimg-amd64.img ubuntu-16.10-server-cloudimg-amd64.img.orig

    Note: this is a compressed qcow2 image - while it's about 320MB the guest, when running, sees it as 2GB (as we'll confirm later).

    Now start the cloud guest:

    ```text
    $ qemu-system-x86_64 \
    -enable-kvm \
    -smp 2 \
    -m 1024 \
    -nographic \
    -hda ubuntu-16.10-server-cloudimg-amd64.img \
    -hdb cloud.img \
    -redir tcp:2222::22
    ```

    The command line arguments:

    * `-enable-kvm` - full virtualization (rather than emulation).
    * `-smp 2` - two (virtual) processors (as we'll confirm later).
    * `-m 1024` - 1024MB of system memory.
    * `-nographic` - output goes to terminal (rather than opening a graphics capable window).
    * `-hda ubuntu-16.10-server-cloudimg-amd64.img` - use our image as the primary drive.
    * `-hdb cloud.img` - use the image we created from `cloud.txt` as the secondary drive.
    * `-redir tcp:2222::22` - map port 2222 on the host to port 22 (the standard ssh port) on the guest.

    Once booted you eventually get to the console getty login prompt. No one can login here - so you need to switch to another terminal tab.

    Now let's logon to the guest using the redirected port and check out a few things and then shut down the guest:

    ```text
    $ ssh -p 2222 ghawkins@localhost
    Welcome to Ubuntu 16.10 (GNU/Linux 4.8.0-26-generic x86_64)
    ...
    $ df -h
    Filesystem Size Used Avail Use% Mounted on
    udev 491M 0 491M 0% /dev
    tmpfs 100M 3.2M 97M 4% /run
    /dev/sda1 2.0G 979M 1016M 50% /
    tmpfs 496M 0 496M 0% /dev/shm
    tmpfs 5.0M 0 5.0M 0% /run/lock
    tmpfs 496M 0 496M 0% /sys/fs/cgroup
    /dev/sda15 105M 4.8M 100M 5% /boot/efi
    tmpfs 100M 0 100M 0% /run/user/1000
    $ cat /proc/cpuinfo
    processor : 0
    vendor_id : GenuineIntel
    ...
    processor : 1
    vendor_id : GenuineIntel
    $ sudo shutdown now
    Connection to localhost closed by remote host.
    ```

    So above using `df -h` we can see that the disk appears to be 2GB and with `cat /proc/cpuinfo` we can see that we appear to have two processors. Finally using `shutdown` we can get back to the command prompt in the terminal where the guest was started.

    TODO: see how changing the number of virtual CPUs affects the performance of the guest.

    If you redo everything from scratch again with a copy of the original disk image then the guest will generate a new key to identify itself which will cause ssh to refuse to allow you to connect due to the change in key. To remove the old key from `known_hosts` do:

    $ ssh-keygen -f ~/.ssh/known_hosts -R '[localhost]:2222'

    Working out how to get this far was down to:

    * <http://www.cnx-software.com/2016/05/10/how-to-run-ubuntu-16-04-aarch64-64-bit-arm-cloud-images-on-your-intelamd-linux-computer/> - yes even though it's about running an emulated ARM guest it was helpful in working out how to get everything going.
    * <https://www.digitalocean.com/community/tutorials/how-to-use-cloud-config-for-your-initial-server-setup> - goes into the cloud config in more detail (and convinced me to finally add `#cloud-config` at the start of the file).

    The Ubuntu cloud images page wasn't as helpful as it should be:

    * <https://help.ubuntu.com/community/UEC/Images>

    But it does cover uncompressing the qcow2 disk image and increasing its size (2GB isn't much) and fancier stuff like creating a delta image to keep your initial disk image in a pristine condition.