NanoPi Neo2 Porting Mender to Openwrt

Hm, still works out-of-tree.

Can you also provide the .config file that is generated in OpenWRT.

https://www.rossco.org/Downloads/OpenWrt/u-boot_config.txt

Yepp, definitely a diff. Unknown why though.

--- .config	2019-03-12 13:53:28.111224166 +0100
+++ openwrt-config	2019-03-12 13:53:24.551210606 +0100
@@ -147,7 +147,8 @@
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 # CONFIG_SPL_DRIVERS_MISC_SUPPORT is not set
-CONFIG_ENV_SIZE=0x4000
+CONFIG_ENV_SIZE=0x20000
+CONFIG_ENV_OFFSET=0x88000
 CONFIG_SPL_SYS_MALLOC_F_LEN=0x400
 CONFIG_SPL=y
 CONFIG_IDENT_STRING=" Allwinner Technology"
@@ -709,16 +710,19 @@
 # Environment
 #
 # CONFIG_ENV_IS_IN_EEPROM is not set
-# CONFIG_ENV_IS_IN_FAT is not set
+CONFIG_ENV_IS_IN_FAT=y
 # CONFIG_ENV_IS_IN_EXT4 is not set
 # CONFIG_ENV_IS_IN_FLASH is not set
-CONFIG_ENV_IS_IN_MMC=y
+# CONFIG_ENV_IS_IN_MMC is not set
 # CONFIG_ENV_IS_IN_NAND is not set
 # CONFIG_ENV_IS_IN_NVRAM is not set
 # CONFIG_ENV_IS_IN_ONENAND is not set
 # CONFIG_ENV_IS_IN_REMOTE is not set
 # CONFIG_ENV_IS_IN_SPI_FLASH is not set
 # CONFIG_ENV_IS_IN_UBI is not set
+CONFIG_ENV_FAT_INTERFACE="mmc"
+CONFIG_ENV_FAT_DEVICE_AND_PART="0:auto"
+CONFIG_ENV_FAT_FILE="uboot.env"
 # CONFIG_USE_DEFAULT_ENV_FILE is not set
 # CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG is not set
 CONFIG_NET=y

Noticed one thing, to fully re-produce your environment I need your config_mender_defines.h file,

which is copied in

  cp ./files/config_mender_defines.h /home/rossb/OpenWrt/trunk/build_dir/target-aarch64_cortex-a53_glibc/u-boot-nanopi_neo2/u-boot-2018.11/include

crap, I sent you .config from standard openwrt build, after I reverted, standby

Ok, config updated (bootlin toolchain), same file

https://www.rossco.org/Downloads/OpenWrt/config_mender_defines.h

I was able to re-produce your error now.

And now I see the problem. You need to drop this line from config_mender_defines.h,

 #include <generated/autoconf.h>

Edit: To further explain, above file contains the U-boot configuration and by adding it here it was also included in the SPL and it enables CONFIG_DM among other things which does not build during SPL build.

1 Like

hm, that’s how I specifed env_size (from .config)
#define MENDER_BOOTENV_SIZE CONFIG_ENV_SIZE

and, in my Makefile:
echo CONFIG_ENV_OFFSET=0x400000 >> (PKG_BUILD_DIR)/configs/nanopi_neo2_defconfig echo CONFIG_ENV_SIZE=0x4000 >> (PKG_BUILD_DIR)/configs/nanopi_neo2_defconfig
…neither of which appear in .config

Removed #include <generated/autoconf.h>, added #define MENDER_BOOTENV_SIZE 0x4000

Result: SUCCESS for both toolchains

still have to sort out impact of missing CONFIG_ENV_OFFSET=0x400000, cleanup, re-org flash layout, port Mender app, test, test, test

Thank you very much! As promised, I will provide everything required for Mender / openwrt integration for you to freely publish and maintain, also with blessings and thanks of my employer. We will, of course, add credits to ourselves.

Regards;
Bill

CONFIG_ENV_OFFSET is undefined and not used. Replaced by:
#define MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET_1 0x400000
and, according to mender patch if defined must match above, else be undefined

Yes, best is to not have it defined outside of the Mender files, and config_mender_defines.h && config_mender.h should take care of it

Makes sense and we will happily look in to this once you have something to share.

Can already now hint that we are looking for community maintainers :wink:

