Mender is an open source system for upgrading embedded Linux devices.
For now integrating Mender is easiest if you are using Yocto to build your systems.
I have a simple meta-layer for Odroid-C2 boards that can be adapted without too much effort to add Mender support.
The steps to setup and build are similar to the ones outlined in this post Building Odroid-C2 Systems with Yocto with the following differences
- The meta-mender repository needs to be cloned and added to bblayers.conf
- Add some mender classes and storage configuration to your local.conf
- Configure the systems for the mender server you plan to use
- Generate artifact signing keys and copy to the proper location
- Add u-boot-fw-utils and a mender daemon startup script to your image
- Create an SD image file
Detailed explanations of each step follow.
Add the meta-mender layer
I am assuming the directory structure from the Building Odroid-C2 Systems with Yocto post.
Namely this
~/poky-rocko/
meta-openembedded/
...
~/odroid-c2/
meta-odroid-c2/
build/
conf/
Adjust accordingly if that is not what you are using.
Clone the meta-mender layer, the [rocko] branch
~$ cd ~/poky-rocko
~/poky-rocko$ git clone -b rocko git://github.com/mendersoftware/meta-mender
Then use the example bblayers.conf-mender-sample in meta-odroid-c2/conf for your bblayers.conf
~$ cd odroid-c2
~/odroid-c2$ mkdir -p build/conf
~/odroid-c2$ cp meta-odroid-c2/conf/bblayers.conf-mender-sample \
build/conf/bblayers.conf
Again adjust accordingly if you are using different paths.
Add Mender configuration to local.conf
There is an example in meta-odroid-c2/conf/local.conf-mender-sample.
Copy it as your local.conf
~/odroid-c2$ cp meta-odroid-c2/conf/local.conf-mender-sample \
build/conf/local.conf
You can choose to edit DL_DIR, SSTATE_DIR and TMPDIR as described in the Building Odroid-C2 Systems with Yocto post or leave them alone and commented.
A KERNEL_DEVICETREE needs to be set in this file (or in machine.conf) so both the mender classes and the kernel recipe can see it.
Only declare one dtb here since the mender patched u-boot is going to embed in the u-boot environment this dtb as the one to feed the kernel. Mender (by default) will override any auto-detection in u-boot about which dtb to load.
This behavior can be changed with some modifications to mender’s u-boot changes, but to get started just choose the correct dtb for the board you are using.
With the exception of MENDER_ARTIFACT_NAME (set to anything you want) and MENDER_SERVER_URL (covered in the next section), you should leave the other variables alone for your first build and experiment later.
The systems generated from these definitions assume an SD card that is at least 4 GB and will generate the following layout
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 * 16384 32767 16384 8M c W95 FAT32 (LBA)
/dev/mmcblk0p2 32768 2129919 2097152 1G 83 Linux
/dev/mmcblk0p3 2129920 4227071 2097152 1G 83 Linux
/dev/mmcblk0p4 4227072 6848511 2621440 1.3G 83 Linux
You also have to decide whether you want your systems to boot from an SD card or an eMMC module. For use with an SD card u-boot will see the SD card as MMC0 and the linux kernel will see the boot MMC device as /dev/mmcblk1. So set these two Mender variables this way
# for SD card use
MENDER_UBOOT_STORAGE_DEVICE = "0"
MENDER_STORAGE_DEVICE = "/dev/mmcblk1"
If you are using an eMMC module, then u-boot and the kernel see the MMC device opposite this, so set the Mender variables like this
# for eMMC use
MENDER_UBOOT_STORAGE_DEVICE = "1"
MENDER_STORAGE_DEVICE = "/dev/mmcblk0"
You can lookup all these definitions in the Mender documentation.
Choose your mender server
You need to tell clients where the mender server is.
If you follow the Production installation steps and run your own mender server, you will set the MENDER_SERVER_URL variable to that server like the example I used here
MENDER_SERVER_URL = "https://fractal.jumpnow"
When setting up server you will have generated some server keys. The server.crt file you generated needs to be copied to
meta-odroid-c2/recipes-mender/mender/files/server.crt
before you build the mender recipe.
If instead you choose to use Mender’s hosting service then you would set the following
MENDER_SERVER_URL = "https://hosted.mender.io"
and then add another variable with your mender tenant token
MENDER_TENANT_TOKEN = "<big long token>"
When using mender’s hosting service or if your mender server has an officially signed CA cert, then you should remove the server.crt line from SRC_URI in my mender recipe bbappend.
meta-odroid-c2/recipes-mender/mender/mender_%.bbappend
Generate artifact signing keys
Signing artifacts is an optional but recommended feature of mender.
You can read about the Mender Signing and verification framework here.
There is a short README in the meta-odroid-c2 repository for setting up the signing keys to work with the meta-odroid-c2 build systems and utility scripts.
meta-odroid-c2/docs/README-mender-keys
If you follow those instructions you can immediately use a provided utility script to generate and sign mender artifacts for uploading to a mender server
meta-odroid-c2/scripts/sign-mender-image.sh
Add u-boot-fw-utils and mender init startup
Mender requires the u-boot-fw-utils for maintaining the u-boot environment about the active root partition.
Mender also requires that the mender daemon be running to communicate with the mender-server.
Mender provides a systemd service file, but since I am using sysvinit I wrote a simple mender-sysvinit package recipe to provide the same.
Fix dtb path problem with Mender and ARM64 systems
See this post in the Mender mailing list.
This is probably just a temporary issue.
I provided the diff I am using to get around this for now.
It is a one liner, easy to apply and remove later.
Build the system
There is a simple Yocto image recipe you can use for testing
meta-odroid-c2/recipes-mender/images/mender-test-image.bb
Build it with bitbake after sourcing the Yocto environment
~/odroid-c2/build$ bitbake mender-test-image
Note that only the two packages in MENDER_EXTRA are required beyond the additions to local.conf to enable mender in the client.
Create an SD image file
The systems built with configuration described above are intended to be run from an SD card.
For the initial installation to the SD card, care needs to be taken to configure the two rootfs partitions and the data partition for persistent data.
There is a script I am using for this
meta-odroid-c2/scripts/create_mender_image.sh
The script does not require any arguments but you may have to modify the TOPDIR variable at the top of the script if you are using different paths then described above.
The result of this script can be copied to an SD card using dd
~/odroid-c2/upload$ sudo dd if=odroid-c2-mender-test.img of=/dev/sdb bs=1M