• 64 bit Linux on Raspberry Pi 3B+

  • For a project I wanted to investigate 64 bit Linux on an A53 core, so I thought that a Raspberry Pi3 would fit the bill. Having unwrapped a Pi 3B+ I started as usual to just get a standard image built, written to SD card and then booted. The great thing about the Pi is that there is plenty of on line documentation, how to guides and forums that provide the answers you need.

    To build as small a filesystem as possible the pi-gen script was used to create a Raspbian image. The LITE image was chosen to get basic tools installed. Following the pi-gen readme I generated a script to build the LITE image which is found at RaspberryPi64bit/build-raspbian.sh.

    The output from this build is pi-gen/work/<today’s date>-Raspbian-lite.img. In my case pi-gen/work/2018-07-11-Raspbian-lite.img. Etcher was used to write this to SD card and booted the Pi. With the Pi3B+ on Ethernet  Fing was used to identify its IP address on the local network but unfortunately it was not possible to log in with SSH. At this point I decided it was time to dive in and build my 64 bit image from scratch to get a terminal (with hindsight the solution at this point would have been to mount the boot partition on my host PC and create a file called ssh to enable SSH).

    The fun started when I realised when I started to customise the build. The main issues were that:

    • The only official kernel supported is 32 bit.

    This was easily solved by downloading a 64bit aarch64 Linaro toolchain and using it to build the kernel.

     

    • there is no u-boot as the binary bootloader that runs on the RPi3’s GPU is powerful enough to boot straight into Linux.

    The bootloader looks for a file kernelX.img on the BOOT partition of the SD card and will load and run the file with the highest value of X. X is typically defined to be the ARM core version and so for a 64 bit A53 this would be kernel8.img.

    In my case I wanted to use u-boot and so the uboot binary compiled with the aarch64 toolchain was renamed kernel8.img. The other trick to get this to work is that the config.txt file on the boot partition needs to have the following command to switch core into 64 bit mode

    arm_control=0x200

    u-boot was then configured to load and run linux using a boot.scr file

     

    • The main UART runs the Bluetooth HCI link by default rather than a serial terminal which will help debug boot problems

    In this case Bluetooth was not required and so the Device Tree file was patched to swap the UART pin usage and the terminal use was enabled in config.txt with

    enable_uart=1

     

    • SSH is disabled by default.

    The solution is to create a dummy file in the boot partition called ssh using touch command

     

    • The good news is that a 64 bit kernel will still be able to run with a 32 bit filesystem so the Raspbian-Lite image can still be used for the file system.

    This meant that the original Raspbian image could be copied to a new .img file which could then be mounted to a BOOT and ROOTFS partition on the host and the new uboot, linux kernel and configuration files copied in. Once these partitions were unmounted the new .img file could be copied to an SD card with Etcher and booted.

     

    This full process is implemented by the scripts at https://github.com/HunterEmbedded/RaspberryPi64bit

    $git clone https://github.com/HunterEmbedded/RaspberryPi64bit.git
    
    $cd RaspberryPi64bit
    
    $./build-raspbian.sh

    At this point edit RASPBIAN_NAME in build-uboot-linux64.sh to match the image just created

    $./build-uboot-linux64.sh

    When that is done use Etcher to programme Raspbian-image/uboot-linux64.img to an SD card.

    With the new SD card image you get 64 bit u-boot and linux booting with a terminal available via the UART on pins 6 (GND), 8 (TXD0) and 10 (RXD0) on a RPi3B+. I used an FTDI RPi TTL cable connect these pins to the PC.

    The only problem I was left with was that the terminal prompt (Teraterm) did not respond to keyboard input and just gave me the boot log. For the purposes of my project this was sufficient to give me the IP address and so I could SSH in and use the 64 bit kernel.