Status: Script to go from openwrt image to mender compliant image complete, boots with mender u-boot patches.
Creating openwrt mender app package and host app

1 Like

Awesome, thanks for the update

Hi;
Need your feedback re descriptions (since its your product) - alter to taste

define Package/$(PKG_NAME)/description
  Mender client is an OTA updater for linux systems.
  Features include redundant boot, failsafe updates, rollback.
  Mender is a client normally connected to an update server for updates.
  Mender is capable of standalone updates.
endef

# mender configuration
menu "Configuration"
	depends on PACKAGE_mender
	config MENDER_SERVER_URL
		string "ServerURL"
		default ""
		help
			Internet URL of Mender update server.
	config MENDER_CERT_LOCATION
		string "ServerCertificate"
		default "/etc/ssl/certs"
		help
			Directory containing Mender SSL certificate.
	config MENDER_CERTIFICATE
		string "Certificate"
		default ""
		help
			File name of Mender client auth SSL certificate.
        config MENDER_KEY
                string "Key"
                default ""
                help
                    	File name of Mender client auth SSL key.
	config MENDER_ROOTFS_PART_A
		string "RootfsPartA"
		default "/dev/mmcblk0p2"
		help
			Device node of First rootfs partition.
	config MENDER_ROOTFS_PART_B
		string "RootfsPartB"
		default "/dev/mmcblk0p3"
		help
			Device node of First rootfs partition.
	config MENDER_UPDATE_POLL_INTERVAL_SECONDS
		int "UpdatePollIntervalSeconds"
		default 86400
		help
			How often to poll mender server for code updates. Default daily (86400 seconds).
	config MENDER_INVENTORY_POLL_INTERVAL_SECONDS
		int "InventoryPollIntervalSeconds"
		default 86400
		help
			How often to poll mender server	for inventory updates. Default daily (86400 seconds).
	config MENDER_RETRY_POLL_INTERVAL_SECONDS
		int "RetryPollIntervalSeconds"
		default 30
		help
			How often to retry polling mender server when connection failure. Default 30 seconds.
endmenu

@MarekBelisko - added markdown

Updated (see below).

It is unclear to me why you need MENDER_CERT_LOCATION and MENDER_KEY so I have dropped them below.

It should be enough with MENDER_CERTIFICATE which is only needed if self-signed certs are used. Otherwise it is enough to install the “ca-certificates” package (might be named differently in OpenWRT)

define Package/$(PKG_NAME)/description
  Mender is an open source, Aparche 2.0 licensed
  over-the-air (OTA) software updater for embedded
  Linux devices. Mender comprises a client running
  at the embedded device, as well as a server that
  manages deployments across many devices.

  More information at https://docs.mender.io
endef

# mender configuration
menu "Configuration"
    depends on PACKAGE_mender
    config MENDER_SERVER_URL
        string "ServerURL"
        default ""
        help
             The server URL which is used as the basis
             for API requests. This should be set to the
             server that runs the Mender server services.
             It should include the whole URL, including
             https:// and a trailing slash
    config MENDER_CERTIFICATE
        string "Certificate"
        default ""
        help
            The location of the public certificate of
            the server, if any. If this certificate is
            missing, or the one presented by the server
            doesn't match the one specified in this
            setting, the server certificate will be
            validated using standard certificate trust
            chains.
    config MENDER_ROOTFS_PART_A
        string "RootfsPartA"
        default "/dev/mmcblk0p2"
        help
            The Linux device that contains root filesystem A.
    config MENDER_ROOTFS_PART_B
        string "RootfsPartB"
        default "/dev/mmcblk0p3"
        help
            The Linux device that contains root filesystem B.
    config MENDER_UPDATE_POLL_INTERVAL_SECONDS
        int "UpdatePollIntervalSeconds"
        default 86400
        help
            An integer that sets the number of seconds
            to wait between each check for a new update.
            Note that the client may occasionally check
            more often if there has been recent activity
            on the device.

            Default daily (86400 seconds).
    config MENDER_INVENTORY_POLL_INTERVAL_SECONDS
        int "InventoryPollIntervalSeconds"
        default 86400
        help
            An integer that sets the number of seconds
            to wait between each inventory update. Note
            that the client may occasionally post its
            inventory more often if there has been recent
            activity on the device.

            Default daily (86400 seconds).
    config MENDER_RETRY_POLL_INTERVAL_SECONDS
        int "RetryPollIntervalSeconds"
        default 30
        help
            An integer that sets the number of seconds
            to wait between each attempt to download an
            update file. Note that the client may attempt
            more often initially to enable rapid upgrades,
            but will gradually fall back to this value if
            the server is busy

            Default 30 seconds
