瀏覽代碼

fix redundant environment for serial flash

This patch fixes problems in the handling of redundant environment in env_sf.c

The major problem are double calls of free() on the allocated buffers,
which damages the internal data of malloc and crashes on next call.

In addition, the selection of the active environment had errors and compiler
warnings, which are corrected by this patch.

Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
thomas.langer@lantiq.com 14 年之前
父節點
當前提交
2dc55d9ede
共有 1 個文件被更改,包括 12 次插入27 次删除
  1. 12 27
      common/env_sf.c

+ 12 - 27
common/env_sf.c

@@ -59,7 +59,6 @@ DECLARE_GLOBAL_DATA_PTR;
 extern uchar default_environment[];
 extern uchar default_environment[];
 
 
 char * env_name_spec = "SPI Flash";
 char * env_name_spec = "SPI Flash";
-env_t *env_ptr;
 
 
 static struct spi_flash *env_flash;
 static struct spi_flash *env_flash;
 
 
@@ -79,7 +78,7 @@ int saveenv(void)
 	char	*saved_buffer = NULL;
 	char	*saved_buffer = NULL;
 	u32	sector = 1;
 	u32	sector = 1;
 	int	ret;
 	int	ret;
-	char	flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG;
+	char	flag = OBSOLETE_FLAG;
 
 
 	if (!env_flash) {
 	if (!env_flash) {
 		env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS,
 		env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS,
@@ -159,7 +158,7 @@ int saveenv(void)
 
 
 	gd->env_valid = (gd->env_valid == 2 ? 1 : 2);
 	gd->env_valid = (gd->env_valid == 2 ? 1 : 2);
 
 
-	printf("Valid environment: %d\n", gd->env_valid);
+	printf("Valid environment: %d\n", (int)gd->env_valid);
 
 
  done:
  done:
 	if (saved_buffer)
 	if (saved_buffer)
@@ -174,25 +173,20 @@ void env_relocate_spec(void)
 	env_t *tmp_env1 = NULL;
 	env_t *tmp_env1 = NULL;
 	env_t *tmp_env2 = NULL;
 	env_t *tmp_env2 = NULL;
 	env_t *ep = NULL;
 	env_t *ep = NULL;
-	uchar flag1, flag2;
-	/* current_env is set only in case both areas are valid! */
-	int current_env = 0;
 
 
 	tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE);
 	tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE);
 	tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE);
 	tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE);
 
 
 	if (!tmp_env1 || !tmp_env2) {
 	if (!tmp_env1 || !tmp_env2) {
-		free(tmp_env1);
-		free(tmp_env2);
 		set_default_env("!malloc() failed");
 		set_default_env("!malloc() failed");
-		return;
+		goto out;
 	}
 	}
 
 
 	env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
 	env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
 			CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
 			CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
 	if (!env_flash) {
 	if (!env_flash) {
 		set_default_env("!spi_flash_probe() failed");
 		set_default_env("!spi_flash_probe() failed");
-		return;
+		goto out;
 	}
 	}
 
 
 	ret = spi_flash_read(env_flash, CONFIG_ENV_OFFSET,
 	ret = spi_flash_read(env_flash, CONFIG_ENV_OFFSET,
@@ -204,33 +198,30 @@ void env_relocate_spec(void)
 
 
 	if (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc)
 	if (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc)
 		crc1_ok = 1;
 		crc1_ok = 1;
-	flag1 = tmp_env1->flags;
 
 
 	ret = spi_flash_read(env_flash, CONFIG_ENV_OFFSET_REDUND,
 	ret = spi_flash_read(env_flash, CONFIG_ENV_OFFSET_REDUND,
 				CONFIG_ENV_SIZE, tmp_env2);
 				CONFIG_ENV_SIZE, tmp_env2);
 	if (!ret) {
 	if (!ret) {
 		if (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc)
 		if (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc)
 			crc2_ok = 1;
 			crc2_ok = 1;
-		flag2 = tmp_env2->flags;
 	}
 	}
 
 
 	if (!crc1_ok && !crc2_ok) {
 	if (!crc1_ok && !crc2_ok) {
-		free(tmp_env1);
-		free(tmp_env2);
 		set_default_env("!bad CRC");
 		set_default_env("!bad CRC");
-		return;
+		goto err_read;
 	} else if (crc1_ok && !crc2_ok) {
 	} else if (crc1_ok && !crc2_ok) {
 		gd->env_valid = 1;
 		gd->env_valid = 1;
-		ep = tmp_env1;
 	} else if (!crc1_ok && crc2_ok) {
 	} else if (!crc1_ok && crc2_ok) {
+		gd->env_valid = 2;
+	} else if (tmp_env1->flags == ACTIVE_FLAG &&
+		   tmp_env2->flags == OBSOLETE_FLAG) {
 		gd->env_valid = 1;
 		gd->env_valid = 1;
-	} else if (flag1 == ACTIVE_FLAG && flag2 == OBSOLETE_FLAG) {
-		gd->env_valid = 1;
-	} else if (flag1 == OBSOLETE_FLAG && flag2 == ACTIVE_FLAG) {
+	} else if (tmp_env1->flags == OBSOLETE_FLAG &&
+		   tmp_env2->flags == ACTIVE_FLAG) {
 		gd->env_valid = 2;
 		gd->env_valid = 2;
-	} else if (flag1 == flag2) {
+	} else if (tmp_env1->flags == tmp_env2->flags) {
 		gd->env_valid = 2;
 		gd->env_valid = 2;
-	} else if (flag1 == 0xFF) {
+	} else if (tmp_env1->flags == 0xFF) {
 		gd->env_valid = 2;
 		gd->env_valid = 2;
 	} else {
 	} else {
 		/*
 		/*
@@ -240,8 +231,6 @@ void env_relocate_spec(void)
 		gd->env_valid = 2;
 		gd->env_valid = 2;
 	}
 	}
 
 
-	free(env_ptr);
-
 	if (gd->env_valid == 1)
 	if (gd->env_valid == 1)
 		ep = tmp_env1;
 		ep = tmp_env1;
 	else
 	else
@@ -257,10 +246,6 @@ err_read:
 	spi_flash_free(env_flash);
 	spi_flash_free(env_flash);
 	env_flash = NULL;
 	env_flash = NULL;
 out:
 out:
-	if (tmp_env1)
-		free(tmp_env1);
-	if (tmp_env2)
-		free(tmp_env2);
 	free(tmp_env1);
 	free(tmp_env1);
 	free(tmp_env2);
 	free(tmp_env2);