WISE-PaaS/OTA Agent(risc linux)

From ESS-WIKI
Jump to: navigation, search

Introduction

This document demonstrates how to support our ota-agent solution on your risc arm linux for BSP update.

Requirement

  • The storage(sd card, Nand flash) capacity need greate than 4G.  8G is recommended

Note

We take our rsb4220 (TI am335x platform) for example.  It is similar for other platfrom.

Architecture

In order to support rollback, we requires the device to have a certain partition layout. At least four different partitions are needed:

  • one boot partition, containing the U-Boot bootloader and its environment
  • two partitions for storing the root file system and kernel. The kernel image file, zImage, and any device tree binary should be stored in directory /boot
  • one partition for persistent data

One of the rootfs and kernel partitions will be marked as the active partition, from which the kernel and rootfs will be booted. The other, called the inactive partition, will be used by the update mechanism to write the updated image. After an update their roles are swapped.

The persistent data partition stores data that needs to be preserved through an update.For our rsb4220, the partition layout is as follow:

  • /dev/mmcblk0p1 containing the u-boot
  • /dev/mmcblk0p2 containing the Current System, or named the active partition
  • /dev/mmcblk0p3 before update, it is blank, it will be used by the update mechanism to write the updated image
  • /dev/mmcblk0p4 persistent data

RTENOTITLE

How to support

uboot modification

modify uboot to let it can switch the boot partition. take our rsb4220 for example:

  • modify file include/configs/am335x_rsb4220.h


define CONFIG_LINUX_OTA
// add boot_part=0
#define CONFIG_EXTRA_ENV_SETTINGS \
...
"boot_part=0\0" \
...
  • modify file arch/arm/lib/board.c


void  board_set_boot_device()
{
    int dev = (*(int *)0XC1000000);
    char *part;
    unsigned int partindex;
    part = getenv("boot_part");
    printf("boot_part index %s\n", part);
    partindex = part ? simple_strtoul (part, NULL, 10) : 0;

    switch(dev) {
    case 0:
    /* booting from MMC0*/
    printf("booting from SD\n");
    setenv("mmcdev", "0");
#ifdef CONFIG_LINUX_OTA
    if(partindex == 0){
        setenv("mmcroot", "/dev/mmcblk0p2 rw");
        setenv("loaduimage","ext2load mmc ${mmcdev}:2 ${kloadaddr} /boot/${bootfile}");
    }
    else if(partindex == 1){
        setenv("mmcroot", "/dev/mmcblk0p3 rw");
        setenv("loaduimage","ext2load mmc ${mmcdev}:3 ${kloadaddr} /boot/${bootfile}");
    }
    else{
        printf("## error: invalid part index, using part A\n");
        setenv("mmcroot", "/dev/mmcblk0p2 rw");
        setenv("loaduimage","ext2load mmc ${mmcdev}:2 ${kloadaddr} /boot/${bootfile}");
    }
#else
    setenv("mmcroot", "/dev/mmcblk0p2 rw");
#endif
#endif
    break;
    }
}

make sd card script

The script formats sd card to meet the requirement of ota under risc linux

You can get the script form here:

https://github.com/ADVANTECH-Corp/wise-paas-ota-agent-risc-linux

Ota script under Linux

This part achieve the ota details under risc linux, mainly copy the kernel and rootfs to the updated partition:

#!/bin/bash
deviceprefix=/dev/mmcblk0p
mountpprefix=/media/mmcblk0p
ubootpartno=1
rootpartAno=2
rootpartBno=3
workpartno=4
ubootdevice=${deviceprefix}${ubootpartno}
rootAdevice=${deviceprefix}${rootpartAno}
rootBdevice=${deviceprefix}${rootpartBno}
workdevice=${deviceprefix}${workpartno}
ubootpoint=${mountpprefix}${ubootpartno}
rootApoint=${mountpprefix}${rootpartAno}
rootBpoint=${mountpprefix}${rootpartBno}
workpoint=${mountpprefix}${workpartno}
OTA_WORK_DIR=${mountpprefix}${workpartno}/ota/work
OTA_LOG_DIR=${mountpprefix}${workpartno}/ota/log
OTA_LOG_FILE=`date +"%Y%m%d%H%M%S"`.log
OTA_LOG_FILE=${OTA_LOG_DIR}/${OTA_LOG_FILE}
partindex=`fw_printenv boot_part | busybox cut -d '=' -f 2`

