3

Questions

  1. Can I convert the architecture of my Ubuntu 18.04 LTS server from armhf to arm64? I've already got it doing a "multiarch" thing, but I'm not sure that's the best solution. How should I proceed?
  2. How can I systematically go through all of the apt packages I have installed, and replace the armhf ones with arm64 where possible/available?

I have this disk image backed-up, so I don't mind solutions which may destroy the server - I can just reinstall the image if anything goes wrong.


Background

I would like to convert from armhf to arm64 on my Raspberry Pi 3 B. I have followed the instructions here, and produced a working 64-bit Ubuntu Bionic Server (which is cool). However, I notice that, while I can install and run arm64 (i.e. 64-bit) packages, most of the packages on my server are armhf (i.e. 32-bit). I would like to replace all (or as many as possible) of the armhf with arm64. The server currently lists arm64 as a "foreign" architecture, and armhf as its native architecture. Can I switch these round?

ubuntu@ubuntu:~$ dpkg --print-architecture
armhf
ubuntu@ubuntu:~$ dpkg --print-foreign-architectures
arm64

Is there some way to make the system switch these two around so that arm64 becomes the default, and armhf is used only where arm64 packages are not available?


Please note: I have no background in computer science, so please forgive my naivety. My thinking is that 64-bit computing will be on average quicker than 32-bit since any software trying to deal with large numbers or high precision can just use the 64-bit architecture of the ARMv8 chip on the Pi 3 B rather than extending the processing of the numbers to several clock cycles. I have seen discussions on Raspberry Pi forums where some conflicting opinions are aired regarding the pros and cons of converting to 64-bit. I would be very grateful if somebody could compile a simple list of pros and cons as I don't understand the complexities of these discussions.

Currently, I don't know if there will be a performance increase in moving to 64-bit, but what the heck - it's a Raspberry Pi - you're supposed to play around with them!


Methods

I followed the instructions at the Ubuntu Wiki page; doing this:

sudo dpkg --add-architecture arm64 
sudo apt update

I now find

dpkg --print-foreign-architectures

returns

arm64

To confirm the 64-bit nature of the server:

uname -a

which returns:

Linux ubuntu 4.15.0-1022-raspi2 #24-Ubuntu SMP PREEMPT Wed Aug 29 10:40:48 UTC 2018 aarch64 aarch64 aarch64 GNU/Linux

Additionally:

dpkg-architecture --list

returns

DEB_BUILD_ARCH=armhf
DEB_BUILD_ARCH_ABI=eabihf
DEB_BUILD_ARCH_BITS=32
DEB_BUILD_ARCH_CPU=arm
DEB_BUILD_ARCH_ENDIAN=little
DEB_BUILD_ARCH_LIBC=gnu
DEB_BUILD_ARCH_OS=linux
DEB_BUILD_GNU_CPU=arm
DEB_BUILD_GNU_SYSTEM=linux-gnueabihf
DEB_BUILD_GNU_TYPE=arm-linux-gnueabihf
DEB_BUILD_MULTIARCH=arm-linux-gnueabihf
DEB_HOST_ARCH=armhf
DEB_HOST_ARCH_ABI=eabihf
DEB_HOST_ARCH_BITS=32
DEB_HOST_ARCH_CPU=arm
DEB_HOST_ARCH_ENDIAN=little
DEB_HOST_ARCH_LIBC=gnu
DEB_HOST_ARCH_OS=linux
DEB_HOST_GNU_CPU=arm
DEB_HOST_GNU_SYSTEM=linux-gnueabihf
DEB_HOST_GNU_TYPE=arm-linux-gnueabihf
DEB_HOST_MULTIARCH=arm-linux-gnueabihf
DEB_TARGET_ARCH=armhf
DEB_TARGET_ARCH_ABI=eabihf
DEB_TARGET_ARCH_BITS=32
DEB_TARGET_ARCH_CPU=arm
DEB_TARGET_ARCH_ENDIAN=little
DEB_TARGET_ARCH_LIBC=gnu
DEB_TARGET_ARCH_OS=linux
DEB_TARGET_GNU_CPU=arm
DEB_TARGET_GNU_SYSTEM=linux-gnueabihf
DEB_TARGET_GNU_TYPE=arm-linux-gnueabihf
DEB_TARGET_MULTIARCH=arm-linux-gnueabihf