endmenu

Thanks;

Just to be sure; MENDER_CERT_LOCATION and MENDER_KEY were used to populate mender.conf values (example link below).

so (correct me if wrong)

  • MENDER_CERTIFICATE is the full path and file name of the update server’s public key if self-signed keys are used, else, “”. This corresponds to the “Certificate” field of mender.conf (above link)
  • MENDER_CERT_LOCATION. This corresponds to the “ServerCertificate” field of mender.conf and is unused, should always be “”. Is this a placeholder for something?
  • MENDER_KEY is unused. Suspect it is part of a placeholder mechanism for client to auth to server, or signing requests, not implemented? As pertains to mender.conf (link above), the “Key” field is unused and always an empty string. This implies that no mechanism is in place for clients to auth to mender update server.
  • In terms of the above config variables, mender.conf looks like this:
{
  "ClientProtocol": "http",
  "HttpsClient": {
    "Certificate": "MENDER_CERTIFICATE",
    "Key": ""
  },
  "RootfsPartA": "MENDER_ROOTFS_PART_A",
  "RootfsPartB": "MENDER_ROOTFS_PART_B",
  "UpdatePollIntervalSeconds": MENDER_UPDATE_POLL_INTERVAL_SECONDS,
  "InventoryPollIntervalSeconds": MENDER_INVENTORY_POLL_INTERVAL_SECONDS,
  "RetryPollIntervalSeconds": MENDER_RETRY_POLL_INTERVAL_SECONDS,
  "ServerURL": "MENDER_SERVER_URL",
  "ServerCertificate": ""
}

Regards;
Bill

Just FYI, there is a section in our docs describing all the configuration options

https://docs.mender.io/1.7/client-configuration/configuration-file/configuration-options

It is actually unclear to me what these are used for:

“ClientProtocol”: “http”,
“HttpsClient”: {
“Certificate”: “”,
“Key”: “”
},

@kacf, do you know the specifics for this?

  • MENDER_CERT_LOCATION. This corresponds to the “ServerCertificate” field of mender.conf and is unused, should always be “”. Is this a placeholder for something?

From the docs

“The location of the public certificate of the server, if any. If this certificate is missing, or the one presented by the server doesn’t match the one specified in this setting, the server certificate will be validated using standard certificate trust chains.”

And it is only used if you are using self-signed certificates. I would also only expect this value configuration option to be necessary.

I think the idea is that you should put server.crt in SRC_URI and leave that variable alone. But it is indeed phrased quite poorly.

so, there is confusion regarding whether the mender server’s public key (if self-signed) should be in the “Certificate” or “ServerCertificate” field of mender.conf? Which is it?

Here’s mender.conf, generated by openwrt build (assumes using standard trust chains, letsencrypt certs in our case):
{
“ClientProtocol”: “http”,
“HttpsClient”: {
“Certificate”: “”,
“Key”: “”
},
“RootfsPartA”: “/dev/mmcblk0p2”,
“RootfsPartB”: “/dev/mmcblk0p3”,
“UpdatePollIntervalSeconds”: 86400,
“InventoryPollIntervalSeconds”: 86400,
“RetryPollIntervalSeconds”: 30,
“ServerURL”: “https://mender.example.com/”,
“ServerCertificate”: “”
}

Yes, this implies that I have successfully ported the mender app to openwrt:
[rossb@localhost trunk]$ ls -la build_dir/target-aarch64_cortex-a53_glibc/mender-1.7/ipkg-aarch64_cortex-a53/mender/usr/bin
total 6092
drwxr-xr-x 2 rossb rossb 4096 Mar 19 05:15 .
drwxr-xr-x 4 rossb rossb 4096 Mar 19 05:15 …
-rwxr-xr-x 1 rossb rossb 6226584 Mar 19 05:15 mender

FYI and IMHO. Because golang is used for the mender app, it is bloated (6M+) by the statically included go libraries. This will be an impediment to mender usage on storage “challenged” devices. Suggestion: Create a C/C++ version of the mender app which can be linked to already existing standard libraries, reducing size, allowing deeper penetration into the embedded market. I’m sure you have heard this before.