Update: I finally made it work. Took a lot of time to dig into all the details, but I know a bit more about U-Boot and Mender now… Thanks @drewmoseley @mirzak and for helping me finding the right information.
My path to success to get Mender to run on Nano Pi R1 (not all details are included):
1 Build U-boot for Mender
I concluded that I had to build the U-Boot image from original source and Mender patches. When we started looking at Mender as a system, we did not realize that this was necessary as the system only was tested using Raspberry devices.
Steps to build U-Boot
- Read the following posts:
- Mender from scratch: Mender from scratch
- Mender without Yocto: https://mender.io/blog/notes-from-a-user-on-mender-without-yocto
- Forked U-boot for NanoPi R1 (link)
- Installed necessary toolchain and cross compiler from http://download.friendlyarm.com/nanopineo
- Modified/patched the forked U-Boot source to become Mender U-Boot
- Added
include/config_mender_defines.h
- Downloaded and added Mender patches (link) (partly manually)
- Added
- Added the following lines to
configs/nanopi_h3_defconfig
:CONFIG_ENV_IS_IN_MMC=y
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyS0,115200 panic=10 rootfstype=ext4 rw rootwait fsck.repair=yes"
- Remove the following lines from
configs/nanopi_h3_defconfig
:CONFIG_ENV_OFFSET ...
- Added the following lines to
include/configs/sun8i.h
(Note: should be ininclude/friendlyelec/boardtype.h
, but this file is not included early enough…):#define CONFIG_BOOTCOUNT_LIMIT
#define CONFIG_BOOTCOUNT_ENV
-
#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
(undocumented?)
- Removed/fixed the following lines from
Kconfig
- ENV_OFFSET:
default 0x88000 if ARCH_SUNXI
(should be 0x400000) - ENV_SIZE:
default 0x20000 if ARCH_SUNXI
(should be 0x4000)
- ENV_OFFSET:
- Fixed the
MENDER_LOAD_KERNEL_AND_FDT
by adding the following lines after loading fdt. This was a bit tricky, but necessary to load the kernel from correct partition and avoiding re-enumerating all the mmc’s). Also note that all boot files are lodead from /boot/ at root partition. I am not even sure if this is the correct way to do it, but it works…:
# define MENDER_LOAD_KERNEL_AND_FDT \
"if test \"${fdt_addr_r}\" != \"\"; then " \
"load ${mender_uboot_root} ${fdt_addr_r} /boot/${mender_dtb_name}; " \
"fdt addr ${fdt_addr_r}; " \
"fdt set mmc${boot_mmc} boot_device <1>; " \
"fi; " \
"load ${mender_uboot_root} ${kernel_addr_r} /boot/${mender_kernel_name}; "
#endif
- Compiled U-Boot and fw_printenv
$ export PATH=/opt/FriendlyARM/toolchain/4.9.3/bin:$PATH
$ make nanopi_h3_defconfig ARCH=arm CROSS_COMPILE=arm-linux-
$ make ARCH=arm CROSS_COMPILE=arm-linux-
$ make envtools ARCH=arm CROSS_COMPILE=arm-linux-
- Created
fw_env.config
(based on Mender from scratch)
The files fw_env.config
, fw_printenv
and u-boot-sunxi-with-spl.bin
is then used as a bases (togehter with the base image) and fed into mender-convert
to create the final complete image.
2 Create image using mender-convert
The trick to get the final image was to use basic mender-convert for Ubuntu/Debian and convert the image by injecting the U-Boot image directly into using dd. In addition, all boot files were placed in a folder called /boot/ at the root-fs. Finally fw_printenv/fw_setenv
was installed together with the configuration file.
- Created a special configuration file (
configs/nanopi_r1_config
) for Nano Pi R1 to be used inmender-convert
:
MENDER_DEVICE_TYPE="NanoPi_R1"
MENDER_GRUB_EFI_INTEGRATION=n
MENDER_KERNEL_IMAGETYPE="zImage"
MENDER_IGNORE_MISSING_EFI_STUB=1
# 8MB alignment
MENDER_PARTITION_ALIGNMENT="8388608"
MENDER_STORAGE_TOTAL_SIZE_MB="7456"
MENDER_COMPRESS_DISK_IMAGE="gzip"
function platform_modify() {
log_info "Copying boot-files to /boot/"
run_and_log_cmd "sudo cp -R work/boot/* work/rootfs/boot/"
log_info "Installing fw_printenv and fw_setenv"
run_and_log_cmd "sudo install -m 755 u-boot-files/fw_printenv work/rootfs/sbin/fw_printenv"
run_and_log_cmd "sudo ln -fs /sbin/fw_printenv work/rootfs/sbin/fw_setenv"
run_and_log_cmd "sudo ln -fs /sbin/fw_printenv work/rootfs/usr/bin/fw_printenv"
run_and_log_cmd "sudo ln -fs /sbin/fw_printenv work/rootfs/usr/bin/fw_setenv"
run_and_log_cmd "sudo ln -fs /sbin/fw_printenv work/rootfs/usr/local/bin/fw_printenv"
run_and_log_cmd "sudo ln -fs /sbin/fw_printenv work/rootfs/usr/local/bin/fw_setenv"
run_and_log_cmd "sudo cp u-boot-files/fw_env.config work/rootfs/etc"
}
function platform_package() {
log_info "Writing pre-compiled U-Boot image to ${img_path}"
run_and_log_cmd "sudo dd if=u-boot-files/u-boot-sunxi-with-spl.bin of=${img_path} bs=1024 seek=8 conv=notrunc"
}
-
Put files from U-Boot in a folder:
mender-convert/u-boot-files/fw_env.config
mender-convert/u-boot-files/fw_printenv
mender-convert/u-boot-files/u-boot-sunxi-with-spl.bin
-
Run
mender-convert
This image can finally be dd’d directly to the device…
3 Final notes
Final testing remains. I cannot guarantie that this will actually work. Remaining tasks:
- Test and verify that device is bootable from both partitions (p2 and p3)
- Seems to be working by manually setting
mender_boot_part
andmender_boot_part_hex
- Seems to be working by manually setting
- Test that and ferify device appears on Mender management server
- Test and verify that device can be updated with artifacts
Edit: Realized that i could place all boot files (kernel and *.dtb) in the folder /boot/
at root. Changed /u-boot/
-> /boot/
. Also fixed some typos.