فهرست منبع

env: Add support for UBI environment

UBI is a better place for the environment on NAND devices because it
handles wear-leveling and bad blocks.

Gluebi is needed in Linux to access the env as an MTD partition.

Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
Joe Hershberger 12 سال پیش
والد
کامیت
2b74433f36
6فایلهای تغییر یافته به همراه144 افزوده شده و 2 حذف شده
  1. 21 0
      README
  2. 1 0
      common/Makefile
  3. 2 1
      common/cmd_nvedit.c
  4. 103 0
      common/env_ubi.c
  5. 15 0
      include/environment.h
  6. 2 1
      tools/env/fw_env.c

+ 21 - 0
README

@@ -3548,6 +3548,27 @@ but it can not erase, write this NOR flash by SRIO or PCIE interface.
 	environment. If redundant environment is used, it will be copied to
 	environment. If redundant environment is used, it will be copied to
 	CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE.
 	CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE.
 
 
+- CONFIG_ENV_IS_IN_UBI:
+
+	Define this if you have an UBI volume that you want to use for the
+	environment.  This has the benefit of wear-leveling the environment
+	accesses, which is important on NAND.
+
+	- CONFIG_ENV_UBI_PART:
+
+	  Define this to a string that is the mtd partition containing the UBI.
+
+	- CONFIG_ENV_UBI_VOLUME:
+
+	  Define this to the name of the volume that you want to store the
+	  environment in.
+
+	- CONFIG_UBI_SILENCE_MSG
+	- CONFIG_UBIFS_SILENCE_MSG
+
+	  You will probably want to define these to avoid a really noisy system
+	  when storing the env in UBI.
+
 - CONFIG_SYS_SPI_INIT_OFFSET
 - CONFIG_SYS_SPI_INIT_OFFSET
 
 
 	Defines offset to the initial SPI buffer area in DPRAM. The
 	Defines offset to the initial SPI buffer area in DPRAM. The

+ 1 - 0
common/Makefile

@@ -66,6 +66,7 @@ COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o
 COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o
 COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o
 COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
 COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
 COBJS-$(CONFIG_ENV_IS_IN_REMOTE) += env_remote.o
 COBJS-$(CONFIG_ENV_IS_IN_REMOTE) += env_remote.o
+COBJS-$(CONFIG_ENV_IS_IN_UBI) += env_ubi.o
 COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
 COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
 
 
 # command
 # command

+ 2 - 1
common/cmd_nvedit.c

@@ -62,9 +62,10 @@ DECLARE_GLOBAL_DATA_PTR;
 	!defined(CONFIG_ENV_IS_IN_ONENAND)	&& \
 	!defined(CONFIG_ENV_IS_IN_ONENAND)	&& \
 	!defined(CONFIG_ENV_IS_IN_SPI_FLASH)	&& \
 	!defined(CONFIG_ENV_IS_IN_SPI_FLASH)	&& \
 	!defined(CONFIG_ENV_IS_IN_REMOTE)	&& \
 	!defined(CONFIG_ENV_IS_IN_REMOTE)	&& \
+	!defined(CONFIG_ENV_IS_IN_UBI)		&& \
 	!defined(CONFIG_ENV_IS_NOWHERE)
 	!defined(CONFIG_ENV_IS_NOWHERE)
 # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\
 # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\
