[U-Boot] [RFC] tools/env: Support UBI devices
Kevin Smith
kevin.smith at elecsyscorp.com
Tue May 17 00:07:34 CEST 2016
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 at elecsyscorp.com>
Cc: Michael Heimpold <mhei at heimpold.de>
Cc: Joe Hershberger <joe.hershberger at 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;
--
2.8.0
More information about the U-Boot
mailing list