"Das U-Boot" Source Tree
at master 224 lines 5.9 kB view raw
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 <asm/global_data.h> 8 9#include <command.h> 10#include <env.h> 11#include <env_internal.h> 12#include <errno.h> 13#include <malloc.h> 14#include <memalign.h> 15#include <search.h> 16#include <ubi_uboot.h> 17#undef crc32 18 19#define _QUOTE(x) #x 20#define QUOTE(x) _QUOTE(x) 21 22#if (CONFIG_ENV_UBI_VID_OFFSET == 0) 23 #define UBI_VID_OFFSET NULL 24#else 25 #define UBI_VID_OFFSET QUOTE(CONFIG_ENV_UBI_VID_OFFSET) 26#endif 27 28DECLARE_GLOBAL_DATA_PTR; 29 30#if CONFIG_SYS_REDUNDAND_ENVIRONMENT 31#define ENV_UBI_VOLUME_REDUND CONFIG_ENV_UBI_VOLUME_REDUND 32#else 33#define ENV_UBI_VOLUME_REDUND "invalid" 34#endif 35 36#ifdef CONFIG_CMD_SAVEENV 37#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT 38static int env_ubi_save(void) 39{ 40 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); 41 int ret; 42 43 ret = env_export(env_new); 44 if (ret) 45 return ret; 46 47 if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) { 48 printf("\n** Cannot find mtd partition \"%s\"\n", 49 CONFIG_ENV_UBI_PART); 50 return 1; 51 } 52 53 if (gd->env_valid == ENV_VALID) { 54 puts("Writing to redundant UBI... "); 55 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND, 56 (void *)env_new, 0, CONFIG_ENV_SIZE)) { 57 printf("\n** Unable to write env to %s:%s **\n", 58 CONFIG_ENV_UBI_PART, 59 CONFIG_ENV_UBI_VOLUME_REDUND); 60 return 1; 61 } 62 } else { 63 puts("Writing to UBI... "); 64 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, 65 (void *)env_new, 0, CONFIG_ENV_SIZE)) { 66 printf("\n** Unable to write env to %s:%s **\n", 67 CONFIG_ENV_UBI_PART, 68 CONFIG_ENV_UBI_VOLUME); 69 return 1; 70 } 71 } 72 73 puts("done\n"); 74 75 gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND; 76 77 return 0; 78} 79#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */ 80static int env_ubi_save(void) 81{ 82 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); 83 int ret; 84 85 ret = env_export(env_new); 86 if (ret) 87 return ret; 88 89 if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) { 90 printf("\n** Cannot find mtd partition \"%s\"\n", 91 CONFIG_ENV_UBI_PART); 92 return 1; 93 } 94 95 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new, 0, 96 CONFIG_ENV_SIZE)) { 97 printf("\n** Unable to write env to %s:%s **\n", 98 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); 99 return 1; 100 } 101 102 puts("done\n"); 103 return 0; 104} 105#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ 106#endif /* CONFIG_CMD_SAVEENV */ 107 108#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT 109static int env_ubi_load(void) 110{ 111 ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE); 112 ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE); 113 int read1_fail, read2_fail; 114 env_t *tmp_env1, *tmp_env2; 115 116 /* 117 * In case we have restarted u-boot there is a chance that buffer 118 * contains old environment (from the previous boot). 119 * If UBI volume is zero size, ubi_volume_read() doesn't modify the 120 * buffer. 121 * We need to clear buffer manually here, so the invalid CRC will 122 * cause setting default environment as expected. 123 */ 124 memset(env1_buf, 0x0, CONFIG_ENV_SIZE); 125 memset(env2_buf, 0x0, CONFIG_ENV_SIZE); 126 127 tmp_env1 = (env_t *)env1_buf; 128 tmp_env2 = (env_t *)env2_buf; 129 130 if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) { 131 printf("\n** Cannot find mtd partition \"%s\"\n", 132 CONFIG_ENV_UBI_PART); 133 env_set_default(NULL, 0); 134 return -EIO; 135 } 136 137 read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1, 0, 138 CONFIG_ENV_SIZE); 139 if (read1_fail) 140 printf("\n** Unable to read env from %s:%s **\n", 141 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); 142 143 read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, 144 (void *)tmp_env2, 0, CONFIG_ENV_SIZE); 145 if (read2_fail) 146 printf("\n** Unable to read redundant env from %s:%s **\n", 147 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND); 148 149 return env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2, 150 read2_fail, H_EXTERNAL); 151} 152#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */ 153static int env_ubi_load(void) 154{ 155 ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); 156 157 /* 158 * In case we have restarted u-boot there is a chance that buffer 159 * contains old environment (from the previous boot). 160 * If UBI volume is zero size, ubi_volume_read() doesn't modify the 161 * buffer. 162 * We need to clear buffer manually here, so the invalid CRC will 163 * cause setting default environment as expected. 164 */ 165 memset(buf, 0x0, CONFIG_ENV_SIZE); 166 167 if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) { 168 printf("\n** Cannot find mtd partition \"%s\"\n", 169 CONFIG_ENV_UBI_PART); 170 env_set_default(NULL, 0); 171 return -EIO; 172 } 173 174 if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, 0, CONFIG_ENV_SIZE)) { 175 printf("\n** Unable to read env from %s:%s **\n", 176 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); 177 env_set_default(NULL, 0); 178 return -EIO; 179 } 180 181 return env_import(buf, 1, H_EXTERNAL); 182} 183#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ 184 185static int env_ubi_erase(void) 186{ 187 ALLOC_CACHE_ALIGN_BUFFER(char, env_buf, CONFIG_ENV_SIZE); 188 int ret = 0; 189 190 if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) { 191 printf("\n** Cannot find mtd partition \"%s\"\n", 192 CONFIG_ENV_UBI_PART); 193 return 1; 194 } 195 196 memset(env_buf, 0x0, CONFIG_ENV_SIZE); 197 198 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, 199 (void *)env_buf, 0, CONFIG_ENV_SIZE)) { 200 printf("\n** Unable to erase env to %s:%s **\n", 201 CONFIG_ENV_UBI_PART, 202 CONFIG_ENV_UBI_VOLUME); 203 ret = 1; 204 } 205 if (IS_ENABLED(CONFIG_SYS_REDUNDAND_ENVIRONMENT)) { 206 if (ubi_volume_write(ENV_UBI_VOLUME_REDUND, 207 (void *)env_buf, 0, CONFIG_ENV_SIZE)) { 208 printf("\n** Unable to erase env to %s:%s **\n", 209 CONFIG_ENV_UBI_PART, 210 ENV_UBI_VOLUME_REDUND); 211 ret = 1; 212 } 213 } 214 215 return ret; 216} 217 218U_BOOT_ENV_LOCATION(ubi) = { 219 .location = ENVL_UBI, 220 ENV_NAME("UBI") 221 .load = env_ubi_load, 222 .save = env_save_ptr(env_ubi_save), 223 .erase = ENV_ERASE_PTR(env_ubi_erase), 224};