Restore the ability to continue booting after legacy image overwrite
Before new uImage code was merged, bootm code allowed for the kernel image to
get overwritten during decompresion. new uImage introduced a check for image
overwrites and refused to boot the image that got overwritten. This patch
restores the old behavior. It also adds a warning when the image overwriten is
a multi-image file, because in such case accessing componentes other than the
first one will fail.
Signed-off-by: Marian Balakowicz <m8@semihalf.com>
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 9e5ce4b..3a0c83d 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -286,9 +286,16 @@
debug ("image_start = 0x%lX, image_end = 0x%lx\n", image_start, image_end);
debug ("load_start = 0x%lx, load_end = 0x%lx\n", load_start, load_end);
- puts ("ERROR: image overwritten - must RESET the board to recover.\n");
- show_boot_progress (-113);
- do_reset (cmdtp, flag, argc, argv);
+ if (images.legacy_hdr_valid) {
+ if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
+ puts ("WARNING: legacy format multi component "
+ "image overwritten\n");
+ } else {
+ puts ("ERROR: new format image overwritten - "
+ "must RESET the board to recover\n");
+ show_boot_progress (-113);
+ do_reset (cmdtp, flag, argc, argv);
+ }
}
show_boot_progress (8);
@@ -533,9 +540,17 @@
show_boot_progress (-5);
return NULL;
}
- images->legacy_hdr_os = hdr;
- images->legacy_hdr_valid = 1;
+ /*
+ * copy image header to allow for image overwrites during kernel
+ * decompression.
+ */
+ memmove (&images->legacy_hdr_os_copy, hdr, sizeof(image_header_t));
+
+ /* save pointer to image header */
+ images->legacy_hdr_os = hdr;
+
+ images->legacy_hdr_valid = 1;
show_boot_progress (6);
break;
#if defined(CONFIG_FIT)
@@ -890,7 +905,7 @@
* address of the original image header.
*/
os_hdr = NULL;
- if (image_check_type (hdr, IH_TYPE_MULTI)) {
+ if (image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
image_multi_getimg (hdr, 1, &kernel_data, &kernel_len);
if (kernel_len)
os_hdr = hdr;
@@ -947,7 +962,7 @@
int argc, char *argv[],
bootm_headers_t *images)
{
- image_header_t *hdr = images->legacy_hdr_os;
+ image_header_t *hdr = &images->legacy_hdr_os_copy;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
@@ -964,7 +979,7 @@
int argc, char *argv[],
bootm_headers_t *images)
{
- image_header_t *hdr = images->legacy_hdr_os;
+ image_header_t *hdr = &images->legacy_hdr_os_copy;
void (*entry_point)(bd_t *);
#if defined(CONFIG_FIT)
@@ -994,10 +1009,10 @@
bootm_headers_t *images)
{
char str[80];
- image_header_t *hdr = images->legacy_hdr_os;
+ image_header_t *hdr = &images->legacy_hdr_os_copy;
#if defined(CONFIG_FIT)
- if (hdr == NULL) {
+ if (!images->legacy_hdr_valid) {
fit_unsupported_reset ("VxWorks");
do_reset (cmdtp, flag, argc, argv);
}
@@ -1014,7 +1029,7 @@
{
char *local_args[2];
char str[16];
- image_header_t *hdr = images->legacy_hdr_os;
+ image_header_t *hdr = &images->legacy_hdr_os_copy;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
@@ -1041,7 +1056,7 @@
int i, j, nxt, len, envno, envsz;
bd_t *kbd;
void (*entry)(bd_t *bd, char *cmdline, char **fwenv, ulong top);
- image_header_t *hdr = images->legacy_hdr_os;
+ image_header_t *hdr = &images->legacy_hdr_os_copy;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
diff --git a/common/image.c b/common/image.c
index 9e63432..d218f2f 100644
--- a/common/image.c
+++ b/common/image.c
@@ -983,7 +983,7 @@
#endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */
} else if (images->legacy_hdr_valid &&
- image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) {
+ image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
/*
* Now check if we have a legacy mult-component image,
* get second entry data start address and len.