[U-Boot-Users] [PATCH 00/13] new uImage patchset1 - cleanup

This is a first set of patches that provides a initial cleanup and code rearrangements before the proper new uImage format implementation.
API is defined for the current (old) image related processing, and it'is being introduced in place of the direct header access.
[new uImage] Return error on image move/uncompress overwrites [new uImage] Cleanup image header pointer use in bootm code [new uImage] Coding style cleanup - part 1 [new uImage] Add memmove_wd() common routine [new uImage] Fix FDT header verification in PPC do_boot_linux() routine [new uImage] Fix uImage header pointer use in i386 do_bootm_linux() [new uImage] Remove I386 uImage fake_header() routine [new uImage] Move CHUNKSZ definition to image.h [new uImage] Move gunzip() common code to common/gunzip.c [new uImage] Cleanup OF/FDT #if/#elif/#endif use in do_bootm_linux() [new uImage] Move PPC do_bootm_linux() to lib_ppc/ppc_linux.c [new uImage] Define a API for image handling operations Add missing cmd_ximg.o to common/Makefile
Comments and suggestions are welcome.
Due to a 40K message limit, not all of the patches can be sent to ml, oversized patches will provide a http location instead.
Cheers, Marian

Signed-off-by: Marian Balakowicz m8@semihalf.com ---
common/Makefile | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/common/Makefile b/common/Makefile index ace8cc7..7554eae 100644 --- a/common/Makefile +++ b/common/Makefile @@ -88,6 +88,7 @@ COBJS-$(CONFIG_CMD_SCSI) += cmd_scsi.o COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o COBJS-$(CONFIG_CMD_USB) += cmd_usb.o +COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-y += cmd_vfd.o COBJS-y += command.o COBJS-y += console.o

- Add inline helper macros for basic header processing - Move common non inline code common/image.c - Replace direct header access with the API routines - Rename IH_CPU_* to IH_ARCH_*
Signed-off-by: Marian Balakowicz m8@semihalf.com ---
Makefile | 3 board/cray/L1/L1.c | 4 board/esd/common/auto_update.c | 73 ++++---- board/mcc200/auto_update.c | 71 ++++---- board/mpl/common/common_util.c | 37 ++-- board/siemens/common/fpga.c | 32 +--- board/trab/auto_update.c | 82 ++++----- common/Makefile | 1 common/cmd_autoscript.c | 30 +-- common/cmd_bootm.c | 331 +++++++++++++------------------------ common/cmd_doc.c | 4 common/cmd_fdc.c | 6 - common/cmd_fpga.c | 8 - common/cmd_ide.c | 12 - common/cmd_nand.c | 12 + common/cmd_scsi.c | 12 - common/cmd_usb.c | 12 - common/cmd_ximg.c | 36 +--- common/image.c | 91 ++++++++++ common/lynxkdi.c | 8 - include/image.h | 174 +++++++++++++++++-- lib_arm/armlinux.c | 45 ++--- lib_avr32/avr32_linux.c | 47 ++--- lib_blackfin/bf533_linux.c | 3 lib_i386/i386_linux.c | 44 ++--- lib_i386/zimage.c | 33 ++-- lib_m68k/m68k_linux.c | 62 ++----- lib_microblaze/microblaze_linux.c | 39 ++-- lib_mips/mips_linux.c | 41 ++--- lib_nios2/nios_linux.c | 2 tools/Makefile | 11 + tools/mkimage.c | 180 ++++++++------------ tools/mkimage.h | 59 +++++++ 33 files changed, 809 insertions(+), 796 deletions(-) create mode 100644 common/image.c create mode 100644 tools/mkimage.h
This patch size is over 40K list limit, please refer to: http://semihalf.com/~m8/new-image/patchset1/02-old-api.patch

Dear Marian,
in message 20080111142800.8025.66590.stgit@hekate.izotz.org you wrote:
- Add inline helper macros for basic header processing
- Move common non inline code common/image.c
- Replace direct header access with the API routines
- Rename IH_CPU_* to IH_ARCH_*
Signed-off-by: Marian Balakowicz m8@semihalf.com
I tried to apply your patches to the u-boot-testing repository; unfortunately, this does now work:
-> git-am -3 -i -u --whitespace=strip ~/Mail/U-Boot/13330 Commit Body is: -------------------------- Define a API for image handling operations
- Add inline helper macros for basic header processing - Move common non inline code common/image.c - Replace direct header access with the API routines - Rename IH_CPU_* to IH_ARCH_*
Signed-off-by: Marian Balakowicz m8@semihalf.com -------------------------- Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all y
Applying Define a API for image handling operations
error: No changes Using index info to reconstruct a base tree... error: No changes Did you hand edit your patch? It does not apply to blobs recorded in its index. Cannot fall back to three-way merge. Patch failed at 0001. When you have resolved this problem run "git-am -i -3 --resolved". If you would prefer to skip this patch, instead run "git-am -i -3 --skip".
Can you please check and - if necessary - rebase the patch set?
Thanks.
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
in message 20080111142800.8025.66590.stgit@hekate.izotz.org you wrote:
- Add inline helper macros for basic header processing
- Move common non inline code common/image.c
- Replace direct header access with the API routines
- Rename IH_CPU_* to IH_ARCH_*
Signed-off-by: Marian Balakowicz m8@semihalf.com
I tried to apply your patches to the u-boot-testing repository; unfortunately, this does now work:
-> git-am -3 -i -u --whitespace=strip ~/Mail/U-Boot/13330 Commit Body is:
Define a API for image handling operations
- Add inline helper macros for basic header processing
- Move common non inline code common/image.c
- Replace direct header access with the API routines
- Rename IH_CPU_* to IH_ARCH_*
Signed-off-by: Marian Balakowicz m8@semihalf.com
Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all y
Applying Define a API for image handling operations
error: No changes Using index info to reconstruct a base tree... error: No changes Did you hand edit your patch? It does not apply to blobs recorded in its index. Cannot fall back to three-way merge. Patch failed at 0001. When you have resolved this problem run "git-am -i -3 --resolved". If you would prefer to skip this patch, instead run "git-am -i -3 --skip".
Can you please check and - if necessary - rebase the patch set?
The baseline was "Release v1.3.1" commit, I'll rebase to current HEAD as there are some conflicts with the latest commits.
But from the above it seems that you were attempting to apply patch 02/13 for which patch body was not posted to the ml?
Cheers, m.

In message 478C8C66.5000501@semihalf.com you wrote:
The baseline was "Release v1.3.1" commit, I'll rebase to current HEAD as there are some conflicts with the latest commits.
thanks.
But from the above it seems that you were attempting to apply patch 02/13 for which patch body was not posted to the ml?
Yes, but you gave us an URL where I downloaded the missing pieces from...
[A repository on pollux would be easier for me, of course.]
Best regards,
Wolfgang Denk

In message 20080111142800.8025.66590.stgit@hekate.izotz.org you wrote:
This patch size is over 40K list limit, please refer to: http://semihalf.com/~m8/new-image/patchset1/02-old-api.patch
Please *post* patches; I will let reasonable patches through; the hard limit is 100 KiB.
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
In message 20080111142800.8025.66590.stgit@hekate.izotz.org you wrote:
This patch size is over 40K list limit, please refer to: http://semihalf.com/~m8/new-image/patchset1/02-old-api.patch
Please *post* patches; I will let reasonable patches through; the hard limit is 100 KiB.
Will do. Although patch 02/13 was over 100KiB...
Best Regards, m.

In message 20080111142800.8025.66590.stgit@hekate.izotz.org you wrote:
- Add inline helper macros for basic header processing
- Move common non inline code common/image.c
- Replace direct header access with the API routines
- Rename IH_CPU_* to IH_ARCH_*
Please review your patches and make sure to keep the original for- matting of the U-Boot output; for example:
--- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c ... - if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { - puts (" Bad Data CRC\n"); - } - puts ("OK\n"); + if (!image_check_dcrc(hdr)) + puts ("Bad Data CRC\n");
This is IMO a change to the worse. Please fix.
--- a/include/image.h +++ b/include/image.h ... +char *strncpy(char *dest, const char *src, size_t count);
Please don't do this! Include the appropriate header file instead.
+static inline int image_check_target_arch(image_header_t *hdr)
Theoretical thought: could it ever happen that we might have a multi-architecture image?
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
In message 20080111142800.8025.66590.stgit@hekate.izotz.org you wrote:
- Add inline helper macros for basic header processing
- Move common non inline code common/image.c
- Replace direct header access with the API routines
- Rename IH_CPU_* to IH_ARCH_*
Please review your patches and make sure to keep the original for- matting of the U-Boot output; for example:
[snip]
--- a/include/image.h +++ b/include/image.h ... +char *strncpy(char *dest, const char *src, size_t count);
Please don't do this! Include the appropriate header file instead.
Will fix.
+static inline int image_check_target_arch(image_header_t *hdr)
Theoretical thought: could it ever happen that we might have a multi-architecture image?
With the new uImage that would be possible, each component image will have it's own arch/os properties.
The above routine (handling current image format which does not allow multi arch images) checks whether image arch matches target arch.
It is a reasonable check, running other arch images usually make little sens. That would also apply for new uImage format, we may have multiple component images (each for different arch) but before running selected image we check for arch compatibility.
Cheers, m.

