uboot/env/ubi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (c) Copyright 2012 by National Instruments,
   4 *        Joe Hershberger <joe.hershberger@ni.com>
   5 */
   6
   7#include <common.h>
   8
   9#include <command.h>
  10#include <environment.h>
  11#include <errno.h>
  12#include <malloc.h>
  13#include <memalign.h>
  14#include <search.h>
  15#include <ubi_uboot.h>
  16#undef crc32
  17
  18DECLARE_GLOBAL_DATA_PTR;
  19
  20#ifdef CONFIG_CMD_SAVEENV
  21#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  22static int env_ubi_save(void)
  23{
  24        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
  25        int ret;
  26
  27        ret = env_export(env_new);
  28        if (ret)
  29                return ret;
  30
  31        if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
  32                printf("\n** Cannot find mtd partition \"%s\"\n",
  33                       CONFIG_ENV_UBI_PART);
  34                return 1;
  35        }
  36
  37        if (gd->env_valid == ENV_VALID) {
  38                puts("Writing to redundant UBI... ");
  39                if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
  40                                     (void *)env_new, CONFIG_ENV_SIZE)) {
  41                        printf("\n** Unable to write env to %s:%s **\n",
  42                               CONFIG_ENV_UBI_PART,
  43                               CONFIG_ENV_UBI_VOLUME_REDUND);
  44                        return 1;
  45                }
  46        } else {
  47                puts("Writing to UBI... ");
  48                if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
  49                                     (void *)env_new, CONFIG_ENV_SIZE)) {
  50                        printf("\n** Unable to write env to %s:%s **\n",
  51                               CONFIG_ENV_UBI_PART,
  52                               CONFIG_ENV_UBI_VOLUME);
  53                        return 1;
  54                }
  55        }
  56
  57        puts("done\n");
  58
  59        gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND;
  60
  61        return 0;
  62}
  63#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
  64static int env_ubi_save(void)
  65{
  66        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
  67        int ret;
  68
  69        ret = env_export(env_new);
  70        if (ret)
  71                return ret;
  72
  73        if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
  74                printf("\n** Cannot find mtd partition \"%s\"\n",
  75                       CONFIG_ENV_UBI_PART);
  76                return 1;
  77        }
  78
  79        if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
  80                             CONFIG_ENV_SIZE)) {
  81                printf("\n** Unable to write env to %s:%s **\n",
  82                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
  83                return 1;
  84        }
  85
  86        puts("done\n");
  87        return 0;
  88}
  89#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
  90#endif /* CONFIG_CMD_SAVEENV */
  91
  92#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  93static int env_ubi_load(void)
  94{
  95        ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
  96        ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
  97        int read1_fail, read2_fail;
  98        env_t *tmp_env1, *tmp_env2;
  99
 100        /*
 101         * In case we have restarted u-boot there is a chance that buffer
 102         * contains old environment (from the previous boot).
 103         * If UBI volume is zero size, ubi_volume_read() doesn't modify the
 104         * buffer.
 105         * We need to clear buffer manually here, so the invalid CRC will
 106         * cause setting default environment as expected.
 107         */
 108        memset(env1_buf, 0x0, CONFIG_ENV_SIZE);
 109        memset(env2_buf, 0x0, CONFIG_ENV_SIZE);
 110
 111        tmp_env1 = (env_t *)env1_buf;
 112        tmp_env2 = (env_t *)env2_buf;
 113
 114        if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
 115                printf("\n** Cannot find mtd partition \"%s\"\n",
 116                       CONFIG_ENV_UBI_PART);
 117                set_default_env(NULL, 0);
 118                return -EIO;
 119        }
 120
 121        read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
 122                                     CONFIG_ENV_SIZE);
 123        if (read1_fail)
 124                printf("\n** Unable to read env from %s:%s **\n",
 125                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
 126
 127        read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND,
 128                                     (void *)tmp_env2, CONFIG_ENV_SIZE);
 129        if (read2_fail)
 130                printf("\n** Unable to read redundant env from %s:%s **\n",
 131                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
 132
 133        return env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
 134                                                         read2_fail);
 135}
 136#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 137static int env_ubi_load(void)
 138{
 139        ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
 140
 141        /*
 142         * In case we have restarted u-boot there is a chance that buffer
 143         * contains old environment (from the previous boot).
 144         * If UBI volume is zero size, ubi_volume_read() doesn't modify the
 145         * buffer.
 146         * We need to clear buffer manually here, so the invalid CRC will
 147         * cause setting default environment as expected.
 148         */
 149        memset(buf, 0x0, CONFIG_ENV_SIZE);
 150
 151        if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
 152                printf("\n** Cannot find mtd partition \"%s\"\n",
 153                       CONFIG_ENV_UBI_PART);
 154                set_default_env(NULL, 0);
 155                return -EIO;
 156        }
 157
 158        if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, CONFIG_ENV_SIZE)) {
 159                printf("\n** Unable to read env from %s:%s **\n",
 160                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
 161                set_default_env(NULL, 0);
 162                return -EIO;
 163        }
 164
 165        return env_import(buf, 1);
 166}
 167#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 168
 169U_BOOT_ENV_LOCATION(ubi) = {
 170        .location       = ENVL_UBI,
 171        ENV_NAME("UBI")
 172        .load           = env_ubi_load,
 173        .save           = env_save_ptr(env_ubi_save),
 174};
 175