uboot/common/env_ubi.c
<<
>>
Prefs
   1/*
   2 * (c) Copyright 2012 by National Instruments,
   3 *        Joe Hershberger <joe.hershberger@ni.com>
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24#include <common.h>
  25
  26#include <command.h>
  27#include <environment.h>
  28#include <errno.h>
  29#include <malloc.h>
  30#include <search.h>
  31#include <ubi_uboot.h>
  32#undef crc32
  33
  34char *env_name_spec = "UBI";
  35
  36env_t *env_ptr;
  37
  38DECLARE_GLOBAL_DATA_PTR;
  39
  40int env_init(void)
  41{
  42        /* use default */
  43        gd->env_addr = (ulong)&default_environment[0];
  44        gd->env_valid = 1;
  45
  46        return 0;
  47}
  48
  49#ifdef CONFIG_CMD_SAVEENV
  50#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  51static unsigned char env_flags;
  52
  53int saveenv(void)
  54{
  55        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
  56        ssize_t len;
  57        char *res;
  58
  59        res = (char *)&env_new->data;
  60        len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
  61        if (len < 0) {
  62                error("Cannot export environment: errno = %d\n", errno);
  63                return 1;
  64        }
  65
  66        if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
  67                printf("\n** Cannot find mtd partition \"%s\"\n",
  68                       CONFIG_ENV_UBI_PART);
  69                return 1;
  70        }
  71
  72        env_new->crc = crc32(0, env_new->data, ENV_SIZE);
  73        env_new->flags = ++env_flags; /* increase the serial */
  74
  75        if (gd->env_valid == 1) {
  76                puts("Writing to redundant UBI... ");
  77                if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
  78                                     (void *)env_new, CONFIG_ENV_SIZE)) {
  79                        printf("\n** Unable to write env to %s:%s **\n",
  80                               CONFIG_ENV_UBI_PART,
  81                               CONFIG_ENV_UBI_VOLUME_REDUND);
  82                        return 1;
  83                }
  84        } else {
  85                puts("Writing to UBI... ");
  86                if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
  87                                     (void *)env_new, CONFIG_ENV_SIZE)) {
  88                        printf("\n** Unable to write env to %s:%s **\n",
  89                               CONFIG_ENV_UBI_PART,
  90                               CONFIG_ENV_UBI_VOLUME);
  91                        return 1;
  92                }
  93        }
  94
  95        puts("done\n");
  96
  97        gd->env_valid = gd->env_valid == 2 ? 1 : 2;
  98
  99        return 0;
 100}
 101#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 102int saveenv(void)
 103{
 104        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
 105        ssize_t len;
 106        char *res;
 107
 108        res = (char *)&env_new->data;
 109        len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 110        if (len < 0) {
 111                error("Cannot export environment: errno = %d\n", errno);
 112                return 1;
 113        }
 114
 115        if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
 116                printf("\n** Cannot find mtd partition \"%s\"\n",
 117                       CONFIG_ENV_UBI_PART);
 118                return 1;
 119        }
 120
 121        env_new->crc = crc32(0, env_new->data, ENV_SIZE);
 122
 123        if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
 124                             CONFIG_ENV_SIZE)) {
 125                printf("\n** Unable to write env to %s:%s **\n",
 126                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
 127                return 1;
 128        }
 129
 130        puts("done\n");
 131        return 0;
 132}
 133#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 134#endif /* CONFIG_CMD_SAVEENV */
 135
 136#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
 137void env_relocate_spec(void)
 138{
 139        ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
 140        ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
 141        int crc1_ok = 0, crc2_ok = 0;
 142        env_t *ep, *tmp_env1, *tmp_env2;
 143
 144        tmp_env1 = (env_t *)env1_buf;
 145        tmp_env2 = (env_t *)env2_buf;
 146
 147        if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
 148                printf("\n** Cannot find mtd partition \"%s\"\n",
 149                       CONFIG_ENV_UBI_PART);
 150                set_default_env(NULL);
 151                return;
 152        }
 153
 154        if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
 155                            CONFIG_ENV_SIZE)) {
 156                printf("\n** Unable to read env from %s:%s **\n",
 157                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
 158        }
 159
 160        if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, (void *)tmp_env2,
 161                            CONFIG_ENV_SIZE)) {
 162                printf("\n** Unable to read redundant env from %s:%s **\n",
 163                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
 164        }
 165
 166        crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc;
 167        crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc;
 168
 169        if (!crc1_ok && !crc2_ok) {
 170                set_default_env("!bad CRC");
 171                return;
 172        } else if (crc1_ok && !crc2_ok) {
 173                gd->env_valid = 1;
 174        } else if (!crc1_ok && crc2_ok) {
 175                gd->env_valid = 2;
 176        } else {
 177                /* both ok - check serial */
 178                if (tmp_env1->flags == 255 && tmp_env2->flags == 0)
 179                        gd->env_valid = 2;
 180                else if (tmp_env2->flags == 255 && tmp_env1->flags == 0)
 181                        gd->env_valid = 1;
 182                else if (tmp_env1->flags > tmp_env2->flags)
 183                        gd->env_valid = 1;
 184                else if (tmp_env2->flags > tmp_env1->flags)
 185                        gd->env_valid = 2;
 186                else /* flags are equal - almost impossible */
 187                        gd->env_valid = 1;
 188        }
 189
 190        if (gd->env_valid == 1)
 191                ep = tmp_env1;
 192        else
 193                ep = tmp_env2;
 194
 195        env_flags = ep->flags;
 196        env_import((char *)ep, 0);
 197}
 198#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 199void env_relocate_spec(void)
 200{
 201        ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
 202
 203        if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
 204                printf("\n** Cannot find mtd partition \"%s\"\n",
 205                       CONFIG_ENV_UBI_PART);
 206                set_default_env(NULL);
 207                return;
 208        }
 209
 210        if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)&buf,
 211                            CONFIG_ENV_SIZE)) {
 212                printf("\n** Unable to read env from %s:%s **\n",
 213                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
 214                set_default_env(NULL);
 215                return;
 216        }
 217
 218        env_import(buf, 1);
 219}
 220#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 221