PPC implementation of do_bootm_linux() routine is moved to a dedicated file lib_ppc/ppc_linux.c
Signed-off-by: Marian Balakowicz m8@semihalf.com ---
common/cmd_bootm.c | 543 ----------------------------------------------- lib_ppc/Makefile | 3 lib_ppc/ppc_linux.c | 589 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 592 insertions(+), 543 deletions(-) create mode 100644 lib_ppc/ppc_linux.c
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index ba07e4e..a4952fd 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -58,14 +58,6 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #include <hush.h> #endif
-#ifdef CFG_INIT_RAM_LOCK -#include <asm/cache.h> -#endif - -#ifdef CONFIG_LOGBUFFER -#include <logbuff.h> -#endif - #ifdef CONFIG_HAS_DATAFLASH #include <dataflash.h> #endif @@ -112,15 +104,8 @@ typedef void boot_os_Fcn (cmd_tbl_t *cmdtp, int flag, ulong *len_ptr, /* multi-file image length table */ int verify); /* getenv("verify")[0] != 'n' */
-#ifdef DEBUG -extern int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); -#endif - -#ifdef CONFIG_PPC -static boot_os_Fcn do_bootm_linux; -#else extern boot_os_Fcn do_bootm_linux; -#endif + #ifdef CONFIG_SILENT_CONSOLE static void fixup_silent_linux (void); #endif @@ -475,532 +460,6 @@ fixup_silent_linux () } #endif /* CONFIG_SILENT_CONSOLE */
-#ifdef CONFIG_PPC -static void __attribute__((noinline)) -do_bootm_linux (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, - ulong *len_ptr, - int verify) -{ - ulong sp; - ulong len; - ulong initrd_start, initrd_end; - ulong cmd_start, cmd_end; - ulong initrd_high; - ulong data; - int initrd_copy_to_ram = 1; - char *cmdline; - char *s; - bd_t *kbd; - void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); - image_header_t *hdr = &header; -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - char *of_flat_tree = NULL; - ulong of_data = 0; -#endif - - if ((s = getenv ("initrd_high")) != NULL) { - /* a value of "no" or a similar string will act like 0, - * turning the "load high" feature off. This is intentional. - */ - initrd_high = simple_strtoul(s, NULL, 16); - if (initrd_high == ~0) - initrd_copy_to_ram = 0; - } else { /* not set, no restrictions to load high */ - initrd_high = ~0; - } - -#ifdef CONFIG_LOGBUFFER - kbd=gd->bd; - /* Prevent initrd from overwriting logbuffer */ - if (initrd_high < (kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD)) - initrd_high = kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD; - debug ("## Logbuffer at 0x%08lX ", kbd->bi_memsize-LOGBUFF_LEN); -#endif - - /* - * Booting a (Linux) kernel image - * - * Allocate space for command line and board info - the - * address should be as high as possible within the reach of - * the kernel (see CFG_BOOTMAPSZ settings), but in unused - * memory, which means far enough below the current stack - * pointer. - */ - - asm( "mr %0,1": "=r"(sp) : ); - - debug ("## Current stack ends at 0x%08lX ", sp); - - sp -= 2048; /* just to be sure */ - if (sp > CFG_BOOTMAPSZ) - sp = CFG_BOOTMAPSZ; - sp &= ~0xF; - - debug ("=> set upper limit to 0x%08lX\n", sp); - - cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF); - kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); - - if ((s = getenv("bootargs")) == NULL) - s = ""; - - strcpy (cmdline, s); - - cmd_start = (ulong)&cmdline[0]; - cmd_end = cmd_start + strlen(cmdline); - - *kbd = *(gd->bd); - -#ifdef DEBUG - printf ("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); - - do_bdinfo (NULL, 0, 0, NULL); -#endif - - if ((s = getenv ("clocks_in_mhz")) != NULL) { - /* convert all clock information to MHz */ - kbd->bi_intfreq /= 1000000L; - kbd->bi_busfreq /= 1000000L; -#if defined(CONFIG_MPC8220) - kbd->bi_inpfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; - kbd->bi_pevfreq /= 1000000L; - kbd->bi_flbfreq /= 1000000L; - kbd->bi_vcofreq /= 1000000L; -#endif -#if defined(CONFIG_CPM2) - kbd->bi_cpmfreq /= 1000000L; - kbd->bi_brgfreq /= 1000000L; - kbd->bi_sccfreq /= 1000000L; - kbd->bi_vco /= 1000000L; -#endif -#if defined(CONFIG_MPC5xxx) - kbd->bi_ipbfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; -#endif /* CONFIG_MPC5xxx */ - } - - kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep(hdr); - - /* - * Check if there is an initrd image - */ - -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - /* Look for a '-' which indicates to ignore the ramdisk argument */ - if (argc >= 3 && strcmp(argv[2], "-") == 0) { - debug ("Skipping initrd\n"); - len = data = 0; - } - else -#endif - if (argc >= 3) { - debug ("Not skipping initrd\n"); - show_boot_progress (9); - - addr = simple_strtoul(argv[2], NULL, 16); - - printf ("## Loading RAMDisk Image at %08lx ...\n", addr); - hdr = (image_header_t *)addr; - - if (!image_check_magic(hdr)) { - puts ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc(hdr)) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - show_boot_progress (10); - - print_image_hdr (hdr); - - if (verify) { - puts (" Verifying Checksum ... "); - - if (!image_check_dcrc_wd(hdr, CHUNKSZ)) { - puts ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - } - - show_boot_progress (11); - - if (!image_check_os(hdr, IH_OS_LINUX) || - !image_check_arch(hdr, IH_ARCH_PPC) || - !image_check_type(hdr, IH_TYPE_RAMDISK)) { - puts ("No Linux PPC Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - - data = image_get_data(hdr); - len = image_get_data_size(hdr); - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type(hdr, IH_TYPE_MULTI) && (len_ptr[1])) { - u_long tail = image_to_cpu(len_ptr[0]) % 4; - int i; - - show_boot_progress (13); - - /* skip kernel length and terminator */ - data = (ulong)(&len_ptr[2]); - /* skip any additional image length fields */ - for (i=1; len_ptr[i]; ++i) - data += 4; - /* add kernel length, and align */ - data += image_to_cpu(len_ptr[0]); - if (tail) { - data += 4 - tail; - } - - len = image_to_cpu(len_ptr[1]); - - } else { - /* - * no initrd image - */ - show_boot_progress (14); - - len = data = 0; - } - -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - if(argc > 3) { - of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); - hdr = (image_header_t *)of_flat_tree; -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree + image_get_header_size())) != OF_DT_HEADER) { -#else - if (fdt_check_header(of_flat_tree + image_get_header_size()) != 0) { -#endif -#ifndef CFG_NO_FLASH - if (addr2info((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; -#endif - } else if (image_check_magic(hdr)) { - printf("## Flat Device Tree at %08lX\n", hdr); - print_image_hdr(hdr); - - if ((image_get_load(hdr) < ((unsigned long)hdr + image_get_image_size(hdr))) && - ((image_get_load(hdr) + image_get_data_size(hdr)) > (unsigned long)hdr)) { - puts ("ERROR: fdt overwritten - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - - puts (" Verifying Checksum ... "); - if (!image_check_hcrc(hdr)) { - puts ("ERROR: fdt header checksum invalid - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_dcrc(hdr)) { - puts ("ERROR: fdt checksum invalid - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - - if (!image_check_type(hdr, IH_TYPE_FLATDT)) { - puts ("ERROR: uImage is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - if (image_get_comp(hdr) != IH_COMP_NONE) { - puts ("ERROR: uImage is compressed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree + image_get_header_size())) != OF_DT_HEADER) { -#else - if (fdt_check_header(of_flat_tree + image_get_header_size()) != 0) { -#endif - puts ("ERROR: uImage data is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - - memmove((void *)image_get_load(hdr), - (void *)(of_flat_tree + image_get_header_size()), - image_get_data_size(hdr)); - - of_flat_tree = (char *)image_get_load(hdr); - } else { - puts ("Did not find a flat Flat Device Tree.\n" - "Must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - printf (" Booting using the fdt at 0x%x\n", - of_flat_tree); - } else if (image_check_type(hdr, IH_TYPE_MULTI) && (len_ptr[1]) && (len_ptr[2])) { - u_long tail = image_to_cpu(len_ptr[0]) % 4; - int i; - - /* skip kernel length, initrd length, and terminator */ - of_flat_tree = (char *)(&len_ptr[3]); - /* skip any additional image length fields */ - for (i=2; len_ptr[i]; ++i) - of_flat_tree += 4; - /* add kernel length, and align */ - of_flat_tree += image_to_cpu(len_ptr[0]); - if (tail) { - of_flat_tree += 4 - tail; - } - - /* add initrd length, and align */ - tail = image_to_cpu(len_ptr[1]) % 4; - of_flat_tree += image_to_cpu(len_ptr[1]); - if (tail) { - of_flat_tree += 4 - tail; - } - -#ifndef CFG_NO_FLASH - /* move the blob if it is in flash (set of_data to !null) */ - if (addr2info ((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; -#endif - - -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { -#else - if (fdt_check_header (of_flat_tree) != 0) { -#endif - puts ("ERROR: image is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - -#if defined(CONFIG_OF_FLAT_TREE) - if (((struct boot_param_header *)of_flat_tree)->totalsize != - image_to_cpu (len_ptr[2])) { -#else - if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != - image_to_cpu(len_ptr[2])) { -#endif - puts ("ERROR: fdt size != image size - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - } -#endif - if (!data) { - debug ("No initrd\n"); - } - - if (data) { - if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = data; - initrd_end = initrd_start + len; - } else { - initrd_start = (ulong)kbd - len; - initrd_start &= ~(4096 - 1); /* align on page */ - - if (initrd_high) { - ulong nsp; - - /* - * the inital ramdisk does not need to be within - * CFG_BOOTMAPSZ as it is not accessed until after - * the mm system is initialised. - * - * do the stack bottom calculation again and see if - * the initrd will fit just below the monitor stack - * bottom without overwriting the area allocated - * above for command line args and board info. - */ - asm( "mr %0,1": "=r"(nsp) : ); - nsp -= 2048; /* just to be sure */ - nsp &= ~0xF; - if (nsp > initrd_high) /* limit as specified */ - nsp = initrd_high; - nsp -= len; - nsp &= ~(4096 - 1); /* align on page */ - if (nsp >= sp) - initrd_start = nsp; - } - - show_boot_progress (12); - - debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - data, data + len - 1, len, len); - - initrd_end = initrd_start + len; - printf (" Loading Ramdisk to %08lx, end %08lx ... ", - initrd_start, initrd_end); -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - { - size_t l = len; - void *to = (void *)initrd_start; - void *from = (void *)data; - - while (l > 0) { - size_t tail = (l > CHUNKSZ) ? CHUNKSZ : l; - WATCHDOG_RESET(); - memmove (to, from, tail); - to += tail; - from += tail; - l -= tail; - } - } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - memmove ((void *)initrd_start, (void *)data, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - puts ("OK\n"); - } - } else { - initrd_start = 0; - initrd_end = 0; - } - -#if defined(CONFIG_OF_LIBFDT) - -#ifdef CFG_BOOTMAPSZ - /* - * The blob must be within CFG_BOOTMAPSZ, - * so we flag it to be copied if it is not. - */ - if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) - of_data = (ulong)of_flat_tree; -#endif - - /* move of_flat_tree if needed */ - if (of_data) { - int err; - ulong of_start, of_len; - - of_len = be32_to_cpu(fdt_totalsize(of_data)); - - /* position on a 4K boundary before the kbd */ - of_start = (ulong)kbd - of_len; - of_start &= ~(4096 - 1); /* align on page */ - debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - of_data, of_data + of_len - 1, of_len, of_len); - - of_flat_tree = (char *)of_start; - printf (" Loading Device Tree to %08lx, end %08lx ... ", - of_start, of_start + of_len - 1); - err = fdt_open_into((void *)of_data, (void *)of_start, of_len); - if (err != 0) { - puts ("ERROR: fdt move failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - } - /* - * Add the chosen node if it doesn't exist, add the env and bd_t - * if the user wants it (the logic is in the subroutines). - */ - if (of_flat_tree) { - if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { - puts ("ERROR: /chosen node create failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } -#ifdef CONFIG_OF_HAS_UBOOT_ENV - if (fdt_env(of_flat_tree) < 0) { - puts ("ERROR: /u-boot-env node create failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } -#endif -#ifdef CONFIG_OF_HAS_BD_T - if (fdt_bd_t(of_flat_tree) < 0) { - puts ("ERROR: /bd_t node create failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } -#endif -#ifdef CONFIG_OF_BOARD_SETUP - /* Call the board-specific fixup routine */ - ft_board_setup(of_flat_tree, gd->bd); -#endif - } -#endif /* CONFIG_OF_LIBFDT */ -#if defined(CONFIG_OF_FLAT_TREE) -#ifdef CFG_BOOTMAPSZ - /* - * The blob must be within CFG_BOOTMAPSZ, - * so we flag it to be copied if it is not. - */ - if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) - of_data = (ulong)of_flat_tree; -#endif - - /* move of_flat_tree if needed */ - if (of_data) { - ulong of_start, of_len; - of_len = ((struct boot_param_header *)of_data)->totalsize; - - /* provide extra 8k pad */ - of_start = (ulong)kbd - of_len - 8192; - of_start &= ~(4096 - 1); /* align on page */ - debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - of_data, of_data + of_len - 1, of_len, of_len); - - of_flat_tree = (char *)of_start; - printf (" Loading Device Tree to %08lx, end %08lx ... ", - of_start, of_start + of_len - 1); - memmove ((void *)of_start, (void *)of_data, of_len); - puts ("OK\n"); - } - /* - * Create the /chosen node and modify the blob with board specific - * values as needed. - */ - ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); - /* ft_dump_blob(of_flat_tree); */ -#endif - debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong)kernel); - - show_boot_progress (15); - -#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) - unlock_ram_in_cache(); -#endif - -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - if (of_flat_tree) { /* device tree; boot new style */ - /* - * Linux Kernel Parameters (passing device tree): - * r3: pointer to the fdt, followed by the board info data - * r4: physical pointer to the kernel itself - * r5: NULL - * r6: NULL - * r7: NULL - */ - (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); - /* does not return */ - } -#endif - /* - * Linux Kernel Parameters (passing board info data): - * r3: ptr to board info data - * r4: initrd_start or 0 if no initrd - * r5: initrd_end - unused if r4 is 0 - * r6: Start of command line string - * r7: End of command line string - */ - (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); - /* does not return */ -} -#endif /* CONFIG_PPC */ - static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], diff --git a/lib_ppc/Makefile b/lib_ppc/Makefile index 2ba034f..2aa0154 100644 --- a/lib_ppc/Makefile +++ b/lib_ppc/Makefile @@ -28,7 +28,8 @@ LIB = $(obj)lib$(ARCH).a SOBJS = ppcstring.o ticks.o
COBJS = board.o \ - bat_rw.o cache.o extable.o kgdb.o time.o interrupts.o + bat_rw.o cache.o extable.o kgdb.o time.o interrupts.o \ + ppc_linux.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c new file mode 100644 index 0000000..823758c --- /dev/null +++ b/lib_ppc/ppc_linux.c @@ -0,0 +1,589 @@ +/* + * (C) Copyright 2008 Semihalf + * + * (C) Copyright 2000-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <image.h> +#include <malloc.h> +#include <zlib.h> +#include <bzlib.h> +#include <environment.h> +#include <asm/byteorder.h> + +#if defined(CONFIG_OF_LIBFDT) +#include <fdt.h> +#include <libfdt.h> +#include <fdt_support.h> +#endif +#if defined(CONFIG_OF_FLAT_TREE) +#include <ft_build.h> +#endif + +#ifdef CONFIG_LOGBUFFER +#include <logbuff.h> +#endif + +#ifdef CFG_INIT_RAM_LOCK +#include <asm/cache.h> +#endif + +#define CHUNKSZ (64 * 1024) + +DECLARE_GLOBAL_DATA_PTR; +extern image_header_t header; + +/*cmd_boot.c*/ +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +#ifdef DEBUG +extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +#endif + +#ifdef CONFIG_PPC +void __attribute__((noinline)) +do_bootm_linux (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong addr, + ulong *len_ptr, + int verify) +{ + ulong sp; + ulong len; + ulong initrd_start, initrd_end; + ulong cmd_start, cmd_end; + ulong initrd_high; + ulong data; + int initrd_copy_to_ram = 1; + char *cmdline; + char *s; + bd_t *kbd; + void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); + image_header_t *hdr = &header; +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) + char *of_flat_tree = NULL; + ulong of_data = 0; +#endif + + if ((s = getenv ("initrd_high")) != NULL) { + /* a value of "no" or a similar string will act like 0, + * turning the "load high" feature off. This is intentional. + */ + initrd_high = simple_strtoul(s, NULL, 16); + if (initrd_high == ~0) + initrd_copy_to_ram = 0; + } else { /* not set, no restrictions to load high */ + initrd_high = ~0; + } + +#ifdef CONFIG_LOGBUFFER + kbd=gd->bd; + /* Prevent initrd from overwriting logbuffer */ + if (initrd_high < (kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD)) + initrd_high = kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD; + debug ("## Logbuffer at 0x%08lX ", kbd->bi_memsize-LOGBUFF_LEN); +#endif + + /* + * Booting a (Linux) kernel image + * + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CFG_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + + asm( "mr %0,1": "=r"(sp) : ); + + debug ("## Current stack ends at 0x%08lX ", sp); + + sp -= 2048; /* just to be sure */ + if (sp > CFG_BOOTMAPSZ) + sp = CFG_BOOTMAPSZ; + sp &= ~0xF; + + debug ("=> set upper limit to 0x%08lX\n", sp); + + cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF); + kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); + + if ((s = getenv("bootargs")) == NULL) + s = ""; + + strcpy (cmdline, s); + + cmd_start = (ulong)&cmdline[0]; + cmd_end = cmd_start + strlen(cmdline); + + *kbd = *(gd->bd); + +#ifdef DEBUG + printf ("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); + + do_bdinfo (NULL, 0, 0, NULL); +#endif + + if ((s = getenv ("clocks_in_mhz")) != NULL) { + /* convert all clock information to MHz */ + kbd->bi_intfreq /= 1000000L; + kbd->bi_busfreq /= 1000000L; +#if defined(CONFIG_MPC8220) + kbd->bi_inpfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; + kbd->bi_pevfreq /= 1000000L; + kbd->bi_flbfreq /= 1000000L; + kbd->bi_vcofreq /= 1000000L; +#endif +#if defined(CONFIG_CPM2) + kbd->bi_cpmfreq /= 1000000L; + kbd->bi_brgfreq /= 1000000L; + kbd->bi_sccfreq /= 1000000L; + kbd->bi_vco /= 1000000L; +#endif +#if defined(CONFIG_MPC5xxx) + kbd->bi_ipbfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; +#endif /* CONFIG_MPC5xxx */ + } + + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep(hdr); + + /* + * Check if there is an initrd image + */ + +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) + /* Look for a '-' which indicates to ignore the ramdisk argument */ + if (argc >= 3 && strcmp(argv[2], "-") == 0) { + debug ("Skipping initrd\n"); + len = data = 0; + } + else +#endif + if (argc >= 3) { + debug ("Not skipping initrd\n"); + show_boot_progress (9); + + addr = simple_strtoul(argv[2], NULL, 16); + + printf ("## Loading RAMDisk Image at %08lx ...\n", addr); + hdr = (image_header_t *)addr; + + if (!image_check_magic(hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-10); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_hcrc(hdr)) { + puts ("Bad Header Checksum\n"); + show_boot_progress (-11); + do_reset (cmdtp, flag, argc, argv); + } + show_boot_progress (10); + + print_image_hdr (hdr); + + if (verify) { + puts (" Verifying Checksum ... "); + + if (!image_check_dcrc_wd(hdr, CHUNKSZ)) { + puts ("Bad Data CRC\n"); + show_boot_progress (-12); + do_reset (cmdtp, flag, argc, argv); + } + puts ("OK\n"); + } + + show_boot_progress (11); + + if (!image_check_os(hdr, IH_OS_LINUX) || + !image_check_arch(hdr, IH_ARCH_PPC) || + !image_check_type(hdr, IH_TYPE_RAMDISK)) { + puts ("No Linux PPC Ramdisk Image\n"); + show_boot_progress (-13); + do_reset (cmdtp, flag, argc, argv); + } + + data = image_get_data(hdr); + len = image_get_data_size(hdr); + + /* + * Now check if we have a multifile image + */ + } else if (image_check_type(hdr, IH_TYPE_MULTI) && (len_ptr[1])) { + u_long tail = image_to_cpu(len_ptr[0]) % 4; + int i; + + show_boot_progress (13); + + /* skip kernel length and terminator */ + data = (ulong)(&len_ptr[2]); + /* skip any additional image length fields */ + for (i=1; len_ptr[i]; ++i) + data += 4; + /* add kernel length, and align */ + data += image_to_cpu(len_ptr[0]); + if (tail) { + data += 4 - tail; + } + + len = image_to_cpu(len_ptr[1]); + + } else { + /* + * no initrd image + */ + show_boot_progress (14); + + len = data = 0; + } + +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) + if(argc > 3) { + of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); + hdr = (image_header_t *)of_flat_tree; +#if defined(CONFIG_OF_FLAT_TREE) + if (*((ulong *)(of_flat_tree + image_get_header_size())) != OF_DT_HEADER) { +#else + if (fdt_check_header(of_flat_tree + image_get_header_size()) != 0) { +#endif +#ifndef CFG_NO_FLASH + if (addr2info((ulong)of_flat_tree) != NULL) + of_data = (ulong)of_flat_tree; +#endif + } else if (image_check_magic(hdr)) { + printf("## Flat Device Tree at %08lX\n", hdr); + print_image_hdr(hdr); + + if ((image_get_load(hdr) < ((unsigned long)hdr + image_get_image_size(hdr))) && + ((image_get_load(hdr) + image_get_data_size(hdr)) > (unsigned long)hdr)) { + puts ("ERROR: fdt overwritten - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + + puts (" Verifying Checksum ... "); + if (!image_check_hcrc(hdr)) { + puts ("ERROR: fdt header checksum invalid - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_dcrc(hdr)) { + puts ("ERROR: fdt checksum invalid - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + puts ("OK\n"); + + if (!image_check_type(hdr, IH_TYPE_FLATDT)) { + puts ("ERROR: uImage is not a fdt - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + if (image_get_comp(hdr) != IH_COMP_NONE) { + puts ("ERROR: uImage is compressed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } +#if defined(CONFIG_OF_FLAT_TREE) + if (*((ulong *)(of_flat_tree + image_get_header_size())) != OF_DT_HEADER) { +#else + if (fdt_check_header(of_flat_tree + image_get_header_size()) != 0) { +#endif + puts ("ERROR: uImage data is not a fdt - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + + memmove((void *)image_get_load(hdr), + (void *)(of_flat_tree + image_get_header_size()), + image_get_data_size(hdr)); + + of_flat_tree = (char *)image_get_load(hdr); + } else { + puts ("Did not find a flat Flat Device Tree.\n" + "Must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + printf (" Booting using the fdt at 0x%x\n", + of_flat_tree); + } else if (image_check_type(hdr, IH_TYPE_MULTI) && (len_ptr[1]) && (len_ptr[2])) { + u_long tail = image_to_cpu(len_ptr[0]) % 4; + int i; + + /* skip kernel length, initrd length, and terminator */ + of_flat_tree = (char *)(&len_ptr[3]); + /* skip any additional image length fields */ + for (i=2; len_ptr[i]; ++i) + of_flat_tree += 4; + /* add kernel length, and align */ + of_flat_tree += image_to_cpu(len_ptr[0]); + if (tail) { + of_flat_tree += 4 - tail; + } + + /* add initrd length, and align */ + tail = image_to_cpu(len_ptr[1]) % 4; + of_flat_tree += image_to_cpu(len_ptr[1]); + if (tail) { + of_flat_tree += 4 - tail; + } + +#ifndef CFG_NO_FLASH + /* move the blob if it is in flash (set of_data to !null) */ + if (addr2info ((ulong)of_flat_tree) != NULL) + of_data = (ulong)of_flat_tree; +#endif + + +#if defined(CONFIG_OF_FLAT_TREE) + if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { +#else + if (fdt_check_header (of_flat_tree) != 0) { +#endif + puts ("ERROR: image is not a fdt - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + +#if defined(CONFIG_OF_FLAT_TREE) + if (((struct boot_param_header *)of_flat_tree)->totalsize != + image_to_cpu (len_ptr[2])) { +#else + if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != + image_to_cpu(len_ptr[2])) { +#endif + puts ("ERROR: fdt size != image size - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + } +#endif + if (!data) { + debug ("No initrd\n"); + } + + if (data) { + if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ + initrd_start = data; + initrd_end = initrd_start + len; + } else { + initrd_start = (ulong)kbd - len; + initrd_start &= ~(4096 - 1); /* align on page */ + + if (initrd_high) { + ulong nsp; + + /* + * the inital ramdisk does not need to be within + * CFG_BOOTMAPSZ as it is not accessed until after + * the mm system is initialised. + * + * do the stack bottom calculation again and see if + * the initrd will fit just below the monitor stack + * bottom without overwriting the area allocated + * above for command line args and board info. + */ + asm( "mr %0,1": "=r"(nsp) : ); + nsp -= 2048; /* just to be sure */ + nsp &= ~0xF; + if (nsp > initrd_high) /* limit as specified */ + nsp = initrd_high; + nsp -= len; + nsp &= ~(4096 - 1); /* align on page */ + if (nsp >= sp) + initrd_start = nsp; + } + + show_boot_progress (12); + + debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", + data, data + len - 1, len, len); + + initrd_end = initrd_start + len; + printf (" Loading Ramdisk to %08lx, end %08lx ... ", + initrd_start, initrd_end); +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + { + size_t l = len; + void *to = (void *)initrd_start; + void *from = (void *)data; + + while (l > 0) { + size_t tail = (l > CHUNKSZ) ? CHUNKSZ : l; + WATCHDOG_RESET(); + memmove (to, from, tail); + to += tail; + from += tail; + l -= tail; + } + } +#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ + memmove ((void *)initrd_start, (void *)data, len); +#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ + puts ("OK\n"); + } + } else { + initrd_start = 0; + initrd_end = 0; + } + +#if defined(CONFIG_OF_LIBFDT) + +#ifdef CFG_BOOTMAPSZ + /* + * The blob must be within CFG_BOOTMAPSZ, + * so we flag it to be copied if it is not. + */ + if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) + of_data = (ulong)of_flat_tree; +#endif + + /* move of_flat_tree if needed */ + if (of_data) { + int err; + ulong of_start, of_len; + + of_len = be32_to_cpu(fdt_totalsize(of_data)); + + /* position on a 4K boundary before the kbd */ + of_start = (ulong)kbd - of_len; + of_start &= ~(4096 - 1); /* align on page */ + debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", + of_data, of_data + of_len - 1, of_len, of_len); + + of_flat_tree = (char *)of_start; + printf (" Loading Device Tree to %08lx, end %08lx ... ", + of_start, of_start + of_len - 1); + err = fdt_open_into((void *)of_data, (void *)of_start, of_len); + if (err != 0) { + puts ("ERROR: fdt move failed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + puts ("OK\n"); + } + /* + * Add the chosen node if it doesn't exist, add the env and bd_t + * if the user wants it (the logic is in the subroutines). + */ + if (of_flat_tree) { + if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { + puts ("ERROR: /chosen node create failed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } +#ifdef CONFIG_OF_HAS_UBOOT_ENV + if (fdt_env(of_flat_tree) < 0) { + puts ("ERROR: /u-boot-env node create failed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } +#endif +#ifdef CONFIG_OF_HAS_BD_T + if (fdt_bd_t(of_flat_tree) < 0) { + puts ("ERROR: /bd_t node create failed - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } +#endif +#ifdef CONFIG_OF_BOARD_SETUP + /* Call the board-specific fixup routine */ + ft_board_setup(of_flat_tree, gd->bd); +#endif + } +#endif /* CONFIG_OF_LIBFDT */ +#if defined(CONFIG_OF_FLAT_TREE) +#ifdef CFG_BOOTMAPSZ + /* + * The blob must be within CFG_BOOTMAPSZ, + * so we flag it to be copied if it is not. + */ + if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) + of_data = (ulong)of_flat_tree; +#endif + + /* move of_flat_tree if needed */ + if (of_data) { + ulong of_start, of_len; + of_len = ((struct boot_param_header *)of_data)->totalsize; + + /* provide extra 8k pad */ + of_start = (ulong)kbd - of_len - 8192; + of_start &= ~(4096 - 1); /* align on page */ + debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", + of_data, of_data + of_len - 1, of_len, of_len); + + of_flat_tree = (char *)of_start; + printf (" Loading Device Tree to %08lx, end %08lx ... ", + of_start, of_start + of_len - 1); + memmove ((void *)of_start, (void *)of_data, of_len); + puts ("OK\n"); + } + /* + * Create the /chosen node and modify the blob with board specific + * values as needed. + */ + ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); + /* ft_dump_blob(of_flat_tree); */ +#endif + debug ("## Transferring control to Linux (at address %08lx) ...\n", + (ulong)kernel); + + show_boot_progress (15); + +#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) + unlock_ram_in_cache(); +#endif + +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) + if (of_flat_tree) { /* device tree; boot new style */ + /* + * Linux Kernel Parameters (passing device tree): + * r3: pointer to the fdt, followed by the board info data + * r4: physical pointer to the kernel itself + * r5: NULL + * r6: NULL + * r7: NULL + */ + (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); + /* does not return */ + } +#endif + /* + * Linux Kernel Parameters (passing board info data): + * r3: ptr to board info data + * r4: initrd_start or 0 if no initrd + * r5: initrd_end - unused if r4 is 0 + * r6: Start of command line string + * r7: End of command line string + */ + (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); + /* does not return */ +} +#endif /* CONFIG_PPC */

