diff mbox

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

Message ID 1463436437-15254-1-git-send-email-kevin.smith@elecsyscorp.com
State RFC
Delegated to: Heiko Schocher
Headers show

Commit Message

Kevin Smith May 16, 2016, 10:07 p.m. UTC
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(-)

Comments

Joe Hershberger May 24, 2016, 3:27 p.m. UTC | #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.
Heiko Schocher June 1, 2016, 5:07 a.m. UTC | #2
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
diff mbox

Patch

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;