-SPI_FLASH|NVRAM|MMC|FAT|REMOTE} or CONFIG_ENV_IS_NOWHERE
+SPI_FLASH|NVRAM|MMC|FAT|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE
 #endif
 #endif
 
 
 /*
 /*

+ 103 - 0
common/env_ubi.c

@@ -0,0 +1,103 @@
+/*
+ * (c) Copyright 2012 by National Instruments,
+ *        Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#include <command.h>
+#include <environment.h>
+#include <errno.h>
+#include <malloc.h>
+#include <search.h>
+#include <ubi_uboot.h>
+#undef crc32
+
+char *env_name_spec = "UBI";
+
+env_t *env_ptr;
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int env_init(void)
+{
+	/* use default */
+	gd->env_addr = (ulong)&default_environment[0];
+	gd->env_valid = 1;
+
+	return 0;
+}
+
+#ifdef CONFIG_CMD_SAVEENV
+int saveenv(void)
+{
+	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
+	ssize_t	len;
+	char *res;
+
+	res = (char *)&env_new->data;
+	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
+	if (len < 0) {
+		error("Cannot export environment: errno = %d\n", errno);
+		return 1;
+	}
+
+	if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
+		printf("\n** Cannot find mtd partition \"%s\"\n",
+		       CONFIG_ENV_UBI_PART);
+		return 1;
+	}
+
+	env_new->crc = crc32(0, env_new->data, ENV_SIZE);
+
+	if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
+			     CONFIG_ENV_SIZE)) {
+		printf("\n** Unable to write env to %s:%s **\n",
+		       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
+		return 1;
+	}
+
+	puts("done\n");
+	return 0;
+}
+#endif /* CONFIG_CMD_SAVEENV */
+
+void env_relocate_spec(void)
+{
+	ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
+
+	if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
+		printf("\n** Cannot find mtd partition \"%s\"\n",
+		       CONFIG_ENV_UBI_PART);
+		set_default_env(NULL);
+		return;
+	}
+
+	if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)&buf,
+			    CONFIG_ENV_SIZE)) {
+		printf("\n** Unable to read env from %s:%s **\n",
+		       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
+		set_default_env(NULL);
+		return;
+	}
+
+	env_import(buf, 1);
+}

+ 15 - 0
include/environment.h

@@ -96,6 +96,21 @@ extern unsigned long nand_env_oob_offset;
 # endif
 # endif
 #endif /* CONFIG_ENV_IS_IN_NAND */
 #endif /* CONFIG_ENV_IS_IN_NAND */
 
 
+#if defined(CONFIG_ENV_IS_IN_UBI)
+# ifndef CONFIG_ENV_UBI_PART
+#  error "Need to define CONFIG_ENV_UBI_PART when using CONFIG_ENV_IS_IN_UBI"
+# endif
+# ifndef CONFIG_ENV_UBI_VOLUME
+#  error "Need to define CONFIG_ENV_UBI_VOLUME when using CONFIG_ENV_IS_IN_UBI"
+# endif
+# ifndef CONFIG_ENV_SIZE
+#  error "Need to define CONFIG_ENV_SIZE when using CONFIG_ENV_IS_IN_UBI"
+# endif
+# ifndef CONFIG_CMD_UBI
+#  error "Need to define CONFIG_CMD_UBI when using CONFIG_ENV_IS_IN_UBI"
+# endif
+#endif /* CONFIG_ENV_IS_IN_UBI */
+
 /* Embedded env is only supported for some flash types */
 /* Embedded env is only supported for some flash types */
 #ifdef CONFIG_ENV_IS_EMBEDDED
 #ifdef CONFIG_ENV_IS_EMBEDDED
 # if	!defined(CONFIG_ENV_IS_IN_FLASH)	&& \
 # if	!defined(CONFIG_ENV_IS_IN_FLASH)	&& \

+ 2 - 1
tools/env/fw_env.c

@@ -968,7 +968,8 @@ static int flash_read (int fd)
 		}
 		}
 		if (mtdinfo.type != MTD_NORFLASH &&
 		if (mtdinfo.type != MTD_NORFLASH &&
 		    mtdinfo.type != MTD_NANDFLASH &&
 		    mtdinfo.type != MTD_NANDFLASH &&
-		    mtdinfo.type != MTD_DATAFLASH) {
+		    mtdinfo.type != MTD_DATAFLASH &&
+		    mtdinfo.type != MTD_UBIVOLUME) {
 			fprintf (stderr, "Unsupported flash type %u on %s\n",
 			fprintf (stderr, "Unsupported flash type %u on %s\n",
 				 mtdinfo.type, DEVNAME(dev_current));
 				 mtdinfo.type, DEVNAME(dev_current));
 			return -1;
 			return -1;