Portal:MicroOS/Yocto
Creating MicroOS Packages with Yocto
The Yocto Project [1] is a build system based on OpenEmbedded [2] to create Linux distributions for embedded systems. Poky is the reference distribution for Yocto, and most of the time the developers create Poky derivatives for their systems, reusing and adapting the different Poky layers and recipes, and integrating their own drivers and applications.
openSUSE MicroOS is a rolling release, transactional distribution built with the open build service (OBS) [3]. This same build system can be used to create different distributions and packages for already existing ones (like Debian, RedHat or Arch)
In certain domains, Yocto is de-facto reference for developers and integrators, where some manufactures deploy kernel patches and drivers as board support packages (BSP) layers or bitbake recipes. Technically, OBS could be adapted to build those components, but that would not be a simple task, and no one that a Yocto developer can help with.
The other approach would be to see if it is possible to use Yocto to build packages to MicroOS, using the tools and the ecosystem that is more close to them.
Initial approach
Since very early, Yocto supported the integration of third party toolchains, like the Linaro or Arm one. Those SDKs can be downloaded and Yocto configured to use it when creating the sysroot and the distribution packages.
To configure the toolchain some meta files need to be provided. Over time those meta files conflated into a single project, meta-arm-toolchain, as part of the meta-arm layer [4].
This will be the base of our first approach to the problem. openSUSE will provide a cross toolchain, glibc and binutils, that can be locally deployed and match the MicroOS requirements. If fact, this toolchain is exactly the same cross-aarch64-gcc used to build MicroOS itself, but adapted to be installed in different Linux distributions and adjusted to be recognized by meta-arm-toolchain.
Warning: The project is under heavy development, and is currently a moving target. This means that the procedure described here will change in the future. We will update this page as a reference.
Install the toolchain
The toolchain is deployed as a tarball that contains the cross compiler, binaries and libraries required to compile applications for MicroOS. It is using the same compiler and libraries available for MicroOS, but depending on an older glibc version for the host.
Currently, the tool chain is not truly self-contained and there is more work to be done in that regard. The existing toolchain is sufficient to have successful builds in other distributions like Debian, Ubuntu or RedHat.
The installation only requires the download on the tarball and to place it in the system:
mkdir -p cross-sdk && cd cross-sdk wget https://download.opensuse.org/repositories/home:/aplanas:/yocto/images/cross-sdk.x86_64.tar.xz tar -xJvf cross-sdk.x86_64.tar.xz
This version of the toolchain is under development and will change in the future, but the installation process will remain the same.
There is a version of this same toolchain deployed as a container, and can be installed with podman:
podman pull registry.opensuse.org/home/aplanas/yocto/containerfile/opensuse/yocto-microos:latest
Install meta-arm
For this first approach we decided to use the same meta-arm-toolchain layer that is available for other 3rd party toolchains.
This layer is deployed as part of the meta-arm one, and as we will see later, it will go one step further and will provide alternative packages to the one generated for binutils, libc and other libraries when bootstrapping the compiler for Poky.
This will create some mismatch in the package naming, that we will need to resolve in the MicroOS recipes, but for now we will install and reuse this helpful layer.
cd git clone https://git.yoctoproject.org/meta-arm/
The differences between the Arm / Linaro toolchains with the MicroOS one, we need to change the external-arm-toolchain.bb recipe with this patch:
diff --git a/meta-arm-toolchain/recipes-devtools/external-arm-toolchain/external-arm-toolchain.bb b/meta-arm-toolchain/recipes-devtools/external-arm-toolchain/external-arm-toolchain.bb index fab17611..bf5ba8ca 100644 --- a/meta-arm-toolchain/recipes-devtools/external-arm-toolchain/external-arm-toolchain.bb +++ b/meta-arm-toolchain/recipes-devtools/external-arm-toolchain/external-arm-toolchain.bb @@ -225,6 +225,22 @@ do_install() { # Remove unused /usr/share/info/dir rm -f ${D}${infodir}/dir + + # Remove missplaced components for MicroOS + rm ${D}${base_libdir}/as + rm ${D}${base_libdir}/cc1 + rm ${D}${base_libdir}/cc1plus + rm ${D}${base_libdir}/g++-mapper-server + rm ${D}${base_libdir}/lto-wrapper + rm ${D}${base_libdir}/lto1 + rm ${D}${base_libdir}/liblto_plugin.so + rm ${D}${base_libdir}/collect2 + rm ${D}${base_libdir}/ld + rm -fr ${D}${base_libdir}/finclude + rm -fr ${D}${base_libdir}/include-fixed + rm -fr ${D}${base_libdir}/include + rm -fr ${D}/usr/share/EMPTY + mkdir ${D}/usr/share/locale } # External toolchain doesn't provide multilib support so make corresponding
Install Yocto
There are plenty of information about how to install Yocto [5]. If we are using a Virtual Machine or a physical host, we will need to install some dependencies required by Yocto, like gcc, git and Python. Again refer to the project documentation [6] for a complete list of requirements.
If you are using the container, those dependencies should be already available.
In any case a required step is to clone the Poky git repository:
git clone git://git.yoctoproject.org/poky -b langdale
Poky is the reference distribution of Yocto, but also bundle all the OpenEmbedded Core recipes and layers, the relevant bbclass, the bitbake set of tools and the Yocto scripts and documentation.
Instead of working with "master", we will switch to the "langdale" branch, that will contain the last (as the write of this guide) stable Poky release.
Now we can create the build directory and the configuration files with:
cd poky source oe-init-build-env
This script is also setting multiple environment variables (including PATH), so we will need to source it every time that we want to work with Yocto.
The first time that this is called it will create the build directory (and place us on it), and the conf/bblayers.conf and conf/local.conf configuration files that we will need to adjust.
For conf/bblayers.conf we need to register the meta-arm-toolchain and the meta-example (described later) layers, so bitbake can find them during the parsing stage. So be sure that the BBLAYERS variable is something like this:
BBLAYERS ?= " \ /home/ubuntu/poky/meta \ /home/ubuntu/meta-arm/meta-arm-toolchain \ /home/ubuntu/meta-example \ /home/ubuntu/poky/meta-poky \ /home/ubuntu/poky/meta-yocto-bsp \ /home/ubuntu/poky/build/workspace \ "
For conf/local.conf we need to target the AArch64 machine, maybe using QEMU for the testing. Also, we need to indicate that we want to use a 3rd party toolchain and the path where it is allocated. Add those lines at the end of the file:
MACHINE = "qemuarm64" DEFAULTTUNE = "aarch64" TCMODE = "external-arm" # Adjust the path here EXTERNAL_TOOLCHAIN = "<FULLPATHOF>/cross-sdk/usr" EAT_TARGET_SYS:aarch64 = "aarch64-suse-linux"
Creating a MicroOS package
The last step is to create this "meta-example" layer, that will contain something that we can compile. For the demo I prepared a bare-bones, self contained and with some adjustment to target MicroOS.
git clone https://github.com/aplanas/meta-example.git
The recipe (example_0.1.bb) is a default one with some changes. The first one is to remove "libc6" as a automatically added dependency when the RPM is generated. This is added dynamically by the packaging bbclass.
The "meta-arm-toolchain" layer is re-packaging some of the libraries in our SDK using the names expected by Poky, and that includes the generation of the "libc6.rpm" package. This is added later as a dependency with this name in our "example.rpm", but MicroOS does not recognize this name, but glibc. This can be fixed adding marking this library as a private one:
PRIVATE_LIBS = "libc.so.6" INSANE_SKIP:${PN} += "file-rdeps"
Also, the bbclass for RPM generation will add all the directories into the "%dir" section of the spec file. That will present a problem in MicroOS, as they are currently owned by the filesystem package. We can use the undocumented "DIRFILES" variable, listing a non-valid directory:
DIRFILES = "None"
After that, we can now compile the package and all the dependencies:
bitbake example
This will generate the RPM and place it in tmp/work/aarch64-poky-linux/example/0.1-r0/deploy-rpms/aarch64 inside the build directory. This package can be directly installed in our MicroOS installation.
Issues and future work
This shows that Yocto can generate packages for MicroOS in AArch64, but the current strategy can be improved to avoid certain shortcomings, like the recipe adjustments.
The toolchain that we use comes directly form MicroOS, but present a different layout that the ones provided by Arm or Linaro. For example, some of our directories are conflating binaries and libraries from the host and the target architectures. This is something that we should fix.
Also maybe the meta-arm-toolchain approach is not the best option for MicroOS. Generating packages directly from the SDK, and using the names expected by Poky force us to workaround this into the bb recipes. Maybe a better idea is to provide our meta-microos-toolchain layer, that will simplify the do_install task and will not provide any package.
To fix then the missing dependencies, a new meta-microos layer can deploy the MicroOS RPM packages into the sysroot in a smart way, avoiding also any recompilation of any library already available.
The current toolchain is also not fully self-contained. This should be fixed with PatchELF, to point some libraries from the system into the bundle.
We are already providing one architecture, AArch64. Toolchain for other architectures, like riscv, should be available too for any serious work.
References
[1] https://www.yoctoproject.org/
[2] https://www.openembedded.org/wiki/Main_Page
[3] https://openbuildservice.org/
[4] https://git.yoctoproject.org/meta-arm/
[5] https://docs.yoctoproject.org/brief-yoctoprojectqs/index.html
[6] https://docs.yoctoproject.org/ref-manual/system-requirements.html