In message 20080111142831.8025.30799.stgit@hekate.izotz.org you wrote:
PPC implementation of do_bootm_linux() routine is moved to a dedicated file lib_ppc/ppc_linux.c
This is a bad name. "bootm" is more than just booting Linux images.
The ARM port did this wrong, and many others copied the error. Now let's take the opportunity and clean this up instead of making it worse.
Please neame this lib_ppc/bootm.c or similar (ditto for the other architectures).
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
In message 20080111142831.8025.30799.stgit@hekate.izotz.org you wrote:
PPC implementation of do_bootm_linux() routine is moved to a dedicated file lib_ppc/ppc_linux.c
This is a bad name. "bootm" is more than just booting Linux images.
The ARM port did this wrong, and many others copied the error. Now let's take the opportunity and clean this up instead of making it worse.
Please neame this lib_ppc/bootm.c or similar (ditto for the other architectures).
I see, naming seemed arbitrary, but I did not know the full story.
I'll rename all related files.
Cheers, m.

Make CONFIG_OF_LIBFDT and CONFIG_OF_FLAT_TREE use more readable in PPC variant of do_bootm_linux() routine.
Signed-off-by: Marian Balakowicz m8@semihalf.com ---
common/cmd_bootm.c | 3 +-- lib_ppc/ppc_linux.c | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index a4952fd..310173a 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -40,8 +40,7 @@ #include <fdt.h> #include <libfdt.h> #include <fdt_support.h> -#endif -#if defined(CONFIG_OF_FLAT_TREE) +#elif defined(CONFIG_OF_FLAT_TREE) #include <ft_build.h> #endif
diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 823758c..3a4b74f 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -37,8 +37,7 @@ #include <fdt.h> #include <libfdt.h> #include <fdt_support.h> -#endif -#if defined(CONFIG_OF_FLAT_TREE) +#elif defined(CONFIG_OF_FLAT_TREE) #include <ft_build.h> #endif
@@ -268,7 +267,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, hdr = (image_header_t *)of_flat_tree; #if defined(CONFIG_OF_FLAT_TREE) if (*((ulong *)(of_flat_tree + image_get_header_size())) != OF_DT_HEADER) { -#else +#elif defined(CONFIG_OF_LIBFDT) if (fdt_check_header(of_flat_tree + image_get_header_size()) != 0) { #endif #ifndef CFG_NO_FLASH @@ -312,7 +311,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, } #if defined(CONFIG_OF_FLAT_TREE) if (*((ulong *)(of_flat_tree + image_get_header_size())) != OF_DT_HEADER) { -#else +#elif defined(CONFIG_OF_LIBFDT) if (fdt_check_header(of_flat_tree + image_get_header_size()) != 0) { #endif puts ("ERROR: uImage data is not a fdt - " @@ -363,7 +362,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
#if defined(CONFIG_OF_FLAT_TREE) if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { -#else +#elif defined(CONFIG_OF_LIBFDT) if (fdt_check_header (of_flat_tree) != 0) { #endif puts ("ERROR: image is not a fdt - " @@ -374,7 +373,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_OF_FLAT_TREE) if (((struct boot_param_header *)of_flat_tree)->totalsize != image_to_cpu (len_ptr[2])) { -#else +#elif defined(CONFIG_OF_LIBFDT) if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != image_to_cpu(len_ptr[2])) { #endif @@ -517,8 +516,9 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, ft_board_setup(of_flat_tree, gd->bd); #endif } -#endif /* CONFIG_OF_LIBFDT */ -#if defined(CONFIG_OF_FLAT_TREE) + +#elif defined(CONFIG_OF_FLAT_TREE) + #ifdef CFG_BOOTMAPSZ /* * The blob must be within CFG_BOOTMAPSZ, @@ -551,7 +551,9 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, */ ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); /* ft_dump_blob(of_flat_tree); */ -#endif + +#endif /* #if defined(CONFIG_OF_LIBFDT) #elif defined(CONFIG_OF_FLAT_TREE) */ + debug ("## Transferring control to Linux (at address %08lx) ...\n", (ulong)kernel);

Marian Balakowicz wrote:
Make CONFIG_OF_LIBFDT and CONFIG_OF_FLAT_TREE use more readable in PPC variant of do_bootm_linux() routine.
Signed-off-by: Marian Balakowicz m8@semihalf.com
What is the wisdom of the crowd, is it possible to port over the remaining 5 boards and removing the "CONFIG_OF_FLAT_TREE" code in this merge window, or is it too risky? My gut says too risky, do it in the next window.
$ find . -name "*.[h]" | xargs grep CONFIG_OF_FLAT_TREE | grep 1 ./include/configs/mpc7448hpc2.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/sbc8349.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/MPC8610HPCD.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/stxxtc.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/sbc8641d.h:#define CONFIG_OF_FLAT_TREE 1
$ find . -name "*.[h]" | xargs grep CONFIG_OF_LIBFDT | grep 1 | wc -l 25
Thanks, gvb

