Installing Ubuntu Mantic on arm64 PINE A64-LTS

Ubuntu provides all that it is needed to run on many ARM development boards but does not have ready made images for most of them.

The PINE A64-LTS uses an Allwinner A64 SoC and comes with 2 GiB of RAM. This is how installed Ubuntu Mantic on it.


As boot firmware the board uses U-Boot which is available as package u-boot-sunix. On an arm64 system it can easily be installed via

 sudo apt-get install u-boot-sunxi

On other architectures I could find the package file in Launchpad on page To download, decompress, and list included files:

dpkg -x u-boot-sunxi_2023.07+dfsg-1ubuntu1_arm64.deb foo
find foo

I had a look at the README:

zcat /usr/share/doc/u-boot-sunxi/README.sunxi64.gz | less

U-Boot is installed only 8 KiB after the start of SD card. A default sized GPT partition table needs 17 KiB (sic!).

Downloading the Ubuntu image

I downloaded an image from the daily build webpage and decompressed it:

$ wget
$ xz -d mantic-preinstalled-server-arm64.img.xz

Resizing the GPT partition table

Inspecting the partition table with gdisk confirmed the conflict with U-Boot:

$ /usr/sbin/gdisk mantic-preinstalled-server-arm64.img
 GPT fdisk (gdisk) version 1.0.9

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): p
Disk mantic-preinstalled-server-arm64.img: 7340032 sectors, 3.5 GiB
Sector size (logical): 512 bytes
Disk identifier (GUID): DD36A78B-3A02-415D-BF5D-FF6C31E02D2C
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 7339998
Partitions will be aligned on 2048-sector boundaries
Total free space is 4061 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1          215040         7339998   3.4 GiB     8300  
  14          206848          215039   4.0 MiB     8300  CIDATA
  15            2048          204800   99.0 MiB    EF00  

Fortunately via the expert menu the GPT partition table can be resized to 56 entries which uses only 8 KiB:

Command (? for help): x

Expert command (? for help): s
Current partition table size is 128.
Enter new size (15 up, default 128): 56
Caution: The partition table size should officially be 16KB or larger,
which works out to 128 entries. In practice, smaller tables seem to
work with most OSes, but this practice is risky. I'm proceeding with
the resize, but you may want to reconsider this action and undo it.

Expert command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to mantic-preinstalled-server-arm64.img.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.

Flashing to SD card

Now things were ready for copying to the SD card. (As writing to the wrong drive cannot be undone I have replaced the actual drive by /dev/sdX in the listing below.)

$ sudo dd if=mantic-preinstalled-server-arm64.img of=/dev/sdX bs=1M conv=fsync
$ sudo dd conv=fsync,notrunc \
if=/usr/lib/u-boot/pine64-lts/sunxi-spl.bin \
of=/dev/sdX bs=8k seek=1
$ sudo dd conv=fsync,notrunc \
if=/usr/lib/u-boot/pine64-lts/ \
of=/dev/sdX bs=8k seek=5

Adjusting the image

The image might not boot because the device-tree provided by U-Boot does not match the Linux kernel. So I mounted the image and entered it via chroot:

sudo mount /dev/sdX1 /mnt
sudo mount /dev/sdX15 /mnt/boot/efi
sudo mount dev -t devtmpfs /mnt/dev
sudo mount devpts -t devpts /mnt/dev/pts
sudo mount proc -t proc /mnt/proc
sudo mount sys -t sysfs /mnt/sys
sudo chroot /mnt

To let U-Boot find the right device-tree it must be in the dts/ directory of the EFI system partition:

# mkdir /boot/efi/dtb
# cp -R /lib/firmware/6.3.0-7-generic/device-tree/* /boot/efi/dtb/

U-Boot internally uses a variable fdtfile to identify the right device-tree file.

I don’t have a monitor attached and want to see the GRUB menu when booting and watch the kernel log on my console. To override the settings in /etc/default/grub and /etc/default/grub.d/50-cloudimg-settings.cfg I create a new configuration file. Due to its name it will be included last.

# cat > /etc/default/grub.d/99-my.cfg << EOF
GRUB_CMDLINE_LINUX_DEFAULT="efi=debug earlyprintk"
# update-grub

Time to exit the chroot and unmount the SD-card:

# exit
$ sudo umount /mnt/sys
$ sudo umount /mnt/proc
$ sudo umount /mnt/dev/pts
$ sudo umount /mnt/dev
$ sudo umount /mnt/boot/efi
$ sudo umount /mnt

First boot

When booting the first time cloud-init is setting up the user ubuntu with password ubuntu. So I waited with logging in until I saw this line showing that cloud-init had finished its work:

[  109.955627] cloud-init[1383]: Cloud-init v. 23.3.1-0ubuntu1 finished at Sun, 10 Sep 2023 10:36:43 +0000. Datasource DataSourceNoCloud [seed=/var/lib/cloud/seed/nocloud-net][dsmode=net].  Up 109.93 seconds

To add a device-tree command to grub.cfg I copied the current device-tree with flash-kernel and ran grub-update:

$ sudo flash-kernel $(uname -r)
$ sudo grub-update

The same commands will run automatically every time the kernel is updated.


  • Ubuntu Mantic runs fine on the PINE A64-LTS
  • Extra care is needed to check if the U-Boot location on disk conflicts with the partitioning scheme.
  • Ubuntu images lack copies of the device-trees pre-installed in /boot/efi/dts needed for U-Boot.
  • While well tuned for a workstation or server the pre-configured GRUB setup may require adjustment for users relying on a serial console.
1 Like