This seems to suggest that whenever I install a package using apt, the system will go for an armhf package by default.

I would like to make arm64 the non-foreign architecture, and armhf my foreign architecture on this server.

2
  • 2
    You can't convert between architecture versions safely. Backup data you want to keep, then install the arm64 variant, then restore your data.
    – Thomas Ward
    Sep 19, 2018 at 14:34
  • Oh is that all I've done! Okay great. I shall go back to the Ubuntu Server ARM images page, and be sure to download the arm64 version. Thank you!
    – Harley Day
    Sep 19, 2018 at 14:37

1 Answer 1

2

Can I convert the architecture of my Ubuntu 18.04 LTS server from armhf to arm64? I've already got it doing a "multiarch" thing, but I'm not sure that's the best solution. How should I proceed?

Yes, you can, but here there be dragons - the initial conversion process will have to be largely manual, and even afterwards you'll have to initially pay very close attention to what your package manager intends to do. I've done multiple conversions - from i386 to amd64, from armel to armhf to arm64, and the other way around - from amd64 to i386 and from arm64 to armhf to armel. Why? Because I can.

First thing to note - if you are cross-grading from less advanced architecture to more advanced (that is, i386->amd64 and armel->armhf->arm64) you need to first install the target architecture kernel and boot into it and only then cross-grade the rest of the packages. If you're cross-grading the other way around (I've done so on a system after I found out 64-bit packages leave too little free RAM) you need to first transition all of the packages to the less advanced architecture and only then transition kernel (if such is available in lesser architecture at all). Second thing to note - APT is not smart enough to cross-grade packages safely, it has a tendency to remove critical components if it believes some of the dependencies are broken. Until all of dpkg, apt, and aptitude (if used) and all of their dependencies are installed in the target architecture - the cross-grading will absolutely have to be done manually, though it should be possible to at least partially script it.

Now onto the process of cross-grading:

  1. make sure you have some way of booting the system and chroot'ing into it in case things go south, e.g. on Pinebook Pro that normally boots from eMMC it can be achieved by keeping around a microSD card with another OS, on x86 - just keep around a live CD/USB.
  2. add the target architecture to dpkg, e.g. dpkg --add-architecture arm64
  3. update APT sources, e.g. apt update
  4. install the kernel in target architecture, e.g. apt install linux-image-arm64:arm64, reboot into that new kernel
  5. open at least a couple of root terminals, especially if you don't have root password and use sudo: sudo -i. Can be quite useful to also install mc and keep it running in one of those root terminals - it can make some recovery tasks easier.
  6. use something like apt-rdepends to obtain full recursive list of all dependencies for the target architecture versions of dpkg, apt, and, optionally, aptitude, download all of those packages using apt download <package1> <package2> .... Do the same for sed, tar, coreutils, findutils - those are runtime dependencies for dpkg, and installing those manually will reduce the chances of getting broken system when moving onto automatic phase.
  7. Use dpkg -i <package_file> to install all the downloaded packages one by one, starting from the most core dependency and moving onto dependent packages - this essentially "upgrades" the old architecture packages with the new architecture packages, correctly removing old files and installing new ones for non-multiarch packages like dpkg and installing new in parallel with old for multiarch packages like libc6.
  8. Once you have new architecture version of apt installed you may run apt update and attempt apt -f install to install/cross-grade any missing dependencies for the target architecture, but be careful to make sure APT doesn't try to remove any packages related to package management or networking - without those the system can still be recovered, but the process is rather tedious. If you see APT proposing to remove any of those critical packages - fall back to apt-rdepends and installing missing dependencies manually.
  9. Once you had at least one successful run of apt -f install you should run apt full-upgrade at least once - it will likely pick up more packages in target architecture that still need to be installed.
  10. ...
  11. PROFIT!!!

How can I systematically go through all of the apt packages I have installed, and replace the armhf ones with arm64 where possible/available?

The way I do it is using aptitude and piping output through grep searching for old architecture, e.g. aptitude search ~i | grep :armhf. For all the found packages - first, attempt to install the new arch version, e.g., if the above command lists firefox:armhf then just do apt install firefox and that should replace armhf version with arm64. Eventually only multi-arch packages will be left installed, at that point it should be possible to just purge all the packages returned by aptitude search ~i | grep :armhf. Once all old architecture packages are purged you should be able to run dpkg --remove-architecture armhf.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.