[U-Boot] [RFC] tools/env: Support UBI devices

Instead of requiring gluebi to update u-boot environments from Linux, directly support writing to an UBI device. The fw_env.config file will look something like this:
Device Offset Envsize LEB Size Count /dev/ubi0_0 0 0x10000 0x1f000 1
It is important to use LEB size instead of PEB size when using UBI.
Signed-off-by: Kevin Smith kevin.smith@elecsyscorp.com Cc: Michael Heimpold mhei@heimpold.de Cc: Joe Hershberger joe.hershberger@ni.com --- tools/env/fw_env.c | 71 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 23 deletions(-)
diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index ba11f77..af7a8ae 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -13,6 +13,7 @@ #include <errno.h> #include <env_flags.h> #include <fcntl.h> +#include <limits.h> #include <linux/stringify.h> #include <stdio.h> #include <stdlib.h> @@ -29,6 +30,7 @@ #else # define __user /* nothing */ # include <mtd/mtd-user.h> +# include <mtd/ubi-user.h> #endif
#include "fw_env.h" @@ -54,6 +56,8 @@ struct envdev_s { uint8_t mtd_type; /* type of the MTD device */ };
+#define UBI_TYPE UCHAR_MAX + static struct envdev_s envdevices[2] = { { @@ -943,7 +947,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, continue; }
- if (mtd_type != MTD_ABSENT) { + if (mtd_type != MTD_ABSENT && mtd_type != UBI_TYPE) { erase.start = blockstart; ioctl(fd, MEMUNLOCK, &erase); /* These do not need an explicit erase cycle */ @@ -956,11 +960,21 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, } }
- if (lseek (fd, blockstart, SEEK_SET) == -1) { - fprintf (stderr, - "Seek error on %s: %s\n", - DEVNAME (dev), strerror (errno)); - return -1; + if (mtd_type == UBI_TYPE) { + uint64_t updatesize = erasesize; + if (ioctl(fd, UBI_IOCVOLUP, &updatesize) != 0) { + fprintf(stderr, + "Error updating UBI volume: %s\n", + strerror(errno)); + return -1; + } + } else { + if (lseek (fd, blockstart, SEEK_SET) == -1) { + fprintf (stderr, + "Seek error on %s: %s\n", + DEVNAME (dev), strerror (errno)); + return -1; + } }
#ifdef DEBUG @@ -973,7 +987,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, return -1; }
- if (mtd_type != MTD_ABSENT) + if (mtd_type != MTD_ABSENT && mtd_type != UBI_TYPE) ioctl(fd, MEMLOCK, &erase);
processed += erasesize; @@ -1084,6 +1098,7 @@ static int flash_read (int fd) { struct mtd_info_user mtdinfo; struct stat st; + int32_t lnum; int rc;
rc = fstat(fd, &st); @@ -1095,28 +1110,38 @@ static int flash_read (int fd)
if (S_ISCHR(st.st_mode)) { rc = ioctl(fd, MEMGETINFO, &mtdinfo); - if (rc < 0) { - fprintf(stderr, "Cannot get MTD information for %s\n", - DEVNAME(dev_current)); - return -1; + if (rc >= 0) { + if (mtdinfo.type != MTD_NORFLASH && + mtdinfo.type != MTD_NANDFLASH && + mtdinfo.type != MTD_DATAFLASH && + mtdinfo.type != MTD_UBIVOLUME) { + fprintf (stderr, + "Unsupported flash type %u on %s\n", + mtdinfo.type, DEVNAME(dev_current)); + return -1; + } + DEVTYPE(dev_current) = mtdinfo.type; + goto read; } - if (mtdinfo.type != MTD_NORFLASH && - mtdinfo.type != MTD_NANDFLASH && - mtdinfo.type != MTD_DATAFLASH && - mtdinfo.type != MTD_UBIVOLUME) { - fprintf (stderr, "Unsupported flash type %u on %s\n", - mtdinfo.type, DEVNAME(dev_current)); - return -1; + + /* Check for an UBI-type device */ + lnum = 0; + rc = ioctl(fd, UBI_IOCEBISMAP, &lnum); + if (rc >= 0) { + DEVTYPE(dev_current) = UBI_TYPE; + goto read; } + + fprintf(stderr, "Cannot get MTD information for %s\n", + DEVNAME(dev_current)); + return -1; } else { - memset(&mtdinfo, 0, sizeof(mtdinfo)); - mtdinfo.type = MTD_ABSENT; + DEVTYPE(dev_current) = MTD_ABSENT; }
- DEVTYPE(dev_current) = mtdinfo.type; - +read: rc = flash_read_buf(dev_current, fd, environment.image, CUR_ENVSIZE, - DEVOFFSET (dev_current), mtdinfo.type); + DEVOFFSET (dev_current), DEVTYPE (dev_current)); if (rc != CUR_ENVSIZE) return -1;

On Mon, May 16, 2016 at 5:07 PM, Kevin Smith kevin.smith@elecsyscorp.com wrote:
Instead of requiring gluebi to update u-boot environments from Linux, directly support writing to an UBI device. The fw_env.config file will look something like this:
Device Offset Envsize LEB Size Count /dev/ubi0_0 0 0x10000 0x1f000 1
It is important to use LEB size instead of PEB size when using UBI.
Signed-off-by: Kevin Smith kevin.smith@elecsyscorp.com Cc: Michael Heimpold mhei@heimpold.de Cc: Joe Hershberger joe.hershberger@ni.com
Seems reasonable to me.

Hello Kevin,
Sorry for the late reply
Am 17.05.2016 um 00:07 schrieb Kevin Smith:
Instead of requiring gluebi to update u-boot environments from Linux, directly support writing to an UBI device. The fw_env.config file will look something like this:
Device Offset Envsize LEB Size Count /dev/ubi0_0 0 0x10000 0x1f000 1
It is important to use LEB size instead of PEB size when using UBI.
Signed-off-by: Kevin Smith kevin.smith@elecsyscorp.com Cc: Michael Heimpold mhei@heimpold.de Cc: Joe Hershberger joe.hershberger@ni.com
tools/env/fw_env.c | 71 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 23 deletions(-)
Did you looked at the patches from Marcin. He also did such an approach here:
[U-Boot,1/2] tools: env: Fix format warnings in debug http://patchwork.ozlabs.org/patch/619306/
[U-Boot,2/2] tools: env: Add support for direct read/write UBI volumes http://patchwork.ozlabs.org/patch/619305/
I like his approach more, as with it we can also use UBI Volumes by name and the config file looks cleaner to me ...
bye, Heiko
participants (3)
-
Heiko Schocher
-
Joe Hershberger
-
Kevin Smith