uboot-envtools: add support for environment in ubi volume
authorblogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Mon, 2 Jun 2014 12:44:19 +0000 (12:44 +0000)
committerblogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Mon, 2 Jun 2014 12:44:19 +0000 (12:44 +0000)
On UBI enabled devices, U-Boot might store it's environment on
UBI volume(s). Support this in uboot-envtools, so fw_setenv and
fw_printenv can work on these platforms.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@40929 3c298f89-4303-0410-b956-a3cf2f4a3e73

package/boot/uboot-envtools/Config.in [new file with mode: 0644]
package/boot/uboot-envtools/Makefile
package/boot/uboot-envtools/patches/300-support-env-in-ubivol-chardev.patch [new file with mode: 0644]

diff --git a/package/boot/uboot-envtools/Config.in b/package/boot/uboot-envtools/Config.in
new file mode 100644 (file)
index 0000000..9fd8103
--- /dev/null
@@ -0,0 +1,9 @@
+config UBOOT_ENVTOOLS_UBI
+       bool "Support environment in UBI volume"
+       depends on PACKAGE_uboot-envtools
+       default n
+       help
+               Add support for reading and writing U-Boot environment
+               stored in UBI volume(s).
+
+               Increases binary size by about 8 kB
index 9f167ed..dad971a 100644 (file)
@@ -21,6 +21,8 @@ PKG_MD5SUM:=6d2116d1385a66e9a59742caa9d62a54
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/u-boot-$(PKG_VERSION)
 
+PKG_BUILD_DEPENDS:=+fstools
+
 include $(INCLUDE_DIR)/package.mk
 
 define Package/uboot-envtools
@@ -34,15 +36,22 @@ define Package/uboot-envtools/description
  This package includes tools to read and modify U-Boot bootloader environment.
 endef
 
+define Package/uboot-envtools/config
+       source "$(SOURCE)/Config.in"
+endef
+
 define Build/Configure
        touch $(PKG_BUILD_DIR)/include/config.mk
        touch $(PKG_BUILD_DIR)/include/config.h
 endef
 
+TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
+
 define Build/Compile
        $(MAKE) -C $(PKG_BUILD_DIR) \
                CROSS_COMPILE="$(TARGET_CROSS)" \
                TARGET_CFLAGS="$(TARGET_CFLAGS)" \
+               UBI="$(CONFIG_UBOOT_ENVTOOLS_UBI)" \
                env
 endef
 
