Hi! I've first sent this on Feb 17, 2007. Unfortunately no reply was received. I think this is a quite useful feature, since a compile time offset into the NAND flash for the environment just doesn't work well with bad blocks ;)
This is the current version of the patch. I'd love to see it included. Thanks! --- This patch adds support for CFG_ENV_OFFSET_PATCHED and CFG_ENV_OFFSET_OOB. Both try to solve the problem of fixing the environment location in NAND flash at compile time, which doesn't work well if the NAND flash has a bad block at exactly that location. CFG_ENV_OFFSET_PATCHED puts the environment in a global variable. You can then use the linker script to put that variable to a fixed location in the u-boot image. Then you can use bianry patching during the production flash process. The idea of CFG_ENV_OFFSET_OOB is to store the environment offset in the NAND OOB data of block 0. We can do this in case the vendor makes a guarantee that block 0 never is a factory-default bad block. Signed-off-by: Harald Welte <[EMAIL PROTECTED]> Index: u-boot/common/Makefile =================================================================== --- u-boot.orig/common/Makefile +++ u-boot/common/Makefile @@ -55,6 +55,7 @@ COBJS-$(CONFIG_CMD_DISPLAY) += cmd_display.o COBJS-$(CONFIG_CMD_DOC) += cmd_doc.o COBJS-$(CONFIG_CMD_DTT) += cmd_dtt.o +COBJS-y += cmd_dynenv.o COBJS-y += cmd_eeprom.o COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o Index: u-boot/common/cmd_dynenv.c =================================================================== --- /dev/null +++ u-boot/common/cmd_dynenv.c @@ -0,0 +1,106 @@ +/* + * (C) Copyright 2006-2007 OpenMoko, Inc. + * Author: Harald Welte <[EMAIL PROTECTED]> + * + * 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 <malloc.h> +#include <environment.h> +#include <nand.h> +#include <asm/errno.h> +#include "cmd_nand.h" + +#if defined(CFG_ENV_OFFSET_OOB) + +int do_dynenv(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + struct mtd_info *mtd = &nand_info[0]; + int ret, size = 8; + uint8_t *buf; + + char *cmd = argv[1]; + + buf = malloc(mtd->oobsize); + if (!buf) + return -ENOMEM; + + ret = mtd->read_oob(mtd, 8, size, (size_t *) &size, (u_char *) buf); + if (!strcmp(cmd, "get")) { + + if (buf[0] == 'E' && buf[1] == 'N' && + buf[2] == 'V' && buf[3] == '0') + printf("0x%08x\n", *((u_int32_t *) &buf[4])); + else + printf("No dynamic environment marker in OOB block 0\n"); + + } else if (!strcmp(cmd, "set")) { + unsigned long addr, dummy; + + if (argc < 3) + goto usage; + + buf[0] = 'E'; + buf[1] = 'N'; + buf[2] = 'V'; + buf[3] = '0'; + + if (arg_off_size(argc-2, argv+2, mtd, &addr, &dummy) < 0) { + printf("Offset or partition name expected\n"); + goto fail; + } + if (!ret) { + uint8_t tmp[4]; + int i; + + memcpy(&tmp, &addr, 4); + for (i = 0; i != 4; i++) + if (tmp[i] & ~buf[i+4]) { + printf("ERROR: erase OOB block to " + "write this value\n"); + goto fail; + } + } + memcpy(buf+4, &addr, 4); + + printf("%02x %02x %02x %02x - %02x %02x %02x %02x\n", + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7]); + + ret = mtd->write_oob(mtd, 8, size, (size_t *) &size, (u_char *) buf); + if (!ret) + CFG_ENV_OFFSET = addr; + } else + goto usage; + + free(buf); + return ret; + +usage: + printf("Usage:\n%s\n", cmdtp->usage); +fail: + free(buf); + return 1; +} + +U_BOOT_CMD(dynenv, 3, 1, do_dynenv, + "dynenv - dynamically placed (NAND) environment\n", + "dynenv set off - set enviromnent offset\n" + "dynenv get - get environment offset\n"); + +#endif /* CFG_ENV_OFFSET_OOB */ Index: u-boot/common/env_nand.c =================================================================== --- u-boot.orig/common/env_nand.c +++ u-boot/common/env_nand.c @@ -292,6 +292,33 @@ int crc1_ok = 0, crc2_ok = 0; env_t *tmp_env1, *tmp_env2; +#if defined(CFG_ENV_OFFSET_OOB) + struct mtd_info *mtd = &nand_info[0]; + struct nand_chip *this = mtd->priv; + int buf_len; + uint8_t *buf; + + buf_len = (1 << this->bbt_erase_shift); + buf_len += (buf_len >> this->page_shift) * mtd->oobsize; + buf = malloc(buf_len); + if (!buf) + return; + + nand_read_raw(mtd, buf, 0, mtd->oobblock, mtd->oobsize); + if (buf[mtd->oobblock + 8 + 0] == 'E' && + buf[mtd->oobblock + 8 + 1] == 'N' && + buf[mtd->oobblock + 8 + 2] == 'V' && + buf[mtd->oobblock + 8 + 3] == '0') { + CFG_ENV_OFFSET = *((unsigned long *) &buf[mtd->oobblock + 8 + 4]); + /* fall through to the normal environment reading code below */ + free(buf); + puts("Found Environment offset in OOB..\n"); + } else { + free(buf); + return use_default(); + } +#endif + total = CFG_ENV_SIZE; tmp_env1 = (env_t *) malloc(CFG_ENV_SIZE); Index: u-boot/common/environment.c =================================================================== --- u-boot.orig/common/environment.c +++ u-boot/common/environment.c @@ -29,6 +29,12 @@ #undef __ASSEMBLY__ #include <environment.h> +#if defined(CFG_ENV_OFFSET_PATCHED) +unsigned long env_offset = CFG_ENV_OFFSET_PATCHED; +#elif defined(CFG_ENV_OFFSET_OOB) +unsigned long env_offset = CFG_ENV_OFFSET_OOB; +#endif + /* * Handle HOSTS that have prepended * crap on symbol names, not TARGETS. Index: u-boot/include/environment.h =================================================================== --- u-boot.orig/include/environment.h +++ u-boot/include/environment.h @@ -70,6 +70,10 @@ #endif /* CFG_ENV_IS_IN_FLASH */ #if defined(CFG_ENV_IS_IN_NAND) +#if defined(CFG_ENV_OFFSET_PATCHED) || defined(CFG_ENV_OFFSET_OOB) +extern unsigned long env_offset; +#define CFG_ENV_OFFSET env_offset +#else # ifndef CFG_ENV_OFFSET # error "Need to define CFG_ENV_OFFSET when using CFG_ENV_IS_IN_NAND" # endif @@ -82,6 +86,7 @@ # ifdef CFG_ENV_IS_EMBEDDED # define ENV_IS_EMBEDDED 1 # endif +#endif /* CFG_ENV_NAND_PATCHED */ #endif /* CFG_ENV_IS_IN_NAND */ #ifdef USE_HOSTCC Index: u-boot/common/cmd_nand.h =================================================================== --- /dev/null +++ u-boot/common/cmd_nand.h @@ -0,0 +1,33 @@ +/* + * cmd_nand.h - Convenience functions + * + * (C) Copyright 2006-2007 OpenMoko, Inc. + * Author: Werner Almesberger <[EMAIL PROTECTED]> + * + * 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 + */ + +#ifndef CMD_NAND_H +#define CMD_NAND_H + +#include <nand.h> + + +/* common/cmd_nand.c */ +int arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, + ulong *size); + +#endif /* CMD_NAND_H */ Index: u-boot/common/cmd_nand.c =================================================================== --- u-boot.orig/common/cmd_nand.c +++ u-boot/common/cmd_nand.c @@ -90,7 +90,7 @@ return (*p != '\0' && *endptr == '\0') ? 1 : 0; } -static int +int arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, size_t *size) { int idx = nand_curr_device; -- - Harald Welte <[EMAIL PROTECTED]> http://openmoko.org/ ============================================================================ Software for the world's first truly open Free Software mobile phone ------------------------------------------------------------------------- Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW! Studies have shown that voting for your favorite open source project, along with a healthy diet, reduces your potential for chronic lameness and boredom. Vote Now at http://www.sourceforge.net/community/cca08 _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users