Embedded Linux .NET applications with Yocto

From KoanSoftware Wiki
Jump to: navigation, search

Embedded Linux .NET applications with Yocto and OpenEmbedded

This walk-through has the aim of taking you from a clean system through to including Mono in a build image using the meta-mono layer, then building and packaging an example .NET project for inclusion in that image.

You may already have Yocto installed and just be looking to work with Mono for the first time, in which case you can jump forward to the section you find most relevant,
such as building an example package on the host to test or adding the meta-mono layer to the Yocto build system.

The following assumptions are made. You are:

  • familiar with basic Linux admin tasks
  • aware of the Yocto Project Reference Manual: here.
  • using Ubuntu 18.04 as your host build system
  • working with Yocto

More details are available in the Yocto wiki page: Building and running embedded Linux .NET applications from first principles

Adding the meta-mono layer to the Yocto build system

A preferred method for adding recipes to the build environment, and the method shown with this guide, is to place them within a new layer.

Layers isolate particular sets of build meta-data based on machine, functionality or similar, and help to keep the environment clean.

The meta-mono layer contains Mono specific recipes to support execution of .NET applications on target boards. The layer can be found here.

To use a new layer such as this you first clone the layer from its git repository and then add the layer to your bitbake configuration by editing conf/bblayers.conf

 $ cd ~/yocto/poky-daisy-11.0.0
 $ git clone git://git.yoctoproject.org/meta-mono
 $ cd ~/yocto/poky-daisy-11.0.0/build_qemux86
 $ nano conf/bblayers.conf

Your bblayers.conf should look similar to this

 # LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
 # changes incompatibly
 BBFILES ?= ""
 BBLAYERS ?= " \
   /home/user/yocto/poky-daisy-11.0.0/meta \
   /home/user/yocto/poky-daisy-11.0.0/meta-yocto \
   /home/user/yocto/poky-daisy-11.0.0/meta-yocto-bsp \
   /home/user/yocto/poky-daisy-11.0.0/meta \
   /home/user/yocto/poky-daisy-11.0.0/meta-yocto \

Make the new layer visible to bitbake by adding a line to BBLAYERS

 BBLAYERS ?= " \
   /home/user/yocto/poky-daisy-11.0.0/meta \
   /home/user/yocto/poky-daisy-11.0.0/meta-yocto \
   /home/user/yocto/poky-daisy-11.0.0/meta-yocto-bsp \
   /home/user/yocto/poky-daisy-11.0.0/meta-mono \

Now bitbake can see the recipes in the new layer.

You will also see when bitbake runs and shows the Build Configuration that the repository branch and hash of your layer is shown which is useful to know, particularly when comparing notes with others as to why a build fails, e.g.

 Build Configuration:
 BB_VERSION        = "1.22.0"
 BUILD_SYS         = "i686-linux"
 NATIVELSBSTRING   = "Ubuntu-12.04"
 TARGET_SYS        = "i586-poky-linux"
 MACHINE           = "qemux86"
 DISTRO            = "poky"
 DISTRO_VERSION    = "1.6"
 TUNE_FEATURES     = "m32 i586"
 TARGET_FPU        = ""
 meta-yocto-bsp    = "<unknown>:<unknown>"
 meta-mono         = "master:88c6d5f1961d58b3ec203ff19594f954c3e49cd9"

Build an image including Mono/.NET support

The meta-mono layer includes a recipe to build an image core-image-mono based on the Yocto standard image core-image-sato

To build this image

 $ bitbake core-image-mono

This may take a while, even if you have already built core-image-minimal as additional GUI support packages need to be built.

The core-image-mono recipe can be found here and pulls in an include file from here.

You can see in the include file that extra packages are added to the standard core-image-sato image.

 IMAGE_INSTALL += "mono mono-helloworld"

This is how you would add Mono support to your image within a recipe, or within a .bbappend file. In fact it should only be necessary to add the mono package as it is not necessary to have the examples unless you wish to for testing purposes.

The mono-helloworld recipe included here shows how to build the example project using autotools. For details see the recipe itself here, and more importantly the include file it pulls in here.

You could choose to replace mono-helloworld with mono-helloworld-xbuild which as the name suggests shows how to build the eaxmple project with xbuild.

Testing the .NET executable on an emulated target

Having built core-image-mono you can then run it up under qemu

To run up the image, simply use

$ runqemu qemux86

This will boot the emulator, load up the image, you'll see a kernel loading and then a basic user interface.

If you find that your keymap is incorrect you might wish to set this explicitly, for example

$ runqemu qemux86 qemuparams='-k en-gb'


$ runqemu qemux86 qemuparams='-k en-us'

Open up a terminal window using the appropriate icon, Log into the emulator as 'root', no password and run the examples.

You can run the first with

 $ mono helloworld.exe

Or alternatively the recipe installs a script to wrap use of Mono, so you can use the form

 $ helloworld

This will output



You can run the second with

 $ mono /usr/lib/helloworldform.exe


 $ helloworldform

Depending on your host environment (e.g. using SSH) you may need to explicitly set the DISPLAY variable for this to work, with

 $ export DISPLAY=:0
 $ mono /usr/lib/helloworld/helloworldform.exe

This will show a test Windows Forms form titled 'Hello World'


Lastly you can run a test GTK# application with

You can run the second with

 $ mono /usr/lib/helloworldgtk.exe


 $ helloworldgtk