[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