diff --git a/package/boot/uboot-envtools/patches/300-support-env-in-ubivol-chardev.patch b/package/boot/uboot-envtools/patches/300-support-env-in-ubivol-chardev.patch
new file mode 100644 (file)
index 0000000..96a95f7
--- /dev/null
@@ -0,0 +1,166 @@
+From ee2c9e3aef32c05b1d7891858baff19bffed1652 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 19 May 2014 21:38:01 +0200
+Subject: [PATCH] tools/env: add support for env in ubi volume chardev
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ tools/env/Makefile |  5 ++++
+ tools/env/fw_env.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++--------
+ 2 files changed, 69 insertions(+), 10 deletions(-)
+
+diff --git a/tools/env/Makefile b/tools/env/Makefile
+index f5368bc..d006a93 100644
+--- a/tools/env/Makefile
++++ b/tools/env/Makefile
+@@ -20,6 +20,11 @@ ifeq ($(MTD_VERSION),old)
+ HOST_EXTRACFLAGS += -DMTD_OLD
+ endif
++ifeq ($(UBI),y)
++HOST_EXTRACFLAGS += -DUBI
++HOST_LOADLIBES = "-Wl,--gc-sections,-lubi-utils"
++endif
++
+ always := fw_printenv
+ hostprogs-y := fw_printenv_unstripped
+diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
+index 30d5b03..5c0acd5 100644
+--- a/tools/env/fw_env.c
++++ b/tools/env/fw_env.c
+@@ -29,6 +29,9 @@
+ # include <mtd/mtd-user.h>
+ #endif
++#ifdef UBI
++# include <libubi.h>
++#endif
+ #include "fw_env.h"
+ #include <aes.h>
+@@ -809,6 +812,11 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
+       off_t top_of_range;     /* end of the last block we may use */
+       loff_t blockstart;      /* running start of the current block -
+                                  MEMGETBADBLOCK needs 64 bits */
++#ifdef UBI
++      libubi_t *libubi = NULL;/* pointer to libubi struct */
++#else
++      void *libubi = NULL;
++#endif
+       int rc;
+       /*
+@@ -914,7 +922,30 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
+                       continue;
+               }
+-              if (mtd_type != MTD_ABSENT) {
++#ifdef UBI
++              if (mtd_type == MTD_UBIVOLUME) {
++                      struct ubi_vol_info volinfo;
++                      libubi = libubi_open();
++                      if (libubi)
++                              rc = ubi_get_vol_info(libubi,
++                                      DEVNAME(dev_current), &volinfo);
++                      if (libubi && !rc) {
++                              erasesize = volinfo.leb_size;
++                              int leb = blockstart / erasesize;
++                              if (volinfo.type != UBI_STATIC_VOLUME)
++                                      rc = ubi_leb_change_start(libubi, fd,
++                                              leb, erasesize);
++                              else
++                                      rc = ubi_update_start(libubi, fd,
++                                              erasesize);
++                      }
++                      if (libubi && rc) {
++                              libubi_close(libubi);
++                              libubi = NULL;
++                      }
++              }
++#endif
++              if (!libubi && mtd_type != MTD_ABSENT) {
+                       erase.start = blockstart;
+                       ioctl(fd, MEMUNLOCK, &erase);
+                       /* These do not need an explicit erase cycle */
+@@ -931,7 +962,8 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
+                       fprintf (stderr,
+                                "Seek error on %s: %s\n",
+                                DEVNAME (dev), strerror (errno));
+-                      return -1;
++                      processed = -1;
++                      goto out;
+               }
+ #ifdef DEBUG
+@@ -941,10 +973,11 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
+               if (write (fd, data + processed, erasesize) != erasesize) {
+                       fprintf (stderr, "Write error on %s: %s\n",
+                                DEVNAME (dev), strerror (errno));
+-                      return -1;
++                      processed = -1;
++                      goto out;
+               }
+-              if (mtd_type != MTD_ABSENT)
++              if (!libubi && mtd_type != MTD_ABSENT)
+                       ioctl(fd, MEMLOCK, &erase);
+               processed  += erasesize;
+@@ -955,6 +988,9 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
+       if (write_total > count)
+               free (data);
++out:
++      if (libubi)
++              libubi_close(libubi);
+       return processed;
+ }
+@@ -1066,12 +1102,8 @@ 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 (mtdinfo.type != MTD_NORFLASH &&
++              if (!rc &&
++                  mtdinfo.type != MTD_NORFLASH &&
+                   mtdinfo.type != MTD_NANDFLASH &&
+                   mtdinfo.type != MTD_DATAFLASH &&
+                   mtdinfo.type != MTD_UBIVOLUME) {
+@@ -1079,6 +1111,28 @@ static int flash_read (int fd)
+                                mtdinfo.type, DEVNAME(dev_current));
+                       return -1;
+               }
++#ifdef UBI
++              if (rc) {
++                      libubi_t *libubi;
++                      struct ubi_vol_info volinfo;
++                      libubi = libubi_open();
++                      if (!libubi)
++                              return -ENOMEM;
++
++                      rc = ubi_get_vol_info(libubi, DEVNAME(dev_current),
++                                              &volinfo);
++                      if (rc) {
++                              libubi_close(libubi);
++                              return -ENODEV;
++                      }
++                      memset(&mtdinfo, 0, sizeof(mtdinfo));
++                      mtdinfo.type = MTD_UBIVOLUME;
++                      mtdinfo.size = volinfo.data_bytes;
++                      mtdinfo.erasesize = volinfo.leb_size;
++                      mtdinfo.writesize = volinfo.leb_size;
++                      libubi_close(libubi);
++              }
++#endif
+       } else {
+               memset(&mtdinfo, 0, sizeof(mtdinfo));
+               mtdinfo.type = MTD_ABSENT;
+-- 
+1.9.2
+