Bake 64-bit raspberryPI3 images with Yocto/OpenEmbedded


RaspberryPI3 SBC and CM come with cortex-a53 based SOC which is 64-bit capable and uses ARM-v8 architecture. Originally RaspberryPI 3 was released with 32bit support alone which is backward compatible with RaspberryPI 2. However, over period of last couple of years a lot of development has gone into enabling 64-bit on ARM in community,  Eric Anholt’s VC4 drivers have matured on 64bit kernels, various userspace packages have been ported by Linaro and other communities.  We have put efforts in integrating all these efforts for full system using OpenEmbedded/Yocto framework. The support is fairly new and therefore there might be some issues still lurking, Here we will go through the steps for building full Graphical images.

Build Setup

Since the support is new, its recommended to use Rocko 2.4 release or newer

mkdir rpi-yocto; cd rpi-yocto
git clone git://
git clone git://
git clone git://
git clone git://

source poky/oe-init-build-env rpi64-build

bitbake-layers add-layer ../meta-raspberrypi
bitbake-layers add-layer ../meta-96boards
bitbake-layers add-layer ../meta-openembedded/meta-oe
bitbake-layers add-layer ../meta-openembedded/meta-python
bitbake-layers add-layer ../meta-openembedded/meta-perl
bitbake-layers add-layer ../meta-openembedded/meta-multimedia 
bitbake-layers add-layer ../meta-openembedded/meta-networking
bitbake-layers add-layer ../meta-openembedded/meta-gnome
bitbake-layers add-layer ../meta-openembedded/meta-xfce

Edit conf/local.conf  to set machine

MACHINE = "raspberrypi3-64"

Build Sato Image ( Yocto Project Reference GUI image )

bitbake core-image-sato

Build XFCE image

If you intend to build a full desktop system like XFCE then build core-image-minimal-xfce

bitbake core-image-minimal-xfce

Prepare SD-Card

sudo dd if=tmp/deploy/images/raspberrypi3-64/core-image-sato-raspberrypi3.rpi-sdimg of=/dev/sdX

where X is the letter a,b,c which your build machine would have mounted the Micro-SD card on you can check that with

dmesg | tail -10

Resize SD-Card

Add in local.conf

CORE_IMAGE_EXTRA_INSTALL_append = " 96boards-tools "

build the image again and flash it to SD-Card, this will expand the rootfs to span over complete SD card.

Using MUSL C library

Musl is a light weight alternative to glibc which is fully supported in OpenEmbedded-core and Yocto project. In order to use musl instead of glibc add ( in local.conf )

TCLIBC = "musl"

Using Clang Compiler

Clang is supported via a layer of its own, if you intend to use clang to compile the packages, you have to add meta-clang to layer mix.

cd rpi-yocto; git clone git://

bitbake-layers add-layer ../meta-clang

If clang should be used as default compiler then add following in local.conf

TOOLCHAIN ?= "clang"

Please note that there is a small number of packages which still would use gcc to build. e.g. for core-image-sato we still build following packages with gcc

  • pixman
  • linux-kernel
  • glibc( if you use it)
  • elfutils
  • tcp-wrappers
  • busybox


What works

  • Ethernet
  • Graphics
  • USB
  • Keyboard/mouse
  • HDMI



  • Validate bluetooth
  • Validate on board WiFi
  • Video playback
  • Sound

Need Help ?

Please ask questions on IRC or mailing lists

Mailing lists

Clang based Cross SDK with OpenEmbedded Framework


Clang based toolchain can be used to compile large portions of packages in OpenEmbedded Framework, in this article we will cover the generating and using OpenEmbedded SDKs based on Clang, This SDK will also have the original cross gcc based compilers cohabiting with clang

Generating SDK

Building image base SDK in OpenEmbedded Framework is a simple process like its building any other image or component. One can generate a SDK corresponding to final image that will be shipped on target. This gets development headers and libraries from all the dependencies packaged into the SDK installer, this SDK then can be installed and used for stand alone application development.

Preparing OpenEmbedded Workspace

$ git clone
$ cd openembedded-core
$ git clone
$ git clone
$ . ./oe-init-build-env

Add meta-clang to conf/bblayers.conf e.g.

# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
 /home/kraj/openembedded-core/meta-clang \
 /home/kraj/openembedded-core/meta \
 /home/kraj/openembedded-core/meta \

Select qemuarm64 for MACHINE in conf/local.conf, you need to uncomment the line marked in red

# Machine Selection
# You need to select a specific machine to target the build with. There are a selection
# of emulated machines available which can boot and run in the QEMU emulator:
#MACHINE ?= "qemuarm"
MACHINE ?= "qemuarm64"
#MACHINE ?= "qemumips"
#MACHINE ?= "qemuppc"
#MACHINE ?= "qemux86"
#MACHINE ?= "qemux86-64"

Build SDK

