From cb1c4896905ab22fcd982e6a8a539f0031942e71 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Fri, 11 Apr 2008 11:07:49 +0200 Subject: [PATCH] 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 --- common/cmd_bootm.c | 37 ++++++++++++++++++++++++++----------- common/image.c | 2 +- include/image.h | 3 ++- lib_arm/bootm.c | 2 +- lib_avr32/bootm.c | 2 +- lib_blackfin/bootm.c | 2 +- lib_m68k/bootm.c | 2 +- lib_microblaze/bootm.c | 2 +- lib_mips/bootm.c | 2 +- lib_nios2/bootm.c | 2 +- lib_ppc/bootm.c | 4 ++-- lib_sh/bootm.c | 2 +- 12 files changed, 39 insertions(+), 23 deletions(-) diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 9e5ce4b38f..3a0c83d2d8 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -286,9 +286,16 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) 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 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] show_boot_progress (-5); return NULL; } + + /* + * 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; + images->legacy_hdr_valid = 1; show_boot_progress (6); break; #if defined(CONFIG_FIT) @@ -890,7 +905,7 @@ static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, * 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 @@ static void do_bootm_lynxkdi (cmd_tbl_t *cmdtp, int flag, 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 @@ static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, 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 @@ static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, 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 @@ static void do_bootm_qnxelf(cmd_tbl_t *cmdtp, int flag, { 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 @@ static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag, 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 9e63432007..d218f2f88b 100644 --- a/common/image.c +++ b/common/image.c @@ -983,7 +983,7 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, #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. diff --git a/include/image.h b/include/image.h index c1a6cbb481..60fdb2bea3 100644 --- a/include/image.h +++ b/include/image.h @@ -197,7 +197,8 @@ typedef struct bootm_headers { * then boot_get_ramdisk() and get_fdt() will attempt to get * data from second and third component accordingly. */ - image_header_t *legacy_hdr_os; + image_header_t *legacy_hdr_os; /* image header pointer */ + image_header_t legacy_hdr_os_copy; /* header copy */ ulong legacy_hdr_valid; #if defined(CONFIG_FIT) diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index c5e8cb3eb6..6b4a80723f 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -78,7 +78,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* find kernel entry point */ if (images->legacy_hdr_valid) { - ep = image_get_ep (images->legacy_hdr_os); + ep = image_get_ep (&images->legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { ret = fit_image_get_entry (images->fit_hdr_os, diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index b1c651ab2c..5ff8c79e9b 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -185,7 +185,7 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* find kernel entry point */ if (images->legacy_hdr_valid) { - ep = image_get_ep (images->legacy_hdr_os); + ep = image_get_ep (&images->legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { ret = fit_image_get_entry (images->fit_hdr_os, diff --git a/lib_blackfin/bootm.c b/lib_blackfin/bootm.c index bea11ed6dd..ef4b1127fc 100644 --- a/lib_blackfin/bootm.c +++ b/lib_blackfin/bootm.c @@ -49,7 +49,7 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* find kernel entry point */ if (images->legacy_hdr_valid) { - ep = image_get_ep (images->legacy_hdr_os); + ep = image_get_ep (&images->legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { int ret = fit_image_get_entry (images->fit_hdr_os, diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index 6f49c31616..61f1a3648a 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -96,7 +96,7 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, /* find kernel entry point */ if (images->legacy_hdr_valid) { - ep = image_get_ep (images->legacy_hdr_os); + ep = image_get_ep (&images->legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { ret = fit_image_get_entry (images->fit_hdr_os, diff --git a/lib_microblaze/bootm.c b/lib_microblaze/bootm.c index fab4a54418..30a03ef359 100644 --- a/lib_microblaze/bootm.c +++ b/lib_microblaze/bootm.c @@ -44,7 +44,7 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], /* find kernel entry point */ if (images->legacy_hdr_valid) { - ep = image_get_ep (images->legacy_hdr_os); + ep = image_get_ep (&images->legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { int ret = fit_image_get_entry (images->fit_hdr_os, diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c index e4c139efab..f813fc5831 100644 --- a/lib_mips/bootm.c +++ b/lib_mips/bootm.c @@ -57,7 +57,7 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], /* find kernel entry point */ if (images->legacy_hdr_valid) { - ep = image_get_ep (images->legacy_hdr_os); + ep = image_get_ep (&images->legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { ret = fit_image_get_entry (images->fit_hdr_os, diff --git a/lib_nios2/bootm.c b/lib_nios2/bootm.c index 0c89e96358..01f4e87cb4 100644 --- a/lib_nios2/bootm.c +++ b/lib_nios2/bootm.c @@ -34,7 +34,7 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* find kernel entry point */ if (images->legacy_hdr_valid) { - ep = image_get_ep (images->legacy_hdr_os); + ep = image_get_ep (&images->legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { int ret = fit_image_get_entry (images->fit_hdr_os, diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index b24a0640c7..0328baddca 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -146,7 +146,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* find kernel entry point */ if (images->legacy_hdr_valid) { - ep = image_get_ep (images->legacy_hdr_os); + ep = image_get_ep (&images->legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { ret = fit_image_get_entry (images->fit_hdr_os, @@ -639,7 +639,7 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], printf (" Booting using the fdt blob at 0x%x\n", fdt_blob); } 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)) { ulong fdt_data, fdt_len; diff --git a/lib_sh/bootm.c b/lib_sh/bootm.c index 3d5c3bbc95..dd32a3ed84 100644 --- a/lib_sh/bootm.c +++ b/lib_sh/bootm.c @@ -67,7 +67,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* find kernel entry point */ if (images->legacy_hdr_valid) { - ep = image_get_ep (images->legacy_hdr_os); + ep = image_get_ep (&images->legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { int ret = fit_image_get_entry (images->fit_hdr_os, -- 2.25.1