Jerry Van Baren wrote:
Marian Balakowicz wrote:
Make CONFIG_OF_LIBFDT and CONFIG_OF_FLAT_TREE use more readable in PPC variant of do_bootm_linux() routine.
Signed-off-by: Marian Balakowicz m8@semihalf.com
What is the wisdom of the crowd, is it possible to port over the remaining 5 boards and removing the "CONFIG_OF_FLAT_TREE" code in this merge window, or is it too risky? My gut says too risky, do it in the next window.
$ find . -name "*.[h]" | xargs grep CONFIG_OF_FLAT_TREE | grep 1 ./include/configs/mpc7448hpc2.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/sbc8349.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/MPC8610HPCD.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/stxxtc.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/sbc8641d.h:#define CONFIG_OF_FLAT_TREE 1
When the 86xx repo is pulled by Wolfgang, the 8610 board will be done!
The sbc8641 board is likely really easy given that I have already done it for the Freescale MPC8641HPCN board. I am not sure who is pushing that code around, though.
jdl

-----Original Message----- From: u-boot-users-bounces@lists.sourceforge.net [mailto:u-boot-users- bounces@lists.sourceforge.net] On Behalf Of Jon Loeliger Sent: Friday, January 11, 2008 10:49 AM To: Jerry Van Baren Cc: u-boot-users@lists.sourceforge.net; Marian Balakowicz Subject: Re: [U-Boot-Users] [PATCH 04/13] [new uImage] Cleanup OF/FDT #if/#elif/#endif use in do_bootm_linux()
Jerry Van Baren wrote:
Marian Balakowicz wrote:
Make CONFIG_OF_LIBFDT and CONFIG_OF_FLAT_TREE use more readable in PPC variant of do_bootm_linux() routine.
Signed-off-by: Marian Balakowicz m8@semihalf.com
What is the wisdom of the crowd, is it possible to port over the remaining 5 boards and removing the "CONFIG_OF_FLAT_TREE" code in this merge window, or is it too risky? My gut says too risky, do it in the next window.
$ find . -name "*.[h]" | xargs grep CONFIG_OF_FLAT_TREE | grep 1 ./include/configs/mpc7448hpc2.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/sbc8349.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/MPC8610HPCD.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/stxxtc.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/sbc8641d.h:#define CONFIG_OF_FLAT_TREE 1
When the 86xx repo is pulled by Wolfgang, the 8610 board will be done!
The sbc8641 board is likely really easy given that I have already done it for the Freescale MPC8641HPCN board. I am not sure who is pushing that code around, though.
I'm going to attempt to get it done this weekend - unless she has plans I don't know about :-P
jdl
Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketpla ce _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users

On Fri, 11 Jan 2008 11:26:03 -0500 Jerry Van Baren gerald.vanbaren@ge.com wrote:
Marian Balakowicz wrote:
Make CONFIG_OF_LIBFDT and CONFIG_OF_FLAT_TREE use more readable in PPC variant of do_bootm_linux() routine.
Signed-off-by: Marian Balakowicz m8@semihalf.com
What is the wisdom of the crowd, is it possible to port over the remaining 5 boards and removing the "CONFIG_OF_FLAT_TREE" code in this merge window, or is it too risky? My gut says too risky, do it in the next window.
$ find . -name "*.[h]" | xargs grep CONFIG_OF_FLAT_TREE | grep 1 ./include/configs/mpc7448hpc2.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/sbc8349.h:#define CONFIG_OF_FLAT_TREE 1
apparently you're not up to date; the sbc8349 has already been converted over.
Kim

Kim Phillips wrote:
On Fri, 11 Jan 2008 11:26:03 -0500 Jerry Van Baren gerald.vanbaren@ge.com wrote:
Marian Balakowicz wrote:
Make CONFIG_OF_LIBFDT and CONFIG_OF_FLAT_TREE use more readable in PPC variant of do_bootm_linux() routine.
Signed-off-by: Marian Balakowicz m8@semihalf.com
What is the wisdom of the crowd, is it possible to port over the remaining 5 boards and removing the "CONFIG_OF_FLAT_TREE" code in this merge window, or is it too risky? My gut says too risky, do it in the next window.
$ find . -name "*.[h]" | xargs grep CONFIG_OF_FLAT_TREE | grep 1 ./include/configs/mpc7448hpc2.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/sbc8349.h:#define CONFIG_OF_FLAT_TREE 1
apparently you're not up to date; the sbc8349 has already been converted over.
Kim
Ahh, you're right (blushes).
$ find . -name "*.[h]" | xargs grep CONFIG_OF_FLAT_TREE | grep 1 ./include/configs/mpc7448hpc2.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/MPC8610HPCD.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/stxxtc.h:#define CONFIG_OF_FLAT_TREE 1 ./include/configs/sbc8641d.h:#define CONFIG_OF_FLAT_TREE 1
$ find . -name "*.[h]" | xargs grep CONFIG_OF_LIBFDT | grep 1 | wc -l 29
Even better! Add in Jon's pending update and we are down to 3 boards, one of which will be "really easy".
mpc7448hpc2 No maintainer listed, "Created 08/11/2006 Roy Zang" stxxtc Dan Malek sbc8641d Joe Hamman
Thanks, everybody, gvb

Jerry Van Baren wrote:
Marian Balakowicz wrote:
Make CONFIG_OF_LIBFDT and CONFIG_OF_FLAT_TREE use more readable in PPC variant of do_bootm_linux() routine.
Signed-off-by: Marian Balakowicz m8@semihalf.com
What is the wisdom of the crowd, is it possible to port over the remaining 5 boards and removing the "CONFIG_OF_FLAT_TREE" code in this merge window, or is it too risky? My gut says too risky, do it in the next window.
[snip]
I'd be more then happy to removed CONFIG_OF_FLAT_TREE from image/bootm related code. It'll simplify the current code and will allow to avoid unnecessary hassle when adding new functionality.
How about I do such cleanup in the next patchset? It will not hit mainline before the next window and it seems we should be done with converting remaining boards by then. Does that sound reasonable?
Cheers, m.

Move gunzip(), zalloc() and zfree() to a separate file. Share zalloc() and zfree() with cramfs uncompress routine.
Signed-off-by: Marian Balakowicz m8@semihalf.com ---
common/Makefile | 1 common/cmd_bootm.c | 94 +--------------------------------------- common/gunzip.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/cramfs/uncompress.c | 20 +------- lib_generic/bzlib.c | 4 ++ 5 files changed, 123 insertions(+), 109 deletions(-) create mode 100644 common/gunzip.c
diff --git a/common/Makefile b/common/Makefile index 00267e1..c86b3a4 100644 --- a/common/Makefile +++ b/common/Makefile @@ -37,6 +37,7 @@ COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o COBJS-$(CONFIG_CMD_BEDBUG) += cmd_bedbug.o COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o COBJS-y += image.o +COBJS-y += gunzip.o COBJS-y += cmd_boot.o COBJS-y += cmd_bootm.o COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 310173a..76ea49f 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -70,8 +70,9 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
int gunzip (void *, int, unsigned char *, unsigned long *);
-static void *zalloc(void *, unsigned, unsigned); -static void zfree(void *, void *, unsigned); +#ifdef CONFIG_BZIP2 +extern void bz_internal_error(int); +#endif
#if defined(CONFIG_CMD_IMI) static int image_info (unsigned long addr); @@ -863,95 +864,6 @@ print_type (image_header_t *hdr) printf ("%s %s %s (%s)", arch, os, type, comp); }
-#define ZALLOC_ALIGNMENT 16 - -static void *zalloc(void *x, unsigned items, unsigned size) -{ - void *p; - - size *= items; - size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); - - p = malloc (size); - - return (p); -} - -static void zfree(void *x, void *addr, unsigned nb) -{ - free (addr); -} - -#define HEAD_CRC 2 -#define EXTRA_FIELD 4 -#define ORIG_NAME 8 -#define COMMENT 0x10 -#define RESERVED 0xe0 - -#define DEFLATED 8 - -int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp) -{ - z_stream s; - int r, i, flags; - - /* skip header */ - i = 10; - flags = src[3]; - if (src[2] != DEFLATED || (flags & RESERVED) != 0) { - puts ("Error: Bad gzipped data\n"); - return (-1); - } - if ((flags & EXTRA_FIELD) != 0) - i = 12 + src[10] + (src[11] << 8); - if ((flags & ORIG_NAME) != 0) - while (src[i++] != 0) - ; - if ((flags & COMMENT) != 0) - while (src[i++] != 0) - ; - if ((flags & HEAD_CRC) != 0) - i += 2; - if (i >= *lenp) { - puts ("Error: gunzip out of data in header\n"); - return (-1); - } - - s.zalloc = zalloc; - s.zfree = zfree; -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - s.outcb = (cb_func)WATCHDOG_RESET; -#else - s.outcb = Z_NULL; -#endif /* CONFIG_HW_WATCHDOG */ - - r = inflateInit2(&s, -MAX_WBITS); - if (r != Z_OK) { - printf ("Error: inflateInit2() returned %d\n", r); - return (-1); - } - s.next_in = src + i; - s.avail_in = *lenp - i; - s.next_out = dst; - s.avail_out = dstlen; - r = inflate(&s, Z_FINISH); - if (r != Z_OK && r != Z_STREAM_END) { - printf ("Error: inflate() returned %d\n", r); - return (-1); - } - *lenp = s.next_out - (unsigned char *) dst; - inflateEnd(&s); - - return (0); -} - -#ifdef CONFIG_BZIP2 -void bz_internal_error(int errcode) -{ - printf ("BZIP2 internal error %d\n", errcode); -} -#endif /* CONFIG_BZIP2 */ - static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong addr, ulong *len_ptr, int verify) diff --git a/common/gunzip.c b/common/gunzip.c new file mode 100644 index 0000000..74f0bf9 --- /dev/null +++ b/common/gunzip.c @@ -0,0 +1,113 @@ +/* + * (C) Copyright 2000-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <image.h> +#include <malloc.h> +#include <zlib.h> + +#define ZALLOC_ALIGNMENT 16 +#define HEAD_CRC 2 +#define EXTRA_FIELD 4 +#define ORIG_NAME 8 +#define COMMENT 0x10 +#define RESERVED 0xe0 +#define DEFLATED 8 + +int gunzip(void *, int, unsigned char *, unsigned long *); +void *zalloc(void *, unsigned, unsigned); +void zfree(void *, void *, unsigned); + +void *zalloc(void *x, unsigned items, unsigned size) +{ + void *p; + + size *= items; + size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); + + p = malloc (size); + + return (p); +} + +void zfree(void *x, void *addr, unsigned nb) +{ + free (addr); +} + +int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp) +{ + z_stream s; + int r, i, flags; + + /* skip header */ + i = 10; + flags = src[3]; + if (src[2] != DEFLATED || (flags & RESERVED) != 0) { + puts ("Error: Bad gzipped data\n"); + return (-1); + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << 8); + if ((flags & ORIG_NAME) != 0) + while (src[i++] != 0) + ; + if ((flags & COMMENT) != 0) + while (src[i++] != 0) + ; + if ((flags & HEAD_CRC) != 0) + i += 2; + if (i >= *lenp) { + puts ("Error: gunzip out of data in header\n"); + return (-1); + } + + s.zalloc = zalloc; + s.zfree = zfree; +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + s.outcb = (cb_func)WATCHDOG_RESET; +#else + s.outcb = Z_NULL; +#endif /* CONFIG_HW_WATCHDOG */ + + r = inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf ("Error: inflateInit2() returned %d\n", r); + return (-1); + } + s.next_in = src + i; + s.avail_in = *lenp - i; + s.next_out = dst; + s.avail_out = dstlen; + r = inflate(&s, Z_FINISH); + if (r != Z_OK && r != Z_STREAM_END) { + printf ("Error: inflate() returned %d\n", r); + return (-1); + } + *lenp = s.next_out - (unsigned char *) dst; + inflateEnd(&s); + + return (0); +} diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c index 2e906eb..e4189e5 100644 --- a/fs/cramfs/uncompress.c +++ b/fs/cramfs/uncompress.c @@ -29,24 +29,8 @@
static z_stream stream;
-#define ZALLOC_ALIGNMENT 16 - -static void *zalloc (void *x, unsigned items, unsigned size) -{ - void *p; - - size *= items; - size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); - - p = malloc (size); - - return (p); -} - -static void zfree (void *x, void *addr, unsigned nb) -{ - free (addr); -} +void *zalloc(void *, unsigned, unsigned); +void zfree(void *, void *, unsigned);
/* Returns length of decompressed data. */ int cramfs_uncompress_block (void *dst, void *src, int srclen) diff --git a/lib_generic/bzlib.c b/lib_generic/bzlib.c index 87e6a6e..0d3f9c2 100644 --- a/lib_generic/bzlib.c +++ b/lib_generic/bzlib.c @@ -1592,6 +1592,10 @@ const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum) } #endif
+void bz_internal_error(int errcode) +{ + printf ("BZIP2 internal error %d\n", errcode); +}
/*-------------------------------------------------------------*/ /*--- end bzlib.c ---*/

CHUNKSZ defined for PPC and M68K is set to the same value of 64K, move this definition to a common header.
Signed-off-by: Marian Balakowicz m8@semihalf.com ---
common/cmd_bootm.c | 7 ------- include/image.h | 7 +++++++ lib_m68k/m68k_linux.c | 2 -- lib_ppc/ppc_linux.c | 2 -- 4 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 76ea49f..4b2ea3f 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -61,13 +61,6 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #include <dataflash.h> #endif
-/* - * Some systems (for example LWMON) have very short watchdog periods; - * we must make sure to split long operations like memmove() or - * crc32() into reasonable chunks. - */ -#define CHUNKSZ (64 * 1024) - int gunzip (void *, int, unsigned char *, unsigned long *);
#ifdef CONFIG_BZIP2 diff --git a/include/image.h b/include/image.h index b4ba2de..00a4549 100644 --- a/include/image.h +++ b/include/image.h @@ -163,6 +163,13 @@ typedef struct image_header { uint8_t ih_name[IH_NMLEN]; /* Image Name */ } image_header_t;
+/* + * Some systems (for example LWMON) have very short watchdog periods; + * we must make sure to split long operations like memmove() or + * crc32() into reasonable chunks. + */ +#define CHUNKSZ (64 * 1024) + #define image_to_cpu(x) ntohl(x) #define cpu_to_image(x) htonl(x)
diff --git a/lib_m68k/m68k_linux.c b/lib_m68k/m68k_linux.c index 6c2a6b2..237cd82 100644 --- a/lib_m68k/m68k_linux.c +++ b/lib_m68k/m68k_linux.c @@ -37,8 +37,6 @@ DECLARE_GLOBAL_DATA_PTR; #define LINUX_MAX_ENVS 256 #define LINUX_MAX_ARGS 256
-#define CHUNKSZ (64 * 1024) - #ifdef CONFIG_SHOW_BOOT_PROGRESS # include <status_led.h> # define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 3a4b74f..1013f9e 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -49,8 +49,6 @@ #include <asm/cache.h> #endif
-#define CHUNKSZ (64 * 1024) - DECLARE_GLOBAL_DATA_PTR; extern image_header_t header;