$ bitbake -cpopulate_sdk core-image-minimal

Install SDK

SDK self-installer will be in deploy are under e.g. tmp-glibc/deploy/sdk/

$ ./tmp-glibc/deploy/sdk/

OpenEmbedded SDK installer version nodistro.0
Enter target directory for SDK (default: /usr/local/oecore-x86_64):
You are about to install the SDK to “/usr/local/oecore-x86_64”. Proceed[Y/n]?
Extracting SDK…………………………….done
Setting it up…done
SDK has been successfully set up and is ready to be used.
Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
$ . /usr/local/oecore-x86_64/environment-setup-aarch64-oe-linux

Using SDK

The environment setup needs to be done in every shell where the SDK is to be used

$ . /usr/local/oecore-x86_64/environment-setup-aarch64-oe-linux

At this point the SDK is ready to be used for compiling applications as well as kernel. Since the SDK has both gcc and clang in it a new set of variables is introduced to make it easy to use clang

CLANGCC – C cross compiler

CLANGCXX – C++ cross compiler

Example 1 – Build musl C library

The example lists compiling musl C library using the cross SDK but this can be used for anything including kernel and application

$ git clone git://
$ cd musl
$ ./configure --host=aarch64-oe-linux CC=${CLANGCC}
$ make -j

Example 2 – Building llvmlinux kernel

$ git clone git:// llvmlinux
$ cd llvmlinux
$ make ARCH=arm64 CC=${CLANGCC} LDFLAGS="" defconfig
$ make ARCH=arm64 CC=${CLANGCC} LDFLAGS="" -j vmlinux

If the kernel for aarch64 won’t build, then hey what have you been waiting for ? you have everything go fix it !!!


I have not provided prebuilt SDKs, if there is enough intrest for such SDKs, I would consider building the SDK self-installs and host them somewhere, contact me if you are interested.

Example is covering aarch64 but the SDKs are not limited to aarch64, one can build for x86,x86_64, ppc, mips, arm in same fashion. All one would need is to changes is MACHINE selection in conf/local.conf

Using Clang with OpenEmbedded/Yocto Project


Clang is C/C++/ObjC  frontend for LLVM compiler suite,  supporting several architectures now. We have added support for clang into OpenEmbedded using a standalone layer

This layer requires OpenEmbedded-core layer as dependency

Configuring meta-clang

git clone git://
cd openembedded-core
git clone git://
git clone git://


. ./oe-init-build-env

Edit conf/bblayer.conf to add meta-clang

# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly


 /a/wheezy/home/kraj/work/openembedded-core/meta-clang \
 /a/wheezy/home/kraj/work/openembedded-core/meta \

 /a/wheezy/home/kraj/work/openembedded-core/meta \


Selecting Default system Compiler

When meta-clang is added to layers it switches the default cross compiler for the system to be clang naturally. This selection is made by a variable which is assigned to choose clang if nothing else is selected

TOOLCHAIN ??= "clang"

One could start using GCC as default system compiler by setting TOOLCHAIN variable to ‘gcc’


This selection is done in configuration metadata files like conf/local.conf

Per-recipe ( package ) Compiler selection

When using clang, not all components are compilable yet, hence we have to sometimes choose gcc for certain package recipe. In order to do it, you have to write a .bbappend in meta-clang, as an example below bbappend shows how we select gcc for building glibc

$ cat recipes-excluded/nonclangable/glibc_%.bbappend

Current Status

We can build/boot core-image-minimal for qemux86 and raspberryPi machines, of course that includes few components which are still compiled using gcc. But at this point, we are ready to port the packages to compile with clang

Compiling Kernel with Clang

For kernel we still use gcc, to start using clang for kernel we would require to override KERNEL_CC variable

kernel-arch.bbclass:KERNEL_CC = "${CCACHE}${HOST_PREFIX}gcc ${HOST_CC_KERNEL_ARCH} -fuse-ld=bfd"

To use clang

kernel-arch.bbclass:KERNEL_CC = "${CCACHE}${HOST_PREFIX}clang ${HOST_CC_KERNEL_ARCH} -fuse-ld=bfd"

This can also be done in kernel recipe too.

KERNEL_CC_forcevariable = "${CCACHE}${HOST_PREFIX}clang ${HOST_CC_KERNEL_ARCH} -fuse-ld=bfd"

Compiler runtime

We currently use gcc runtime by default with clang as well, meta-clang does have recipes for compiler-rt and libc++ which can be used to replace libgcc and libstdc++, at application level this selection can be made to depend on compiler-rt and libc++


We can generate OpenEmbedded SDK which will have both gcc and clang based cross compilers

bitbake -cpopulate_sdk core-image-minimal

Installing the SDK should be done something like this Installing the Toolchain¶

To use clang in SDK one should use CLANGCC and CLANGCXX environment variables to reference the clang compilers