Fast upgrade Raspberry Pi3 from Source


Active Member

Reaction score: 6
Messages: 134

I want to share with you a little experience of mine.
Maybe it will help.
I have Raspberry Pi3 with FreeBSD 12.1-RELEASE installed.
Binary upgrade freebsd-update(8) is not supported for the ARM architecture. And you have to recompile the Kernel and the World manually. But on a small Raspberry, it can take more than one day. Therefore, you need to use cross-compilation and build the kernel and the world on an i386/amd64 computer.
You can read about cross-build here: CrossBuild
But for Raspberry Pi3 arm64/aarch64 you need add some extra parameters.

I have FreeBSD 12.2-RELEASE amd64 installed on my working Lenovo T530 with Intel core i5 CPU.
On this computer I will do cross-compilation and build the Kernel for arm64/aarch64 architecture.

1. Source code​

First, we need to download or update our source code on i386/amd64 machine.
I want upgrade my Raspberry Pi3 to 12.2-RELEASE, for this I have to download a new one source code.

# cd /use/scr
# svnlite checkout .

2. Building​

After updating the source code when we can start to build.
Our reference will be on Handbook
But we need to specify the processor architecture and additional parameters and CrossBuild will help us.
-j4 this is for Multi-core CPU, 4 this is number of my CPU cores on host system.
TARGET_ARCH=aarch64 specify the architecture of Raspberry Pi3.

UBLDR_LOADADDR=0x2000000 "This is a tedious little detail currently required for ARM systems. The loader(8) flavor used on most ARM systems is 'ubldr' (U-Boot loader), and it currently has to be linked at a fixed address." said in the CrossBuild. And "0x2000000" I found in Internet.
acheron said that UBLDR_LOADADDR does not need to be specified, we boot using EFI on aarch64 (and armv6/7 with recent FreeBSD version)
I compiled with this parameter and it did not affect a new system.

KERNCONF=GENERIC I saw that my original FreeBSD 12.1-RELEASE on Raspberry Pi3 system was built with the GENERIC Kernel. Therefore, you can set this parameter. Although the GENERIC configuration is used by default.

# make buildworld -j4 TARGET_ARCH=aarch64 UBLDR_LOADADDR=0x2000000 KERNCONF=GENERIC
# make buildkernel -j4 TARGET_ARCH=aarch64 KERNCONF=GENERIC

Now you need some patience and free disk space in /usr/obj.
The build directory can be overridden with MAKEOBJDIRPREFIX variable.
On my system it took about 2-2.5 hours.

3. BackUp​

Before upgrading the system on Raspberry Pi3, I made a backup of the entire SD-Card.
I turned off the Raspberry Pi3 and connected the SD-card to my host machine (Lenovo T530) on which I am doing the compilation and with the help of dd I made a copy of the SD card.

# dd if=/dev/da0 of=/media/backup/rpi3.dd bs=1M status=progress

4. Install​

When the backup is done, do not remove the card.
Mount SD card for example in /mnt

# mount /dev/da0s2a /mnt

We will install the Kernel and the World directly on the SD card.
I think this is the fastest way.

First install the kernel.
Never forget to specify variables TARGET_ARCH and KERNCONF.
And we will indicate where we will want install it with DESTDIR=/mnt.

# make installkernel TARGET_ARCH=aarch64 KERNCONF=GENERIC DESTDIR=/mnt

Merge configuration files with mergemaster.

# mergemaster -p -A aarch64 -D /mnt

Now we can start installing the World and after merge configuration files.

# make installworld -j 4 TARGET_ARCH=aarch64 DESTDIR=/mnt
# mergemaster -iF -A aarch64 -D /mnt

The installation process is pretty quick.
And everything is ready!

5. Delet obsolete files​

Delet obsolete files, directories and libraries.

# make delete-old TARGET_ARCH=aarch64 BATCH_DELETE_OLD_FILES=yes DESTDIR=/mnt
# make delete-old-libs TARGET_ARCH=aarch64 BATCH_DELETE_OLD_FILES=yes DESTDIR=/mnt

6. Ready to use​

Unmount the SD card. Insert it back into Raspberry Pi 3 and boot the new system.

# umount /mnt


Aspiring Daemon

Reaction score: 323
Messages: 778

ublr is not used on aarch64 (and also on recent armv6/7 version if I'm not mistaken)


Active Member

Reaction score: 6
Messages: 134

ublr is not used on aarch64 (and also on recent armv6/7 version if I'm not mistaken)
You want to say that UBLDR_LOADADDR = 0x2000000 does not need to be specified?