error_log(){
	echo "$1" >> ${OTA_LOG_FILE}
	exit 1
}
mount_prepare()
{
        umount ${workdevice}
        mount -t ext3  ${workdevice} ${workpoint}
        [ "$?" -ne 0 ] &&  error_log "error: mount failed"
}

if [[ -z $1 ]]; then
cat << EOF
SYNOPSIS:
    $0 {new-bsp-file}

EXAMPLE:
    $0 4221LIV0001_2016-02-29.tar.gz

EOF
    exit 1
fi

#mount_prepare
t1=`echo $1 | busybox cut -d '_' -f 1`
version=`echo ${t1:0-5}`
mkdir -p ${OTA_WORK_DIR}
mkdir -p ${OTA_LOG_DIR}
rm -rf ${OTA_WORK_DIR}/*
touch ${OTA_LOG_FILE}
echo "info: begin: " > ${OTA_LOG_FILE}
echo "info: version: ${version}" >>  ${OTA_LOG_FILE}
echo "info: boot_part: ${partindex}" >>  ${OTA_LOG_FILE}
tar xvf $1 -C ${OTA_WORK_DIR} > /dev/null
[ "$?" -ne 0 ] &&  error_log "error: tar failed" 
cd ${OTA_WORK_DIR}/image
if [ ${partindex} == "0" ];then
	echo "info: current is partA" >> ${OTA_LOG_FILE}
	umount ${rootBdevice}
	echo "info: mkfs.ext3 for rootB" >> ${OTA_LOG_FILE}
	mkfs.ext3 ${rootBdevice}
	[ "$?" -ne 0 ] &&  error_log "error: format rootB failed"
	echo "info: mount rootB" >> ${OTA_LOG_FILE}
	mount -t ext3  ${rootBdevice} ${rootBpoint}
	[ "$?" -ne 0 ] &&  error_log "error: mount rootB failed"
	echo "info: copy files to  rootB" >> ${OTA_LOG_FILE}
	busybox cp -rfa ${OTA_WORK_DIR}/image/rootfs/* ${rootBpoint}/
	[ "$?" -ne 0 ] &&  error_log "error: copy rootB failed"	
elif [ ${version} == "1" ];then
        echo "info: current is partB" >> ${OTA_LOG_FILE}
        umount ${rootAdevice}
	echo "info: mkfs.ext3 for rootA" >> ${OTA_LOG_FILE}
        mkfs.ext3 ${rootAdevice}
        [ "$?" -ne 0 ] &&  error_log "error: format rootA failed"
	echo "info: mount rootA" >> ${OTA_LOG_FILE}
        mount -t ext3  ${rootAdevice} ${rootApoint}
        [ "$?" -ne 0 ] &&  error_log "error: mount rootA failed"
	echo "info: copy files to  rootA" >> ${OTA_LOG_FILE}
        busybox cp -rfa ${OTA_WORK_DIR}/image/rootfs/* ${rootApoint}/
        [ "$?" -ne 0 ] &&  error_log "error: copy rootA failed" 
else
	error_log "error: invalid partition"
fi

rm -rf ${OTA_WORK_DIR}/*
let  newpartindex=($partindex+1)%2
echo "info: will set boot_part to ${newpartindex}" >> ${OTA_LOG_FILE}
fw_setenv boot_part ${newpartindex}
echo "info: success" >> ${OTA_LOG_FILE} 
echo "==============================================" >> ${OTA_LOG_FILE} 
#sync
#reboot
You can get the script from here: https://github.com/ADVANTECH-Corp/wise-paas-ota-agent-risc-linux

modify-env-tools under linux

After update new-bsp to the update partition, it is time to modify the uboot-env to let uboot to boot this new-bsp when next startup.

It is easy under uboot through set the env boot_part, but under linux system, we can't. So we find a tool named fw_printenv to do this.

The source code of fw_printenv tools is under uboot source code(tools/env).Cross-compile it and move fw_printenv to /bin directory under your board. then create a softlink named fw_setenv to fw_printenv. 

Now your can use command fw_printenv to print some environment variable and use fw_setenv to modify some environment variable.

Refer to 

WISE-PaaS/OTA Server

WISE-PaaS/OTA Agent