I386 targets are not using a uImage format, instead fake header is added to ram image before it is further processed by bootm.
Remove this fixup and force proper uImage use for I386.
Signed-off-by: Marian Balakowicz m8@semihalf.com ---
common/cmd_bootm.c | 16 --------------- include/asm-i386/zimage.h | 1 - lib_i386/i386_linux.c | 12 ----------- lib_i386/zimage.c | 48 --------------------------------------------- 4 files changed, 0 insertions(+), 77 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 4b2ea3f..40df9b0 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -79,10 +79,6 @@ static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
static void print_type (image_header_t *hdr);
-#ifdef __I386__ -image_header_t *fake_header(image_header_t *hdr, void *ptr, int size); -#endif - /* * Continue booting an OS image; caller already has: * - copied image header to global variable `header' @@ -158,21 +154,9 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) memmove (&header, (char *)addr, image_get_header_size());
if (!image_check_magic(hdr)) { -#ifdef __I386__ /* correct image format not implemented yet - fake it */ - if (fake_header(hdr, (void*)addr, -1) != NULL) { - /* to compensate for the addition below */ - addr -= image_get_header_size(); - /* turnof verify, - * fake_header() does not fake the data crc - */ - verify = 0; - } else -#endif /* __I386__ */ - { puts ("Bad Magic Number\n"); show_boot_progress (-1); return 1; - } } show_boot_progress (2);
diff --git a/include/asm-i386/zimage.h b/include/asm-i386/zimage.h index c7103b1..b6266e4 100644 --- a/include/asm-i386/zimage.h +++ b/include/asm-i386/zimage.h @@ -70,6 +70,5 @@ void *load_zimage(char *image, unsigned long kernel_size, int auto_boot);
void boot_zimage(void *setup_base); -image_header_t *fake_zimage_header(image_header_t *hdr, void *ptr, int size);
#endif diff --git a/lib_i386/i386_linux.c b/lib_i386/i386_linux.c index d8ae4fc..8792d84 100644 --- a/lib_i386/i386_linux.c +++ b/lib_i386/i386_linux.c @@ -33,18 +33,6 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
extern image_header_t header; /* from cmd_bootm.c */
- -image_header_t *fake_header(image_header_t *hdr, void *ptr, int size) -{ - /* try each supported image type in order */ - if (NULL != fake_zimage_header(hdr, ptr, size)) { - return hdr; - } - - return NULL; -} - - void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong addr, ulong *len_ptr, int verify) { diff --git a/lib_i386/zimage.c b/lib_i386/zimage.c index abe0a25..a998f6f 100644 --- a/lib_i386/zimage.c +++ b/lib_i386/zimage.c @@ -224,51 +224,3 @@ void boot_zimage(void *setup_base) regs.eflags = 0; enter_realmode(((u32)setup_base+SETUP_START_OFFSET)>>4, 0, ®s, ®s); } - - -image_header_t *fake_zimage_header(image_header_t *hdr, void *ptr, int size) -{ - /* There is no way to know the size of a zImage ... * - * so we assume that 2MB will be enough for now */ -#define ZIMAGE_SIZE 0x200000 - - /* load a 1MB, the loaded will have to be moved to its final - * position again later... */ -#define ZIMAGE_LOAD 0x100000 - - ulong checksum; - - if (KERNEL_MAGIC != *(u16*)(ptr + BOOT_FLAG_OFF)) { - /* not a zImage or bzImage */ - return NULL; - } - - if (-1 == size) { - size = ZIMAGE_SIZE; - } -#if 0 - checksum = crc32 (0, ptr, size); -#else - checksum = 0; -#endif - memset(hdr, 0, image_get_header_size()); - - /* Build new header */ - image_set_magic(hdr, IH_MAGIC); - image_set_time(hdr, 0); - image_set_size(hdr, size); - image_set_load(hdr, ZIMAGE_LOAD); - image_set_ep(hdr, 0); - image_set_dcrc(hdr, checksum); - image_set_os(hdr, IH_OS_LINUX); - image_set_arch(hdr, IH_ARCH_I386); - image_set_type(hdr, IH_TYPE_KERNEL); - image_set_comp(hdr, IH_COMP_NONE); - - image_set_name(hdr, "(none)"); - - checksum = crc32(0, (const char *)hdr, image_get_header_size()); - image_set_hcrc(hdr, checksum); - - return hdr; -}

Use image header copy instead of a (possibly corrupted) pointer to a initial image location.
Signed-off-by: Marian Balakowicz m8@semihalf.com ---
lib_i386/i386_linux.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib_i386/i386_linux.c b/lib_i386/i386_linux.c index 8792d84..3a92570 100644 --- a/lib_i386/i386_linux.c +++ b/lib_i386/i386_linux.c @@ -129,13 +129,13 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], }
/* if multi-part image, we need to advance base ptr */ - if (image_check_type(hdr, IH_TYPE_MULTI) && (len_ptr[1])) { + if (image_check_type(&header, IH_TYPE_MULTI) && (len_ptr[1])) { int i; for (i=0, addr+=sizeof(int); len_ptr[i++]; addr+=sizeof(int)); }
base_ptr = load_zimage((void*)addr + image_get_header_size(), - image_get_data_size(hdr), + image_get_data_size(&header), initrd_start, initrd_end-initrd_start, 0);
if (NULL == base_ptr) {

Signed-off-by: Marian Balakowicz m8@semihalf.com ---
lib_ppc/ppc_linux.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 1013f9e..732f1f3 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -264,9 +264,9 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); hdr = (image_header_t *)of_flat_tree; #if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree + image_get_header_size())) != OF_DT_HEADER) { + if (*((ulong *)(of_flat_tree)) == OF_DT_HEADER) { #elif defined(CONFIG_OF_LIBFDT) - if (fdt_check_header(of_flat_tree + image_get_header_size()) != 0) { + if (fdt_check_header(of_flat_tree) == 0) { #endif #ifndef CFG_NO_FLASH if (addr2info((ulong)of_flat_tree) != NULL)

Move common, watchdog sensible memmove code to a helper memmmove_wd() routine.
Signed-off-by: Marian Balakowicz m8@semihalf.com ---
common/cmd_bootm.c | 20 ++++---------------- common/image.c | 18 ++++++++++++++++++ include/image.h | 1 + lib_m68k/m68k_linux.c | 23 ++++------------------- lib_ppc/ppc_linux.c | 22 ++++------------------ 5 files changed, 31 insertions(+), 53 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 40df9b0..7c3bb2f 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -250,24 +250,12 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (image_get_load(hdr) == addr) { printf (" XIP %s ... ", name); } else { -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - size_t l = len; - void *to = (void *)image_get_load(hdr); - void *from = (void *)data; - printf (" Loading %s ... ", name);
- while (l > 0) { - size_t tail = (l > CHUNKSZ) ? CHUNKSZ : l; - WATCHDOG_RESET(); - memmove (to, from, tail); - to += tail; - from += tail; - l -= tail; - } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - memmove ((void *)image_get_load(hdr), (uchar *)data, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ + memmove_wd((void *)image_get_load(hdr), + (void *)data, len, CHUNKSZ); + + puts("OK\n"); } break; case IH_COMP_GZIP: diff --git a/common/image.c b/common/image.c index 11470bb..7e862be 100644 --- a/common/image.c +++ b/common/image.c @@ -24,6 +24,7 @@ */ #ifndef USE_HOSTCC # include <common.h> +# include <watchdog.h> #else # include "mkimage.h" #endif @@ -56,6 +57,7 @@ int image_check_dcrc(image_header_t *hdr) return (dcrc == image_get_dcrc(hdr)); }
+#ifndef USE_HOSTCC int image_check_dcrc_wd(image_header_t *hdr, ulong chunksz) { ulong dcrc = 0; @@ -89,3 +91,19 @@ int getenv_verify(void) return (s && (*s == 'n')) ? 0 : 1; }
+void memmove_wd(void *to, void *from, size_t len, ulong chunksz) +{ +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + while (len > 0) { + size_t tail = (len > chunksz) ? chunksz : len; + WATCHDOG_RESET(); + memmove(to, from, tail); + to += tail; + from += tail; + len -= tail; + } +#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ + memmove(to, from, len); +#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ +} +#endif /* USE_HOSTCC */ diff --git a/include/image.h b/include/image.h index 00a4549..1c26a9c 100644 --- a/include/image.h +++ b/include/image.h @@ -251,6 +251,7 @@ int image_check_hcrc(image_header_t *); int image_check_dcrc(image_header_t *); int image_check_dcrc_wd(image_header_t *, ulong); int getenv_verify(void); +void memmove_wd(void *, void *, size_t, ulong);
static inline int image_check_magic(image_header_t *hdr) { diff --git a/lib_m68k/m68k_linux.c b/lib_m68k/m68k_linux.c index 237cd82..4ea74d7 100644 --- a/lib_m68k/m68k_linux.c +++ b/lib_m68k/m68k_linux.c @@ -266,25 +266,10 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, initrd_end = initrd_start + len; printf(" Loading Ramdisk to %08lx, end %08lx ... ", initrd_start, initrd_end); -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - { - size_t l = len; - void *to = (void *)initrd_start; - void *from = (void *)data; - - while (l > 0) { - size_t tail = - (l > CHUNKSZ) ? CHUNKSZ : l; - WATCHDOG_RESET(); - memmove(to, from, tail); - to += tail; - from += tail; - l -= tail; - } - } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - memmove((void *)initrd_start, (void *)data, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ + + memmove_wd((void *)initrd_start, + (void *)data, len, CHUNKSZ); + puts("OK\n"); } } else { diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 732f1f3..15349b3 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -425,24 +425,10 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, initrd_end = initrd_start + len; printf (" Loading Ramdisk to %08lx, end %08lx ... ", initrd_start, initrd_end); -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - { - size_t l = len; - void *to = (void *)initrd_start; - void *from = (void *)data; - - while (l > 0) { - size_t tail = (l > CHUNKSZ) ? CHUNKSZ : l; - WATCHDOG_RESET(); - memmove (to, from, tail); - to += tail; - from += tail; - l -= tail; - } - } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - memmove ((void *)initrd_start, (void *)data, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ + + memmove_wd((void *)initrd_start, + (void *)data, len, CHUNKSZ); + puts ("OK\n"); } } else {

common/cmd_autoscript.c common/cmd_bootm.c common/lynxkdi.c
- sort and cleanup headers, declarations, etc. - group related routines - cleanup indentation, white spaces
Signed-off-by: Marian Balakowicz m8@semihalf.com ---
common/cmd_autoscript.c | 32 +- common/cmd_bootm.c | 755 ++++++++++++++++++++++++----------------------- common/lynxkdi.c | 36 +- 3 files changed, 415 insertions(+), 408 deletions(-)
diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c index c1ff32a..5948cd5 100644 --- a/common/cmd_autoscript.c +++ b/common/cmd_autoscript.c @@ -49,8 +49,7 @@
#if defined(CONFIG_AUTOSCRIPT) || defined(CONFIG_CMD_AUTOSCRIPT)
-int -autoscript (ulong addr) +int autoscript(ulong addr) { ulong len; image_header_t *hdr = (image_header_t *)addr; @@ -93,18 +92,17 @@ autoscript (ulong addr)
debug ("** Script length: %ld\n", len);
- if ((cmd = malloc (len + 1)) == NULL) { + if ((cmd = malloc(len + 1)) == NULL) return 1; - }
while (*len_ptr++);
/* make sure cmd is null terminated */ - memmove (cmd, (char *)len_ptr, len); + memmove(cmd, (char *)len_ptr, len); *(cmd + len) = 0;
#ifdef CFG_HUSH_PARSER /*?? */ - rcode = parse_string_outer (cmd, FLAG_PARSE_SEMICOLON); + rcode = parse_string_outer(cmd, FLAG_PARSE_SEMICOLON); #else { char *line = cmd; @@ -120,9 +118,9 @@ autoscript (ulong addr) *next = '\0'; /* run only non-empty commands */ if ((next - line) > 1) { - debug ("** exec: "%s"\n", - line); - if (run_command (line, 0) < 0) { + debug("** exec: "%s"\n", + line); + if (run_command(line, 0) < 0) { rcode = 1; break; } @@ -133,7 +131,7 @@ autoscript (ulong addr) } } #endif - free (cmd); + free(cmd); return rcode; }
@@ -141,20 +139,18 @@ autoscript (ulong addr)
/**************************************************/ #if defined(CONFIG_CMD_AUTOSCRIPT) -int -do_autoscript (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_autoscript(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong addr; int rcode;
- if (argc < 2) { + if (argc < 2) addr = CFG_LOAD_ADDR; - } else { - addr = simple_strtoul (argv[1],0,16); - } + else + addr = simple_strtoul(argv[1], 0, 16);
- printf ("## Executing script at %08lx\n",addr); - rcode = autoscript (addr); + printf("## Executing script at %08lx\n",addr); + rcode = autoscript(addr); return rcode; }
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 7c3bb2f..51c67bb 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -44,11 +44,6 @@ #include <ft_build.h> #endif
-DECLARE_GLOBAL_DATA_PTR; - -/*cmd_boot.c*/ -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) #include <rtc.h> #endif @@ -61,23 +56,33 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #include <dataflash.h> #endif
-int gunzip (void *, int, unsigned char *, unsigned long *); +DECLARE_GLOBAL_DATA_PTR; + +extern int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp); +#ifndef CFG_BOOTM_LEN +#define CFG_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */ +#endif
#ifdef CONFIG_BZIP2 extern void bz_internal_error(int); #endif
#if defined(CONFIG_CMD_IMI) -static int image_info (unsigned long addr); +static int image_info(unsigned long addr); #endif
#if defined(CONFIG_CMD_IMLS) #include <flash.h> extern flash_info_t flash_info[]; /* info for FLASH chips */ -static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +#endif + +#ifdef CONFIG_SILENT_CONSOLE +static void fixup_silent_linux(void); #endif
-static void print_type (image_header_t *hdr); +static void print_type(image_header_t *hdr); +extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
/* * Continue booting an OS image; caller already has: @@ -87,42 +92,39 @@ static void print_type (image_header_t *hdr); * - loaded (first part of) image to header load address, * - disabled interrupts. */ -typedef void boot_os_Fcn (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, /* of image to boot */ - ulong *len_ptr, /* multi-file image length table */ - int verify); /* getenv("verify")[0] != 'n' */ - -extern boot_os_Fcn do_bootm_linux; - -#ifdef CONFIG_SILENT_CONSOLE -static void fixup_silent_linux (void); +typedef void boot_os_fn(cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong addr, /* of image to boot */ + ulong *len_ptr, /* multi-file image length table */ + int verify); /* getenv("verify")[0] != 'n' */ + +extern boot_os_fn do_bootm_linux; +static boot_os_fn do_bootm_netbsd; +#ifdef CONFIG_LYNXKDI +static boot_os_fn do_bootm_lynxkdi; +extern void lynxkdi_boot(image_header_t *); #endif -static boot_os_Fcn do_bootm_netbsd; -static boot_os_Fcn do_bootm_rtems; +static boot_os_fn do_bootm_rtems; #if defined(CONFIG_CMD_ELF) -static boot_os_Fcn do_bootm_vxworks; -static boot_os_Fcn do_bootm_qnxelf; -int do_bootvx ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] ); -int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] ); +static boot_os_fn do_bootm_vxworks; +static boot_os_fn do_bootm_qnxelf; +int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #endif #if defined(CONFIG_ARTOS) && defined(CONFIG_PPC) -static boot_os_Fcn do_bootm_artos; -#endif -#ifdef CONFIG_LYNXKDI -static boot_os_Fcn do_bootm_lynxkdi; -extern void lynxkdi_boot( image_header_t * ); -#endif - -#ifndef CFG_BOOTM_LEN -#define CFG_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */ +extern uchar (*env_get_char)(int); /* Returns a character from the environment */ +static boot_os_fn do_bootm_artos; #endif
image_header_t header;
-ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ +ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */
-int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) + +/*******************************************************************/ +/* bootm - boot application image from image in memory */ +/*******************************************************************/ +int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong iflag; ulong addr; @@ -142,8 +144,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) addr = simple_strtoul(argv[1], NULL, 16); }
- show_boot_progress (1); - printf ("## Booting image at %08lx ...\n", addr); + show_boot_progress(1); + printf("## Booting image at %08lx ...\n", addr);
/* Copy header so we can blank CRC field for re-calculation */ #ifdef CONFIG_HAS_DATAFLASH @@ -154,18 +156,18 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) memmove (&header, (char *)addr, image_get_header_size());
if (!image_check_magic(hdr)) { - puts ("Bad Magic Number\n"); - show_boot_progress (-1); + puts("Bad Magic Number\n"); + show_boot_progress(-1); return 1; } - show_boot_progress (2); + show_boot_progress(2);
if (!image_check_hcrc(hdr)) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-2); + puts("Bad Header Checksum\n"); + show_boot_progress(-2); return 1; } - show_boot_progress (3); + show_boot_progress(3);
#ifdef CONFIG_HAS_DATAFLASH if (addr_dataflash(addr)){ @@ -175,7 +177,6 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } #endif
- /* for multi-file images we need the data part, too */ print_image_hdr((image_header_t *)addr);
@@ -184,30 +185,29 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) len_ptr = (ulong *)data;
if (verify) { - puts (" Verifying Checksum ... "); + puts(" Verifying Checksum ... "); if (!image_check_dcrc((image_header_t *)addr)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-3); + printf("Bad Data CRC\n"); + show_boot_progress(-3); return 1; } - puts ("OK\n"); + puts("OK\n"); } - show_boot_progress (4); + show_boot_progress(4);
if (!image_check_target_arch(hdr)) { - printf ("Unsupported Architecture 0x%x\n", image_get_arch(hdr)); - show_boot_progress (-4); + printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr)); + show_boot_progress(-4); return 1; } - show_boot_progress (5); + show_boot_progress(5);
switch (image_get_type(hdr)) { case IH_TYPE_STANDALONE: name = "Standalone Application"; /* A second argument overwrites the load address */ - if (argc > 2) { + if (argc > 2) image_set_load(hdr, simple_strtoul(argv[2], NULL, 16)); - } break; case IH_TYPE_KERNEL: name = "Kernel Image"; @@ -220,18 +220,18 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) for (i=1; len_ptr[i]; ++i) data += 4; break; - default: printf ("Wrong Image Type for %s command\n", cmdtp->name); - show_boot_progress (-5); + default: + printf("Wrong Image Type for %s command\n", cmdtp->name); + show_boot_progress(-5); return 1; } - show_boot_progress (6); + show_boot_progress(6);
/* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ - iflag = disable_interrupts();
#ifdef CONFIG_AMIGAONEG3SE @@ -248,9 +248,9 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) switch (image_get_comp(hdr)) { case IH_COMP_NONE: if (image_get_load(hdr) == addr) { - printf (" XIP %s ... ", name); + printf(" XIP %s ... ", name); } else { - printf (" Loading %s ... ", name); + printf(" Loading %s ... ", name);
memmove_wd((void *)image_get_load(hdr), (void *)data, len, CHUNKSZ); @@ -259,41 +259,41 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } break; case IH_COMP_GZIP: - printf (" Uncompressing %s ... ", name); - if (gunzip ((void *)image_get_load(hdr), unc_len, + printf(" Uncompressing %s ... ", name); + if (gunzip((void *)image_get_load(hdr), unc_len, (uchar *)data, &len) != 0) { - puts ("GUNZIP ERROR - must RESET board to recover\n"); - show_boot_progress (-6); - do_reset (cmdtp, flag, argc, argv); + puts("GUNZIP ERROR - must RESET board to recover\n"); + show_boot_progress(-6); + do_reset(cmdtp, flag, argc, argv); } break; #ifdef CONFIG_BZIP2 case IH_COMP_BZIP2: - printf (" Uncompressing %s ... ", name); + printf(" Uncompressing %s ... ", name); /* * If we've got less than 4 MB of malloc() space, * use slower decompression algorithm which requires * at most 2300 KB of memory. */ - i = BZ2_bzBuffToBuffDecompress ((char*)image_get_load(hdr), + i = BZ2_bzBuffToBuffDecompress((char*)image_get_load(hdr), &unc_len, (char *)data, len, CFG_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { - printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i); - show_boot_progress (-6); - do_reset (cmdtp, flag, argc, argv); + printf("BUNZIP2 ERROR %d - must RESET board to recover\n", i); + show_boot_progress(-6); + do_reset(cmdtp, flag, argc, argv); } break; #endif /* CONFIG_BZIP2 */ default: if (iflag) enable_interrupts(); - printf ("Unimplemented compression type %d\n", image_get_comp(hdr)); - show_boot_progress (-7); + printf("Unimplemented compression type %d\n", image_get_comp(hdr)); + show_boot_progress(-7); return 1; } - puts ("OK\n"); - show_boot_progress (7); + puts("OK\n"); + show_boot_progress(7);
switch (image_get_type(hdr)) { case IH_TYPE_STANDALONE: @@ -319,11 +319,11 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) default: if (iflag) enable_interrupts(); - printf ("Can't boot image type %d\n", image_get_type(hdr)); - show_boot_progress (-8); + printf("Can't boot image type %d\n", image_get_type(hdr)); + show_boot_progress(-8); return 1; } - show_boot_progress (8); + show_boot_progress(8);
switch (image_get_os(hdr)) { default: /* handled by (original) Linux case */ @@ -331,58 +331,60 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #ifdef CONFIG_SILENT_CONSOLE fixup_silent_linux(); #endif - do_bootm_linux (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_linux(cmdtp, flag, argc, argv, + addr, len_ptr, verify); break; + case IH_OS_NETBSD: - do_bootm_netbsd (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_netbsd(cmdtp, flag, argc, argv, + addr, len_ptr, verify); break;
#ifdef CONFIG_LYNXKDI case IH_OS_LYNXOS: - do_bootm_lynxkdi (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_lynxkdi(cmdtp, flag, argc, argv, + addr, len_ptr, verify); break; #endif
case IH_OS_RTEMS: - do_bootm_rtems (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_rtems(cmdtp, flag, argc, argv, + addr, len_ptr, verify); break;
#if defined(CONFIG_CMD_ELF) case IH_OS_VXWORKS: - do_bootm_vxworks (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_vxworks(cmdtp, flag, argc, argv, + addr, len_ptr, verify); break; case IH_OS_QNX: - do_bootm_qnxelf (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_qnxelf(cmdtp, flag, argc, argv, + addr, len_ptr, verify); break; #endif + #ifdef CONFIG_ARTOS case IH_OS_ARTOS: - do_bootm_artos (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_artos(cmdtp, flag, argc, argv, + addr, len_ptr, verify); break; #endif }
- show_boot_progress (-9); + show_boot_progress(-9); #ifdef DEBUG - puts ("\n## Control returned to monitor - resetting...\n"); - do_reset (cmdtp, flag, argc, argv); + puts("\n## Control returned to monitor - resetting...\n"); + do_reset(cmdtp, flag, argc, argv); #endif return 1; }
U_BOOT_CMD( - bootm, CFG_MAXARGS, 1, do_bootm, - "bootm - boot application image from memory\n", - "[addr [arg ...]]\n - boot application image stored in memory\n" - "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n" - "\t'arg' can be the address of an initrd image\n" + bootm, CFG_MAXARGS, 1, do_bootm, + "bootm - boot application image from memory\n", + "[addr [arg ...]]\n - boot application image stored in memory\n" + "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n" + "\t'arg' can be the address of an initrd image\n" #if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) "\tWhen booting a Linux kernel which requires a flat device-tree\n" "\ta third argument is required which is the address of the\n" @@ -392,279 +394,88 @@ U_BOOT_CMD( #endif );
-#ifdef CONFIG_SILENT_CONSOLE -static void -fixup_silent_linux () -{ - char buf[256], *start, *end; - char *cmdline = getenv ("bootargs"); - - /* Only fix cmdline when requested */ - if (!(gd->flags & GD_FLG_SILENT)) - return; - - debug ("before silent fix-up: %s\n", cmdline); - if (cmdline) { - if ((start = strstr (cmdline, "console=")) != NULL) { - end = strchr (start, ' '); - strncpy (buf, cmdline, (start - cmdline + 8)); - if (end) - strcpy (buf + (start - cmdline + 8), end); - else - buf[start - cmdline + 8] = '\0'; - } else { - strcpy (buf, cmdline); - strcat (buf, " console="); - } - } else { - strcpy (buf, "console="); - } - - setenv ("bootargs", buf); - debug ("after silent fix-up: %s\n", buf); -} -#endif /* CONFIG_SILENT_CONSOLE */ - -static void -do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, - ulong *len_ptr, - int verify) -{ - image_header_t *hdr = &header; - - void (*loader)(bd_t *, image_header_t *, char *, char *); - image_header_t *img_addr; - char *consdev; - char *cmdline; - - - /* - * Booting a (NetBSD) kernel image - * - * This process is pretty similar to a standalone application: - * The (first part of an multi-) image must be a stage-2 loader, - * which in turn is responsible for loading & invoking the actual - * kernel. The only differences are the parameters being passed: - * besides the board info strucure, the loader expects a command - * line, the name of the console device, and (optionally) the - * address of the original image header. - */ - - img_addr = 0; - if ((image_check_type(hdr, IH_TYPE_MULTI)) && (len_ptr[1])) - img_addr = (image_header_t *) addr; - - - consdev = ""; -#if defined (CONFIG_8xx_CONS_SMC1) - consdev = "smc1"; -#elif defined (CONFIG_8xx_CONS_SMC2) - consdev = "smc2"; -#elif defined (CONFIG_8xx_CONS_SCC2) - consdev = "scc2"; -#elif defined (CONFIG_8xx_CONS_SCC3) - consdev = "scc3"; -#endif - - if (argc > 2) { - ulong len; - int i; - - for (i=2, len=0 ; i<argc ; i+=1) - len += strlen (argv[i]) + 1; - cmdline = malloc (len); - - for (i=2, len=0 ; i<argc ; i+=1) { - if (i > 2) - cmdline[len++] = ' '; - strcpy (&cmdline[len], argv[i]); - len += strlen (argv[i]); - } - } else if ((cmdline = getenv("bootargs")) == NULL) { - cmdline = ""; - } - - loader = (void (*)(bd_t *, image_header_t *, char *, char *))image_get_ep(hdr); - - printf ("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n", - (ulong)loader); - - show_boot_progress (15); - - /* - * NetBSD Stage-2 Loader Parameters: - * r3: ptr to board info data - * r4: image address - * r5: console device - * r6: boot args string - */ - (*loader) (gd->bd, img_addr, consdev, cmdline); -} - -#if defined(CONFIG_ARTOS) && defined(CONFIG_PPC) - -/* Function that returns a character from the environment */ -extern uchar (*env_get_char)(int); - -static void -do_bootm_artos (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, - ulong *len_ptr, - int verify) -{ - ulong top; - char *s, *cmdline; - char **fwenv, **ss; - 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 = &header; - - /* - * Booting an ARTOS kernel image + application - */ - - /* this used to be the top of memory, but was wrong... */ -#ifdef CONFIG_PPC - /* get stack pointer */ - asm volatile ("mr %0,1" : "=r"(top) ); -#endif - debug ("## Current stack ends at 0x%08lX ", top); - - top -= 2048; /* just to be sure */ - if (top > CFG_BOOTMAPSZ) - top = CFG_BOOTMAPSZ; - top &= ~0xF; - - debug ("=> set upper limit to 0x%08lX\n", top); - - /* first check the artos specific boot args, then the linux args*/ - if ((s = getenv("abootargs")) == NULL && (s = getenv("bootargs")) == NULL) - s = ""; - - /* get length of cmdline, and place it */ - len = strlen(s); - top = (top - (len + 1)) & ~0xF; - cmdline = (char *)top; - debug ("## cmdline at 0x%08lX ", top); - strcpy(cmdline, s); - - /* copy bdinfo */ - top = (top - sizeof(bd_t)) & ~0xF; - debug ("## bd at 0x%08lX ", top); - kbd = (bd_t *)top; - memcpy(kbd, gd->bd, sizeof(bd_t)); - - /* first find number of env entries, and their size */ - envno = 0; - envsz = 0; - for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { - for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) - ; - envno++; - envsz += (nxt - i) + 1; /* plus trailing zero */ - } - envno++; /* plus the terminating zero */ - debug ("## %u envvars total size %u ", envno, envsz); - - top = (top - sizeof(char **)*envno) & ~0xF; - fwenv = (char **)top; - debug ("## fwenv at 0x%08lX ", top); - - top = (top - envsz) & ~0xF; - s = (char *)top; - ss = fwenv; - - /* now copy them */ - for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { - for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) - ; - *ss++ = s; - for (j = i; j < nxt; ++j) - *s++ = env_get_char(j); - *s++ = '\0'; - } - *ss++ = NULL; /* terminate */ - - entry = (void (*)(bd_t *, char *, char **, ulong))image_get_ep(hdr); - (*entry)(kbd, cmdline, fwenv, top); -} -#endif -
+/*******************************************************************/ +/* bootd - boot default image */ +/*******************************************************************/ #if defined(CONFIG_CMD_BOOTD) -int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int rcode = 0; + #ifndef CFG_HUSH_PARSER - if (run_command (getenv ("bootcmd"), flag) < 0) rcode = 1; + if (run_command(getenv("bootcmd"), flag) < 0) + rcode = 1; #else if (parse_string_outer(getenv("bootcmd"), - FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0 ) rcode = 1; + FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0) + rcode = 1; #endif return rcode; }
U_BOOT_CMD( - boot, 1, 1, do_bootd, - "boot - boot default, i.e., run 'bootcmd'\n", + boot, 1, 1, do_bootd, + "boot - boot default, i.e., run 'bootcmd'\n", NULL );
/* keep old command name "bootd" for backward compatibility */ U_BOOT_CMD( - bootd, 1, 1, do_bootd, - "bootd - boot default, i.e., run 'bootcmd'\n", + bootd, 1, 1, do_bootd, + "bootd - boot default, i.e., run 'bootcmd'\n", NULL );
#endif
+ +/*******************************************************************/ +/* iminfo - print header info for a requested image */ +/*******************************************************************/ #if defined(CONFIG_CMD_IMI) -int do_iminfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_iminfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - int arg; - ulong addr; - int rcode=0; + int arg; + ulong addr; + int rcode = 0;
if (argc < 2) { return image_info (load_addr); }
- for (arg=1; arg <argc; ++arg) { + for (arg = 1; arg < argc; ++arg) { addr = simple_strtoul(argv[arg], NULL, 16); - if (image_info (addr) != 0) rcode = 1; + if (image_info (addr) != 0) + rcode = 1; } return rcode; }
-static int image_info (ulong addr) +static int image_info(ulong addr) { image_header_t *hdr = (image_header_t *)addr;
- printf ("\n## Checking Image at %08lx ...\n", addr); + printf("\n## Checking Image at %08lx ...\n", addr);
if (!image_check_magic(hdr)) { - puts (" Bad Magic Number\n"); + puts(" Bad Magic Number\n"); return 1; }
if (!image_check_hcrc(hdr)) { - puts (" Bad Header Checksum\n"); + puts(" Bad Header Checksum\n"); return 1; }
print_image_hdr(hdr);
- puts (" Verifying Checksum ... "); + puts(" Verifying Checksum ... "); if (!image_check_dcrc(hdr)) { - puts (" Bad Data CRC\n"); + puts(" Bad Data CRC\n"); return 1; } - puts ("OK\n"); + puts("OK\n"); return 0; }
@@ -676,23 +487,25 @@ U_BOOT_CMD( " address 'addr' in memory; this includes verification of the\n" " image contents (magic number, header and payload checksums)\n" ); - #endif
+ +/*******************************************************************/ +/* imls - list all images found in flash */ +/*******************************************************************/ #if defined(CONFIG_CMD_IMLS) -/*----------------------------------------------------------------------- - * List all images found in flash. - */ -int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { flash_info_t *info; int i, j; image_header_t *hdr;
- for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) { + for (i = 0, info = &flash_info[0]; + i < CFG_MAX_FLASH_BANKS; ++i, ++info) { + if (info->flash_id == FLASH_UNKNOWN) goto next_bank; - for (j=0; j<info->sector_count; ++j) { + for (j = 0; j < info->sector_count; ++j) {
hdr = (image_header_t *)info->start[j];
@@ -702,14 +515,14 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (!image_check_hcrc(hdr)) goto next_sector;
- printf ("Image at %08lX:\n", (ulong)hdr); + printf("Image at %08lX:\n", (ulong)hdr); print_image_hdr( hdr );
- puts (" Verifying Checksum ... "); + puts(" Verifying Checksum ... "); if (!image_check_dcrc(hdr)) - puts ("Bad Data CRC\n"); + puts("Bad Data CRC\n"); else - puts ("OK\n"); + puts("OK\n"); next_sector: ; } next_bank: ; @@ -727,26 +540,31 @@ U_BOOT_CMD( ); #endif
-void -print_image_hdr (image_header_t *hdr) +/*******************************************************************/ +/* */ +/*******************************************************************/ +void print_image_hdr(image_header_t *hdr) { #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) time_t timestamp = (time_t)image_get_time(hdr); struct rtc_time tm; #endif
- printf (" Image Name: %.*s\n", IH_NMLEN, image_get_name(hdr)); + printf(" Image Name: %.*s\n", IH_NMLEN, image_get_name(hdr)); + #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) to_tm (timestamp, &tm); - printf (" Created: %4d-%02d-%02d %2d:%02d:%02d UTC\n", + printf(" Created: %4d-%02d-%02d %2d:%02d:%02d UTC\n", tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); #endif - puts (" Image Type: "); print_type(hdr); - printf ("\n Data Size: %d Bytes = ", image_get_data_size(hdr)); + puts(" Image Type: "); + print_type(hdr); + + printf("\n Data Size: %d Bytes = ", image_get_data_size(hdr)); print_size (image_get_data_size(hdr), "\n"); - printf (" Load Address: %08x\n" - " Entry Point: %08x\n", + + printf(" Load Address: %08x\n Entry Point: %08x\n", image_get_load(hdr), image_get_ep(hdr));
if (image_check_type(hdr, IH_TYPE_MULTI)) { @@ -754,17 +572,15 @@ print_image_hdr (image_header_t *hdr) ulong len; ulong *len_ptr = (ulong *)((ulong)hdr + image_get_header_size());
- puts (" Contents:\n"); - for (i=0; (len = image_to_cpu(*len_ptr)); ++i, ++len_ptr) { - printf (" Image %d: %8ld Bytes = ", i, len); + puts(" Contents:\n"); + for (i = 0; (len = image_to_cpu(*len_ptr)); ++i, ++len_ptr) { + printf(" Image %d: %8ld Bytes = ", i, len); print_size (len, "\n"); } } }
- -static void -print_type (image_header_t *hdr) +static void print_type(image_header_t *hdr) { char *os, *arch, *type, *comp;
@@ -826,35 +642,157 @@ print_type (image_header_t *hdr) default: comp = "unknown compression"; break; }
- printf ("%s %s %s (%s)", arch, os, type, comp); + printf("%s %s %s (%s)", arch, os, type, comp); +} + +#ifdef CONFIG_SILENT_CONSOLE +static void fixup_silent_linux() +{ + char buf[256], *start, *end; + char *cmdline = getenv ("bootargs"); + + /* Only fix cmdline when requested */ + if (!(gd->flags & GD_FLG_SILENT)) + return; + + debug("before silent fix-up: %s\n", cmdline); + if (cmdline) { + if ((start = strstr (cmdline, "console=")) != NULL) { + end = strchr (start, ' '); + strncpy (buf, cmdline, (start - cmdline + 8)); + if (end) + strcpy (buf + (start - cmdline + 8), end); + else + buf[start - cmdline + 8] = '\0'; + } else { + strcpy (buf, cmdline); + strcat (buf, " console="); + } + } else { + strcpy (buf, "console="); + } + + setenv ("bootargs", buf); + debug("after silent fix-up: %s\n", buf); +} +#endif /* CONFIG_SILENT_CONSOLE */ + + +/*******************************************************************/ +/* OS booting routines */ +/*******************************************************************/ + +static void do_bootm_netbsd(cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong addr, ulong *len_ptr, + int verify) +{ + image_header_t *hdr = &header; + + void (*loader)(bd_t *, image_header_t *, char *, char *); + image_header_t *img_addr; + char *consdev; + char *cmdline; + + /* + * Booting a (NetBSD) kernel image + * + * This process is pretty similar to a standalone application: + * The (first part of an multi-) image must be a stage-2 loader, + * which in turn is responsible for loading & invoking the actual + * kernel. The only differences are the parameters being passed: + * besides the board info strucure, the loader expects a command + * line, the name of the console device, and (optionally) the + * address of the original image header. + */ + + img_addr = 0; + if ((image_check_type(hdr, IH_TYPE_MULTI)) && (len_ptr[1])) + img_addr = (image_header_t *)addr; + + consdev = ""; +#if defined (CONFIG_8xx_CONS_SMC1) + consdev = "smc1"; +#elif defined (CONFIG_8xx_CONS_SMC2) + consdev = "smc2"; +#elif defined (CONFIG_8xx_CONS_SCC2) + consdev = "scc2"; +#elif defined (CONFIG_8xx_CONS_SCC3) + consdev = "scc3"; +#endif + + if (argc > 2) { + ulong len; + int i; + + for (i = 2, len = 0; i < argc; i += 1) + len += strlen(argv[i]) + 1; + cmdline = malloc(len); + + for (i = 2, len = 0; i < argc; i += 1) { + if (i > 2) + cmdline[len++] = ' '; + strcpy(&cmdline[len], argv[i]); + len += strlen(argv[i]); + } + } else if ((cmdline = getenv("bootargs")) == NULL) { + cmdline = ""; + } + + loader = (void (*)(bd_t *, image_header_t *, char *, char *))image_get_ep(hdr); + + printf("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n", + (ulong)loader); + + show_boot_progress(15); + + /* + * NetBSD Stage-2 Loader Parameters: + * r3: ptr to board info data + * r4: image address + * r5: console device + * r6: boot args string + */ + (*loader) (gd->bd, img_addr, consdev, cmdline); +} + +#ifdef CONFIG_LYNXKDI +static void do_bootm_lynxkdi(cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong addr, ulong *len_ptr, + int verify) +{ + lynxkdi_boot(&header); } +#endif /* CONFIG_LYNXKDI */
-static void -do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) +static void do_bootm_rtems(cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong addr, ulong *len_ptr, + int verify) { image_header_t *hdr = &header; - void (*entry_point)(bd_t *); + void (*entry_point)(bd_t *);
entry_point = (void (*)(bd_t *))image_get_ep(hdr);
- printf ("## Transferring control to RTEMS (at address %08lx) ...\n", + printf("## Transferring control to RTEMS (at address %08lx) ...\n", (ulong)entry_point);
- show_boot_progress (15); + show_boot_progress(15);
/* * RTEMS Parameters: * r3: ptr to board info data */ - - (*entry_point ) ( gd->bd ); + (*entry_point)(gd->bd); }
#if defined(CONFIG_CMD_ELF) -static void -do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) +static void do_bootm_vxworks(cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong addr, ulong *len_ptr, + int verify) { image_header_t *hdr = &header; char str[80]; @@ -864,9 +802,10 @@ do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], do_bootvx(cmdtp, 0, 0, NULL); }
-static void -do_bootm_qnxelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) +static void do_bootm_qnxelf (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong addr, ulong *len_ptr, + int verify) { image_header_t *hdr = &header; char *local_args[2]; @@ -879,15 +818,87 @@ do_bootm_qnxelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } #endif
-#ifdef CONFIG_LYNXKDI -static void -do_bootm_lynxkdi (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, - ulong *len_ptr, - int verify) +#if defined(CONFIG_ARTOS) && defined(CONFIG_PPC) +static void do_bootm_artos(cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong addr, ulong *len_ptr, + int verify) { - lynxkdi_boot( &header ); -} + ulong top; + char *s, *cmdline; + char **fwenv, **ss; + 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 = &header;
-#endif /* CONFIG_LYNXKDI */ + /* + * Booting an ARTOS kernel image + application + */ + + /* this used to be the top of memory, but was wrong... */ +#ifdef CONFIG_PPC + /* get stack pointer */ + asm volatile ("mr %0,1" : "=r"(top) ); +#endif + debug("## Current stack ends at 0x%08lX ", top); + + top -= 2048; /* just to be sure */ + if (top > CFG_BOOTMAPSZ) + top = CFG_BOOTMAPSZ; + top &= ~0xF; + + debug("=> set upper limit to 0x%08lX\n", top); + + /* first check the artos specific boot args, then the linux args*/ + if ((s = getenv("abootargs")) == NULL && (s = getenv("bootargs")) == NULL) + s = ""; + + /* get length of cmdline, and place it */ + len = strlen(s); + top = (top - (len + 1)) & ~0xF; + cmdline = (char *)top; + debug("## cmdline at 0x%08lX ", top); + strcpy(cmdline, s); + + /* copy bdinfo */ + top = (top - sizeof(bd_t)) & ~0xF; + debug("## bd at 0x%08lX ", top); + kbd = (bd_t *)top; + memcpy(kbd, gd->bd, sizeof(bd_t)); + + /* first find number of env entries, and their size */ + envno = 0; + envsz = 0; + for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { + for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) + ; + envno++; + envsz += (nxt - i) + 1; /* plus trailing zero */ + } + envno++; /* plus the terminating zero */ + debug("## %u envvars total size %u ", envno, envsz); + + top = (top - sizeof(char **)*envno) & ~0xF; + fwenv = (char **)top; + debug("## fwenv at 0x%08lX ", top); + + top = (top - envsz) & ~0xF; + s = (char *)top; + ss = fwenv; + + /* now copy them */ + for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { + for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) + ; + *ss++ = s; + for (j = i; j < nxt; ++j) + *s++ = env_get_char(j); + *s++ = '\0'; + } + *ss++ = NULL; /* terminate */ + + entry = (void (*)(bd_t *, char *, char **, ulong))image_get_ep(hdr); + (*entry)(kbd, cmdline, fwenv, top); +} +#endif diff --git a/common/lynxkdi.c b/common/lynxkdi.c index 62b2a04..5516f85 100644 --- a/common/lynxkdi.c +++ b/common/lynxkdi.c @@ -23,14 +23,14 @@ DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR) -void lynxkdi_boot ( image_header_t *hdr ) +void lynxkdi_boot(image_header_t *hdr) { void (*lynxkdi)(void) = (void(*)(void))image_get_ep(hdr); lynxos_bootparms_t *parms = (lynxos_bootparms_t *)0x0020; bd_t *kbd; u32 *psz = (u32 *)(image_get_load(hdr) + 0x0204);
- memset( parms, 0, sizeof(*parms)); + memset(parms, 0, sizeof(*parms)); kbd = gd->bd; parms->clock_ref = kbd->bi_busfreq; parms->dramsz = kbd->bi_memsize; @@ -40,25 +40,25 @@ void lynxkdi_boot ( image_header_t *hdr ) /* Do a simple check for Bluecat so we can pass the * kernel command line parameters. */ - if( le32_to_cpu(*psz) == image_get_data_size(hdr) ){ /* FIXME: NOT SURE HERE ! */ - char *args; - char *cmdline = (char *)(image_get_load(hdr) + 0x020c); - int len; + if (le32_to_cpu(*psz) == image_get_data_size(hdr)) { /* FIXME: NOT SURE HERE ! */ + char *args; + char *cmdline = (char *)(image_get_load(hdr) + 0x020c); + int len;
- printf("Booting Bluecat KDI ...\n"); - udelay(200*1000); /* Allow serial port to flush */ - if ((args = getenv("bootargs")) == NULL) - args = ""; - /* Prepend the cmdline */ - len = strlen(args); - if( len && (len + strlen(cmdline) + 2 < (0x0400 - 0x020c))) { - memmove( cmdline + strlen(args) + 1, cmdline, strlen(cmdline) ); - strcpy( cmdline, args ); - cmdline[len] = ' '; - } + printf("Booting Bluecat KDI ...\n"); + udelay(200*1000); /* Allow serial port to flush */ + if ((args = getenv("bootargs")) == NULL) + args = ""; + /* Prepend the cmdline */ + len = strlen(args); + if( len && (len + strlen(cmdline) + 2 < (0x0400 - 0x020c))) { + memmove( cmdline + strlen(args) + 1, cmdline, strlen(cmdline) ); + strcpy( cmdline, args ); + cmdline[len] = ' '; + } } else { - printf("Booting LynxOS KDI ...\n"); + printf("Booting LynxOS KDI ...\n"); }
lynxkdi();

In message 20080111143021.8025.70916.stgit@hekate.izotz.org you wrote:
common/cmd_autoscript.c common/cmd_bootm.c common/lynxkdi.c
- sort and cleanup headers, declarations, etc.
- group related routines
- cleanup indentation, white spaces
Be careful!
- memmove (cmd, (char *)len_ptr, len);
- memmove(cmd, (char *)len_ptr, len);
...
- rcode = parse_string_outer (cmd, FLAG_PARSE_SEMICOLON);
- rcode = parse_string_outer(cmd, FLAG_PARSE_SEMICOLON);
...
debug ("** exec: \"%s\"\n",
debug("** exec: \"%s\"\n",
...
- free (cmd);
- free(cmd);
This is not a cleanup, this makes it (IMO) worse. Please undo.
- int arg;
- ulong addr;
- int rcode=0;
- int arg;
- ulong addr;
- int rcode = 0;
Do you really think the new code is better or cleaner? It's just uglier.
Please undo.
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
In message 20080111143021.8025.70916.stgit@hekate.izotz.org you wrote:
[snip]
- int arg;
- ulong addr;
- int rcode=
- int arg;
- ulong addr;
- int rcode =;
Do you really think the new code is better or cleaner? It's just uglier.
Please undo.
Best regards,
Wolfgang Denk
Hi Wolfgang,
I agree the change is uglier. Unfortunately, running a file through Lindent does this. (My personal coding style uses much more whitespace than the Linux style, so sometimes I need to run Lindent to remove spaces my fingers put in automatically.)
Maybe the coding style should be "run 'Lindent -pcs', then undo the following...". I'll admit that I'm already removing all the tabs that Lindent inserts before comment in the case of
#endif /* defined(FOO) */
Best regards, Larry

Wolfgang Denk wrote:
In message 20080111143021.8025.70916.stgit@hekate.izotz.org you wrote:
common/cmd_autoscript.c common/cmd_bootm.c common/lynxkdi.c
- sort and cleanup headers, declarations, etc.
- group related routines
- cleanup indentation, white spaces
Be careful!
[snip]
This is not a cleanup, this makes it (IMO) worse. Please undo.
[snip]
Do you really think the new code is better or cleaner? It's just uglier.
Thanks for pointing this out, will fix this.
Cheers, m.

- use single image header pointer instead of a set of auxilliary variables. - add multi component image helper routines: get component size/data address
Signed-off-by: Marian Balakowicz m8@semihalf.com ---
common/cmd_autoscript.c | 10 +- common/cmd_bootm.c | 162 ++++++++++++++-------------------- common/image.c | 85 ++++++++++++++++++ include/image.h | 25 +++++ lib_arm/armlinux.c | 92 ++++++++----------- lib_avr32/avr32_linux.c | 70 +++++---------- lib_blackfin/bf533_linux.c | 4 - lib_i386/i386_linux.c | 81 +++++++---------- lib_m68k/m68k_linux.c | 82 +++++++---------- lib_microblaze/microblaze_linux.c | 71 ++++++--------- lib_mips/mips_linux.c | 68 +++++--------- lib_nios/nios_linux.c | 2 lib_nios2/nios_linux.c | 7 - lib_ppc/ppc_linux.c | 176 +++++++++++++++---------------------- 14 files changed, 440 insertions(+), 495 deletions(-)
This patch size is over 40K list limit, please refer to: http://semihalf.com/~m8/new-image/patchset1/12-multi_helpers-single_hdr.patc...

Check for overwrites during image move/uncompress, return with error when the original image gets corrupted. Report clear message to the user and prevent further troubles when pointer to the corrupted images is passed to do_bootm_linux routine.
Signed-off-by: Marian Balakowicz m8@semihalf.com ---
common/cmd_bootm.c | 23 ++++++++++++++++++++++- lib_ppc/ppc_linux.c | 14 ++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 6a9d5ad..b5f7526 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -133,6 +133,10 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong img_addr; ulong os_data, os_len;
+ ulong image_start, image_end; + ulong load_start, load_end; + + if (argc < 2) img_addr = load_addr; else @@ -232,16 +236,21 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) dcache_disable(); #endif
+ image_start = (ulong)hdr; + image_end = image_get_image_end(hdr); + load_start = image_get_load(hdr); + load_end = 0; + switch (image_get_comp(hdr)) { case IH_COMP_NONE: if (image_get_load(hdr) == img_addr) { printf(" XIP %s ... ", name); } else { printf(" Loading %s ... ", name); - memmove_wd((void *)image_get_load(hdr), (void *)os_data, os_len, CHUNKSZ);
+ load_end = load_start + os_len; puts("OK\n"); } break; @@ -253,6 +262,8 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress(-6); do_reset(cmdtp, flag, argc, argv); } + + load_end = load_start + os_len; break; #ifdef CONFIG_BZIP2 case IH_COMP_BZIP2: @@ -270,6 +281,8 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress(-6); do_reset(cmdtp, flag, argc, argv); } + + load_end = load_start + unc_len; break; #endif /* CONFIG_BZIP2 */ default: @@ -282,6 +295,14 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) puts("OK\n"); show_boot_progress(7);
+ if ((load_start < image_end) && (load_end > image_start)) { + 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"); + do_reset (cmdtp, flag, argc, argv); + } + switch (image_get_type(hdr)) { case IH_TYPE_STANDALONE: if (iflag) diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 56cdcc8..e0b55db 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -23,6 +23,8 @@ * MA 02111-1307 USA */
+#define DEBUG + #include <common.h> #include <watchdog.h> #include <command.h> @@ -259,11 +261,19 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, of_data = (ulong)of_flat_tree; #endif } else if (image_check_magic(fdt_hdr)) { + ulong image_start, image_end; + ulong load_start, load_end; + printf("## Flat Device Tree at %08lX\n", fdt_hdr); print_image_hdr(fdt_hdr);
- if ((image_get_load(fdt_hdr) < image_get_image_end(fdt_hdr)) && - ((image_get_load(fdt_hdr) + image_get_data_size(fdt_hdr)) > (unsigned long)fdt_hdr)) { + image_start = (ulong)fdt_hdr; + image_end = image_get_image_end(fdt_hdr); + + load_start = image_get_load(fdt_hdr); + load_end = load_start + image_get_data_size(fdt_hdr); + + if ((load_start < image_end) && (load_end > image_start)) { puts ("ERROR: fdt overwritten - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv);

In message 20080111143054.8025.33808.stgit@hekate.izotz.org you wrote:
Check for overwrites during image move/uncompress, return with error when the original image gets corrupted. Report clear message to the user and prevent further troubles when pointer to the corrupted images is passed to do_bootm_linux routine.
Does this really work? With compressed images?
image_start = (ulong)fdt_hdr;
image_end = image_get_image_end(fdt_hdr);
load_start = image_get_load(fdt_hdr);
load_end = load_start + image_get_data_size(fdt_hdr);
if ((load_start < image_end) && (load_end > image_start)) { puts ("ERROR: fdt overwritten - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv);
Me thinks that load_end gives a value which does not take into account that the loaded, uncompressed image will be much bigger than image_get_data_size() tells - or am I missing something?
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
In message 20080111143054.8025.33808.stgit@hekate.izotz.org you wrote:
Check for overwrites during image move/uncompress, return with error when the original image gets corrupted. Report clear message to the user and prevent further troubles when pointer to the corrupted images is passed to do_bootm_linux routine.
Does this really work? With compressed images?
Yes it does, I tested it with compressed linux kernel images.
image_start = (ulong)fdt_hdr;
image_end = image_get_image_end(fdt_hdr);
load_start = image_get_load(fdt_hdr);
load_end = load_start + image_get_data_size(fdt_hdr);
if ((load_start < image_end) && (load_end > image_start)) { puts ("ERROR: fdt overwritten - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv);
Me thinks that load_end gives a value which does not take into account that the loaded, uncompressed image will be much bigger than image_get_data_size() tells - or am I missing something?
That part of the patch deals with the FDT blob image. Compressed blobs are not supported in the current code, so no decompression happens and we can use image_get_data_size(). BTW, this particular overwrite check is already present in the current U-boot.
Cheers, m.

On Friday 11 January 2008, Marian Balakowicz wrote:
This is a first set of patches that provides a initial cleanup and code rearrangements before the proper new uImage format implementation.
API is defined for the current (old) image related processing, and it'is being introduced in place of the direct header access.
[new uImage] Return error on image move/uncompress overwrites [new uImage] Cleanup image header pointer use in bootm code [new uImage] Coding style cleanup - part 1 [new uImage] Add memmove_wd() common routine [new uImage] Fix FDT header verification in PPC do_boot_linux() routine [new uImage] Fix uImage header pointer use in i386 do_bootm_linux() [new uImage] Remove I386 uImage fake_header() routine [new uImage] Move CHUNKSZ definition to image.h [new uImage] Move gunzip() common code to common/gunzip.c [new uImage] Cleanup OF/FDT #if/#elif/#endif use in do_bootm_linux() [new uImage] Move PPC do_bootm_linux() to lib_ppc/ppc_linux.c [new uImage] Define a API for image handling operations Add missing cmd_ximg.o to common/Makefile
Comments and suggestions are welcome.
Due to a 40K message limit, not all of the patches can be sent to ml, oversized patches will provide a http location instead.
Argh! :-(
Best regard, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

Stefan Roese wrote:
On Friday 11 January 2008, Marian Balakowicz wrote:
[snip]
Due to a 40K message limit, not all of the patches can be sent to ml, oversized patches will provide a http location instead.
Argh! :-(
Best regard, Stefan
Fortunately, we browbeat the list admin into exercising some flexibility on oversize messages. :-D
Now we have to start working him over to make the hard limit 100K with a soft limit of 400K to keep up with linux-ppc (and yes, that's a joke!).
Best regards, gvb

In message 47879A13.8040301@ge.com you wrote:
Fortunately, we browbeat the list admin into exercising some flexibility on oversize messages. :-D
I still don't know how to sit or lie with all the bruises on my back.
Now we have to start working him over to make the hard limit 100K with a soft limit of 400K to keep up with linux-ppc (and yes, that's a joke!).
Do you remember my words that 100 kB would not be enough? It already happened. Next week you will ask for a 32 MB limit.
Best regards,
Wolfgang Denk

In message 200801111547.15660.sr@denx.de you wrote:
Due to a 40K message limit, not all of the patches can be sent to ml, oversized patches will provide a http location instead.
Argh! :-(
Just to tell the complete story: we discussed this internally before, and even a 100 kB klimit would have been too small.
Best regards,
Wolfgang Denk

In message 20080111142744.8025.82931.stgit@hekate.izotz.org you wrote:
This is a first set of patches that provides a initial cleanup and code rearrangements before the proper new uImage format implementation.
API is defined for the current (old) image related processing, and it'is being introduced in place of the direct header access.
Can you please comment a bit about the current state of these patches?
Is this just a RFC, or tested code?
Does the code compile? For which boards / architectures?
How much does it change the memory footprint?
Viele Grüße,
Wolfgang Denk

Wolfgang Denk wrote:
In message 20080111142744.8025.82931.stgit@hekate.izotz.org you wrote:
This is a first set of patches that provides a initial cleanup and code rearrangements before the proper new uImage format implementation.
API is defined for the current (old) image related processing, and it'is being introduced in place of the direct header access.
Can you please comment a bit about the current state of these patches?
Is this just a RFC, or tested code?
It has been tested on lite5200b board. Tests covering bootm (single na multi component images), autoscr, iminfo, imls.
Does the code compile? For which boards / architectures?
Yes, it does. MAKEALL builds were run for ppc, mips, arm and coldfire (although not all targets, as some of them are broken in the baseline code). I have also attempted to build on i386, but the i386 target builds are broken as well, I have just verified that modified files do compile. Other architectures were skipped due to lack of the toolchains.
It would be good if other architecture maintainers could help testing new uImage patches, as the changes are cross platform. Another good verification would be booting OS other than linux. But, as there are more significant changes coming, it may have more sens to wait with the detailed tests until crucial modifications are finished.
How much does it change the memory footprint?
Here is the build output for lite5200b_LOWBOOT configuration and with the patches applied:
text data bss dec hex filename 222739 13120 305152 541011 84153 ./u-boot
Note, that patches enable DEBUG in do_bootm() and PPC variant of do_bootm_linux(), with those disabled we get:
text data bss dec hex filename 222011 13080 305152 540243 83e53 ./u-boot
and the same configuration build for the 1.3.1 baseline:
text data bss dec hex filename 221463 13040 305408 539911 83d07 ./u-boot
Best Regards, Marian
participants (8)
-
Jerry Van Baren
-
Joe Hamman
-
Jon Loeliger
-
Kim Phillips
-
Larry Johnson
-
Marian Balakowicz
-
Stefan Roese
-
Wolfgang Denk