From ed29bc4e8142b46b626f67524207b36e43d9aad6 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:19:58 +0100 Subject: Add missing cmd_ximg.o to common/Makefile Signed-off-by: Marian Balakowicz diff --git a/common/Makefile b/common/Makefile index fbfa536..533c415 100644 --- a/common/Makefile +++ b/common/Makefile @@ -89,6 +89,7 @@ COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o COBJS-$(CONFIG_CMD_TERMINAL) += cmd_terminal.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 -- cgit v0.10.2 From b97a2a0a21f279d66de8a9bdbfe21920968bcb1c Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:14:09 +0100 Subject: [new uImage] 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 diff --git a/Makefile b/Makefile index ec8661a..ba6940b 100644 --- a/Makefile +++ b/Makefile @@ -2913,7 +2913,8 @@ clobber: clean @rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS @rm -fr $(obj)*.*~ @rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL) - @rm -f $(obj)tools/crc32.c $(obj)tools/environment.c $(obj)tools/env/crc32.c $(obj)tools/sha1.c + @rm -f $(obj)tools/crc32.c $(obj)tools/environment.c $(obj)tools/env/crc32.c + @rm -f $(obj)tools/sha1.c $(obj)tools/image.c @rm -f $(obj)tools/inca-swap-bytes $(obj)cpu/mpc824x/bedbug_603e.c @rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm @[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f diff --git a/board/cray/L1/L1.c b/board/cray/L1/L1.c index a0fac7f..8e6d74e 100644 --- a/board/cray/L1/L1.c +++ b/board/cray/L1/L1.c @@ -139,8 +139,8 @@ int misc_init_r (void) struct rtc_time tm; char bootcmd[32]; - hdr = (image_header_t *) (CFG_MONITOR_BASE - sizeof (image_header_t)); - timestamp = (time_t) hdr->ih_time; + hdr = (image_header_t *) (CFG_MONITOR_BASE - image_get_header_size ()); + timestamp = (time_t)image_get_time (hdr); to_tm (timestamp, &tm); printf ("Welcome to U-Boot on Cray L1. Compiled %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); diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c index a76b00f..cb8087b 100644 --- a/board/esd/common/auto_update.c +++ b/board/esd/common/auto_update.c @@ -89,24 +89,22 @@ extern block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE]; int au_check_cksum_valid(int i, long nbytes) { image_header_t *hdr; - unsigned long checksum; hdr = (image_header_t *)LOAD_ADDR; - if ((au_image[i].type == AU_FIRMWARE) && (au_image[i].size != ntohl(hdr->ih_size))) { + if ((au_image[i].type == AU_FIRMWARE) && + (au_image[i].size != image_get_data_size (hdr))) { printf ("Image %s has wrong size\n", au_image[i].name); return -1; } - if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) { + if (nbytes != (image_get_image_size (hdr))) { printf ("Image %s bad total SIZE\n", au_image[i].name); return -1; } - /* check the data CRC */ - checksum = ntohl(hdr->ih_dcrc); - if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) - != checksum) { + /* check the data CRC */ + if (!image_check_dcrc (hdr)) { printf ("Image %s bad data checksum\n", au_image[i].name); return -1; } @@ -123,48 +121,43 @@ int au_check_header_valid(int i, long nbytes) /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG - printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC); - printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_PPC); - printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes); - printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL); + printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC); + printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_PPC); + printf("size %#x %#lx ", image_get_data_size (hdr), nbytes); + printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL); #endif - if (nbytes < sizeof(*hdr)) + if (nbytes < image_get_header_size ()) { printf ("Image %s bad header SIZE\n", au_image[i].name); return -1; } - if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC) + if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC)) { printf ("Image %s bad MAGIC or ARCH\n", au_image[i].name); return -1; } - /* check the hdr CRC */ - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) { + if (!image_check_hcrc (hdr)) { printf ("Image %s bad header checksum\n", au_image[i].name); return -1; } - hdr->ih_hcrc = htonl(checksum); /* check the type - could do this all in one gigantic if() */ - if ((au_image[i].type == AU_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) { + if ((au_image[i].type == AU_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) { printf ("Image %s wrong type\n", au_image[i].name); return -1; } - if ((au_image[i].type == AU_SCRIPT) && (hdr->ih_type != IH_TYPE_SCRIPT)) { + if ((au_image[i].type == AU_SCRIPT) && !image_check_type (hdr, IH_TYPE_SCRIPT)) { printf ("Image %s wrong type\n", au_image[i].name); return -1; } /* recycle checksum */ - checksum = ntohl(hdr->ih_size); + checksum = image_get_data_size (hdr); #if 0 /* test-only */ /* for kernel and app the image header must also fit into flash */ if (idx != IDX_DISK) - checksum += sizeof(*hdr); + checksum += image_get_header_size (); /* check the size does not exceed space in flash. HUSH scripts */ /* all have ausize[] set to 0 */ if ((ausize[idx] != 0) && (ausize[idx] < checksum)) { @@ -196,11 +189,11 @@ int au_do_update(int i, long sz) printf("Executing script %s\n", au_image[i].name); /* execute a script */ - if (hdr->ih_type == IH_TYPE_SCRIPT) { - addr = (char *)((char *)hdr + sizeof(*hdr)); + if (image_check_type (hdr, IH_TYPE_SCRIPT)) { + addr = (char *)((char *)hdr + image_get_header_size ()); /* stick a NULL at the end of the script, otherwise */ /* parse_string_outer() runs off the end. */ - addr[ntohl(hdr->ih_size)] = 0; + addr[image_get_data_size (hdr)] = 0; addr += 8; /* @@ -231,8 +224,8 @@ int au_do_update(int i, long sz) */ if (au_image[i].type == AU_FIRMWARE) { char *orig = (char*)start; - char *new = (char *)((char *)hdr + sizeof(*hdr)); - nbytes = ntohl(hdr->ih_size); + char *new = (char *)((char *)hdr + image_get_header_size ()); + nbytes = image_get_data_size (hdr); while(--nbytes) { if (*orig++ != *new++) { @@ -272,12 +265,12 @@ int au_do_update(int i, long sz) /* strip the header - except for the kernel and ramdisk */ if (au_image[i].type != AU_FIRMWARE) { addr = (char *)hdr; - off = sizeof(*hdr); - nbytes = sizeof(*hdr) + ntohl(hdr->ih_size); + off = image_get_header_size (); + nbytes = image_get_image_size (hdr); } else { - addr = (char *)((char *)hdr + sizeof(*hdr)); + addr = (char *)((char *)hdr + image_get_header_size ()); off = 0; - nbytes = ntohl(hdr->ih_size); + nbytes = image_get_data_size (hdr); } /* @@ -305,15 +298,15 @@ int au_do_update(int i, long sz) * check the dcrc of the copy */ if (au_image[i].type != AU_NAND) { - rc = crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)); + rc = crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)); } else { #if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY) rc = nand_legacy_rw(nand_dev_desc, NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP, start, nbytes, (size_t *)&total, (uchar *)addr); - rc = crc32 (0, (uchar *)(addr + off), ntohl(hdr->ih_size)); + rc = crc32 (0, (uchar *)(addr + off), image_get_data_size (hdr)); #endif } - if (rc != ntohl(hdr->ih_dcrc)) { + if (rc != image_get_dcrc (hdr)) { printf ("Image %s Bad Data Checksum After COPY\n", au_image[i].name); return -1; } @@ -497,10 +490,10 @@ int do_auto_update(void) printf("Reading %s ...", au_image[i].name); /* just read the header */ - sz = do_fat_read(au_image[i].name, LOAD_ADDR, sizeof(image_header_t), LS_NO); + sz = do_fat_read(au_image[i].name, LOAD_ADDR, image_get_header_size (), LS_NO); debug ("read %s sz %ld hdr %d\n", - au_image[i].name, sz, sizeof(image_header_t)); - if (sz <= 0 || sz < sizeof(image_header_t)) { + au_image[i].name, sz, image_get_header_size ()); + if (sz <= 0 || sz < image_get_header_size ()) { puts(" not found\n"); continue; } @@ -510,8 +503,8 @@ int do_auto_update(void) } sz = do_fat_read(au_image[i].name, LOAD_ADDR, MAX_LOADSZ, LS_NO); debug ("read %s sz %ld hdr %d\n", - au_image[i].name, sz, sizeof(image_header_t)); - if (sz <= 0 || sz <= sizeof(image_header_t)) { + au_image[i].name, sz, image_get_header_size ()); + if (sz <= 0 || sz <= image_get_header_size ()) { puts(" not found\n"); continue; } diff --git a/board/mcc200/auto_update.c b/board/mcc200/auto_update.c index 28e4c87..8b520c8 100644 --- a/board/mcc200/auto_update.c +++ b/board/mcc200/auto_update.c @@ -141,18 +141,15 @@ extern void lcd_enable(void); int au_check_cksum_valid(int idx, long nbytes) { image_header_t *hdr; - unsigned long checksum; hdr = (image_header_t *)LOAD_ADDR; - if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) { + if (nbytes != image_get_image_size (hdr)) { printf ("Image %s bad total SIZE\n", aufile[idx]); return -1; } /* check the data CRC */ - checksum = ntohl(hdr->ih_dcrc); - - if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) != checksum) { + if (!image_check_dcrc (hdr)) { printf ("Image %s bad data checksum\n", aufile[idx]); return -1; } @@ -168,56 +165,52 @@ int au_check_header_valid(int idx, long nbytes) /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG - printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC); - printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_ARM); - printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes); - printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL); + printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC); + printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_ARM); + printf("size %#x %#lx ", image_get_data_size (hdr), nbytes); + printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL); #endif - if (nbytes < sizeof(*hdr)) { + if (nbytes < image_get_header_size ()) { printf ("Image %s bad header SIZE\n", aufile[idx]); ausize[idx] = 0; return -1; } - if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC) { + if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC)) { printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]); ausize[idx] = 0; return -1; } /* check the hdr CRC */ - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) { + if (!image_check_hcrc (hdr)) { printf ("Image %s bad header checksum\n", aufile[idx]); ausize[idx] = 0; return -1; } - hdr->ih_hcrc = htonl(checksum); /* check the type - could do this all in one gigantic if() */ - if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) { + if ((idx == IDX_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) { printf ("Image %s wrong type\n", aufile[idx]); ausize[idx] = 0; return -1; } - if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) { + if ((idx == IDX_KERNEL) && !image_check_type (hdr, IH_TYPE_KERNEL)) { printf ("Image %s wrong type\n", aufile[idx]); ausize[idx] = 0; return -1; } if ((idx == IDX_ROOTFS) && - ( (hdr->ih_type != IH_TYPE_RAMDISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM) ) - ) { + (!image_check_type (hdr, IH_TYPE_RAMDISK) && + !image_check_type (hdr, IH_TYPE_FILESYSTEM))) { printf ("Image %s wrong type\n", aufile[idx]); ausize[idx] = 0; return -1; } /* recycle checksum */ - checksum = ntohl(hdr->ih_size); + checksum = image_get_data_size (hdr); - fsize = checksum + sizeof(*hdr); + fsize = checksum + image_get_header_size (); /* for kernel and ramdisk the image header must also fit into flash */ - if (idx == IDX_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) - checksum += sizeof(*hdr); + if (idx == IDX_KERNEL || image_check_type (hdr, IH_TYPE_RAMDISK)) + checksum += image_get_header_size (); /* check the size does not exceed space in flash. HUSH scripts */ if ((ausize[idx] != 0) && (ausize[idx] < checksum)) { @@ -242,11 +235,11 @@ int au_do_update(int idx, long sz) hdr = (image_header_t *)LOAD_ADDR; /* execute a script */ - if (hdr->ih_type == IH_TYPE_SCRIPT) { - addr = (char *)((char *)hdr + sizeof(*hdr)); + if (image_check_type (hdr, IH_TYPE_SCRIPT)) { + addr = (char *)((char *)hdr + image_get_header_size ()); /* stick a NULL at the end of the script, otherwise */ /* parse_string_outer() runs off the end. */ - addr[ntohl(hdr->ih_size)] = 0; + addr[image_get_data_size (hdr)] = 0; addr += 8; parse_string_outer(addr, FLAG_PARSE_SEMICOLON); return 0; @@ -278,19 +271,20 @@ int au_do_update(int idx, long sz) #endif /* strip the header - except for the kernel and ramdisk */ - if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) { + if (image_check_type (hdr, IH_TYPE_KERNEL) || + image_check_type (hdr, IH_TYPE_RAMDISK)) { addr = (char *)hdr; - off = sizeof(*hdr); - nbytes = sizeof(*hdr) + ntohl(hdr->ih_size); + off = image_get_header_size (); + nbytes = image_get_image_size (hdr); } else { - addr = (char *)((char *)hdr + sizeof(*hdr)); + addr = (char *)((char *)hdr + image_get_header_size ()); #ifdef AU_UPDATE_TEST /* copy it to where Linux goes */ if (idx == IDX_FIRMWARE) start = aufl_layout[1].start; #endif off = 0; - nbytes = ntohl(hdr->ih_size); + nbytes = image_get_data_size (hdr); } /* copy the data from RAM to FLASH */ @@ -306,7 +300,8 @@ int au_do_update(int idx, long sz) #endif /* check the data CRC of the copy */ - if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) { + if (crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)) != + image_get_dcrc (hdr)) { printf ("Image %s Bad Data Checksum after COPY\n", aufile[idx]); return -1; } @@ -442,10 +437,10 @@ int do_auto_update(void) for (i = 0; i < AU_MAXFILES; i++) { ulong imsize; /* just read the header */ - sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t)); + sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ()); debug ("read %s sz %ld hdr %d\n", - aufile[i], sz, sizeof(image_header_t)); - if (sz <= 0 || sz < sizeof(image_header_t)) { + aufile[i], sz, image_get_header_size ()); + if (sz <= 0 || sz < image_get_header_size ()) { debug ("%s not found\n", aufile[i]); ausize[i] = 0; continue; @@ -474,14 +469,14 @@ int do_auto_update(void) sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]); debug ("read %s sz %ld hdr %d\n", - aufile[i], sz, sizeof(image_header_t)); + aufile[i], sz, image_get_header_size ()); if (sz != ausize[i]) { printf ("%s: size %d read %d?\n", aufile[i], ausize[i], sz); continue; } - if (sz <= 0 || sz <= sizeof(image_header_t)) { + if (sz <= 0 || sz <= image_get_header_size ()) { debug ("%s not found\n", aufile[i]); continue; } diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c index 8d4cbe8..30c6ca9 100644 --- a/board/mpl/common/common_util.c +++ b/board/mpl/common/common_util.c @@ -57,9 +57,6 @@ extern int mem_test(ulong start, ulong ramsize, int quiet); extern flash_info_t flash_info[]; /* info for FLASH chips */ -static image_header_t header; - - static int mpl_prg(uchar *src, ulong size) { @@ -77,7 +74,7 @@ mpl_prg(uchar *src, ulong size) info = &flash_info[0]; #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI) - if (ntohl(magic[0]) != IH_MAGIC) { + if (image_to_cpu (magic[0]) != IH_MAGIC) { puts("Bad Magic number\n"); return -1; } @@ -179,44 +176,39 @@ mpl_prg(uchar *src, ulong size) static int mpl_prg_image(uchar *ld_addr) { - unsigned long len, checksum; + unsigned long len; uchar *data; - image_header_t *hdr = &header; + image_header_t *hdr = (image_header_t *)ld_addr; int rc; - /* Copy header so we can blank CRC field for re-calculation */ - memcpy (&header, (char *)ld_addr, sizeof(image_header_t)); - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { puts("Bad Magic Number\n"); return 1; } print_image_hdr(hdr); - if (hdr->ih_os != IH_OS_U_BOOT) { + if (!image_check_os (hdr, IH_OS_U_BOOT)) { puts("No U-Boot Image\n"); return 1; } - if (hdr->ih_type != IH_TYPE_FIRMWARE) { + if (!image_check_type (hdr, IH_TYPE_FIRMWARE)) { puts("No Firmware Image\n"); return 1; } - data = (uchar *)&header; - len = sizeof(image_header_t); - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - if (crc32 (0, (uchar *)data, len) != checksum) { + if (!image_check_hcrc (hdr)) { puts("Bad Header Checksum\n"); return 1; } - data = ld_addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); puts("Verifying Checksum ... "); - if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { + if (!image_check_dcrc (hdr)) { puts("Bad Data CRC\n"); return 1; } puts("OK\n"); - if (hdr->ih_comp != IH_COMP_NONE) { + data = (uchar *)image_get_data (hdr); + len = image_get_data_size (hdr); + + if (image_get_comp (hdr) != IH_COMP_NONE) { uchar *buf; /* reserve space for uncompressed image */ if ((buf = malloc(IMAGE_SIZE)) == NULL) { @@ -224,7 +216,7 @@ mpl_prg_image(uchar *ld_addr) return 1; } - switch (hdr->ih_comp) { + switch (image_get_comp (hdr)) { case IH_COMP_GZIP: puts("Uncompressing (GZIP) ... "); rc = gunzip ((void *)(buf), IMAGE_SIZE, data, &len); @@ -253,7 +245,8 @@ mpl_prg_image(uchar *ld_addr) break; #endif default: - printf ("Unimplemented compression type %d\n", hdr->ih_comp); + printf ("Unimplemented compression type %d\n", + image_get_comp (hdr)); free(buf); return 1; } diff --git a/board/siemens/common/fpga.c b/board/siemens/common/fpga.c index f022ed6..9d71946 100644 --- a/board/siemens/common/fpga.c +++ b/board/siemens/common/fpga.c @@ -131,45 +131,37 @@ static int fpga_reset (fpga_t* fpga) static int fpga_load (fpga_t* fpga, ulong addr, int checkall) { volatile uchar *fpga_addr = (volatile uchar *)fpga->conf_base; - image_header_t hdr; - ulong len, checksum; - uchar *data = (uchar *)&hdr; - char *s, msg[32]; + image_header_t *hdr = (image_header_t *)addr; + ulong len; + uchar *data; + char msg[32]; int verify, i; /* * Check the image header and data of the net-list */ - memcpy (&hdr, (char *)addr, sizeof(image_header_t)); - - if (hdr.ih_magic != IH_MAGIC) { + if (!image_check_magic (hdr)) { strcpy (msg, "Bad Image Magic Number"); goto failure; } - len = sizeof(image_header_t); - - checksum = hdr.ih_hcrc; - hdr.ih_hcrc = 0; - - if (crc32 (0, data, len) != checksum) { + if (!image_check_hcrc (hdr)) { strcpy (msg, "Bad Image Header CRC"); goto failure; } - data = (uchar*)(addr + sizeof(image_header_t)); - len = hdr.ih_size; + data = (uchar*)image_get_data (hdr); + len = image_get_data_size (hdr); - s = getenv ("verify"); - verify = (s && (*s == 'n')) ? 0 : 1; + verify = getenv_verify (); if (verify) { - if (crc32 (0, data, len) != hdr.ih_dcrc) { + if (!image_check_dcrc (hdr)) { strcpy (msg, "Bad Image Data CRC"); goto failure; } } - if (checkall && fpga_get_version(fpga, (char *)(hdr.ih_name)) < 0) + if (checkall && fpga_get_version(fpga, image_get_name (hdr)) < 0) return 1; /* align length */ @@ -184,7 +176,7 @@ static int fpga_load (fpga_t* fpga, ulong addr, int checkall) goto failure; } - printf ("(%s)... ", hdr.ih_name); + printf ("(%s)... ", image_get_name (hdr)); /* * Copy data to FPGA */ @@ -341,7 +333,7 @@ int fpga_init (void) } hdr = (image_header_t *)addr; - if ((new_id = fpga_get_version(fpga, (char *)(hdr->ih_name))) == -1) + if ((new_id = fpga_get_version(fpga, image_get_name (hdr))) == -1) return 1; do_load = 1; diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c index 54d3645..bd9ee0c 100644 --- a/board/trab/auto_update.c +++ b/board/trab/auto_update.c @@ -209,20 +209,16 @@ int au_check_cksum_valid(int idx, long nbytes) { image_header_t *hdr; - unsigned long checksum; hdr = (image_header_t *)LOAD_ADDR; - if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) + if (nbytes != image_get_image_size (hdr)) { printf ("Image %s bad total SIZE\n", aufile[idx]); return -1; } /* check the data CRC */ - checksum = ntohl(hdr->ih_dcrc); - - if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) - != checksum) + if (!image_check_dcrc (hdr)) { { printf ("Image %s bad data checksum\n", aufile[idx]); return -1; @@ -241,50 +237,46 @@ au_check_header_valid(int idx, long nbytes) /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG - printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC); - printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_ARM); - printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes); - printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL); + printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC); + printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_ARM); + printf("size %#x %#lx ", image_get_data_size (hdr), nbytes); + printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL); #endif - if (nbytes < sizeof(*hdr)) + if (nbytes < image_get_header_size ()) { printf ("Image %s bad header SIZE\n", aufile[idx]); return -1; } - if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_ARM) + if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_ARM)) { printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]); return -1; } /* check the hdr CRC */ - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) { + if (!image_check_hcrc (hdr)) { printf ("Image %s bad header checksum\n", aufile[idx]); return -1; } - hdr->ih_hcrc = htonl(checksum); /* check the type - could do this all in one gigantic if() */ - if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) { + if ((idx == IDX_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } - if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) { + if ((idx == IDX_KERNEL) && !image_check_type (hdr, IH_TYPE_KERNEL)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } - if ((idx == IDX_DISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM)) { + if ((idx == IDX_DISK) && !image_check_type (hdr, IH_TYPE_FILESYSTEM)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } - if ((idx == IDX_APP) && (hdr->ih_type != IH_TYPE_RAMDISK) - && (hdr->ih_type != IH_TYPE_FILESYSTEM)) { + if ((idx == IDX_APP) && !image_check_type (hdr, IH_TYPE_RAMDISK) + && !image_check_type (hdr, FILESYSTEM)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } if ((idx == IDX_PREPARE || idx == IDX_PREINST || idx == IDX_POSTINST) - && (hdr->ih_type != IH_TYPE_SCRIPT)) + && !image_check_type (hdr, IH_TYPE_SCRIPT)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; @@ -293,10 +285,10 @@ au_check_header_valid(int idx, long nbytes) if (idx == IDX_PREPARE) return 0; /* recycle checksum */ - checksum = ntohl(hdr->ih_size); + checksum = image_get_data_size (hdr); /* for kernel and app the image header must also fit into flash */ if ((idx != IDX_DISK) && (idx != IDX_FIRMWARE)) - checksum += sizeof(*hdr); + checksum += image_get_header_size (); /* check the size does not exceed space in flash. HUSH scripts */ /* all have ausize[] set to 0 */ if ((ausize[idx] != 0) && (ausize[idx] < checksum)) { @@ -310,10 +302,10 @@ au_check_header_valid(int idx, long nbytes) printf ("buf[0] %#x buf[1] %#x buf[2] %#x buf[3] %#x " "as int %#x time %#x\n", buf[0], buf[1], buf[2], buf[3], - *((unsigned int *)buf), ntohl(hdr->ih_time)); + *((unsigned int *)buf), image_get_time (hdr)); #endif /* check it */ - if (*((unsigned int *)buf) >= ntohl(hdr->ih_time)) { + if (*((unsigned int *)buf) >= image_get_time (hdr)) { printf ("Image %s is too old\n", aufile[idx]); return -1; } @@ -340,11 +332,11 @@ au_do_update(int idx, long sz) *CPLD_VFD_BK |= POWER_OFF; /* execute a script */ - if (hdr->ih_type == IH_TYPE_SCRIPT) { - addr = (char *)((char *)hdr + sizeof(*hdr)); + if (image_check_type (hdr, IH_TYPE_SCRIPT)) { + addr = (char *)((char *)hdr + image_get_header_size ()); /* stick a NULL at the end of the script, otherwise */ /* parse_string_outer() runs off the end. */ - addr[ntohl(hdr->ih_size)] = 0; + addr[image_get_data_size (hdr)] = 0; addr += 8; parse_string_outer(addr, FLAG_PARSE_SEMICOLON); return 0; @@ -372,19 +364,20 @@ au_do_update(int idx, long sz) flash_sect_erase(start, end); wait_ms(100); /* strip the header - except for the kernel and ramdisk */ - if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) { + if (image_check_type (hdr, IH_TYPE_KERNEL) || + image_check_type (hdr, IH_TYPE_RAMDISK)) { addr = (char *)hdr; - off = sizeof(*hdr); - nbytes = sizeof(*hdr) + ntohl(hdr->ih_size); + off = image_get_header_size (); + nbytes = image_get_image_size (hdr); } else { - addr = (char *)((char *)hdr + sizeof(*hdr)); + addr = (char *)((char *)hdr + image_get_header_size ()); #ifdef AU_UPDATE_TEST /* copy it to where Linux goes */ if (idx == IDX_FIRMWARE) start = aufl_layout[1].start; #endif off = 0; - nbytes = ntohl(hdr->ih_size); + nbytes = image_get_data_size (hdr); } /* copy the data from RAM to FLASH */ @@ -396,7 +389,8 @@ au_do_update(int idx, long sz) } /* check the dcrc of the copy */ - if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) { + if (crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)) != + image_get_dcrc (hdr)) { printf ("Image %s Bad Data Checksum After COPY\n", aufile[idx]); return -1; } @@ -425,15 +419,15 @@ au_update_eeprom(int idx) hdr = (image_header_t *)LOAD_ADDR; /* write the time field into EEPROM */ off = auee_off[idx].time; - val = ntohl(hdr->ih_time); + val = image_get_time (hdr); i2c_write_multiple(0x54, off, 1, &val, sizeof(val)); /* write the size field into EEPROM */ off = auee_off[idx].size; - val = ntohl(hdr->ih_size); + val = image_get_data_size (hdr); i2c_write_multiple(0x54, off, 1, &val, sizeof(val)); /* write the dcrc field into EEPROM */ off = auee_off[idx].dcrc; - val = ntohl(hdr->ih_dcrc); + val = image_get_dcrc (hdr); i2c_write_multiple(0x54, off, 1, &val, sizeof(val)); /* enable the power switch */ *CPLD_VFD_BK &= ~POWER_OFF; @@ -577,10 +571,10 @@ do_auto_update(void) /* just loop thru all the possible files */ for (i = 0; i < AU_MAXFILES; i++) { /* just read the header */ - sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t)); + sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ()); debug ("read %s sz %ld hdr %d\n", - aufile[i], sz, sizeof(image_header_t)); - if (sz <= 0 || sz < sizeof(image_header_t)) { + aufile[i], sz, image_get_header_size ()); + if (sz <= 0 || sz < image_get_header_size ()) { debug ("%s not found\n", aufile[i]); continue; } @@ -590,8 +584,8 @@ do_auto_update(void) } sz = file_fat_read(aufile[i], LOAD_ADDR, MAX_LOADSZ); debug ("read %s sz %ld hdr %d\n", - aufile[i], sz, sizeof(image_header_t)); - if (sz <= 0 || sz <= sizeof(image_header_t)) { + aufile[i], sz, image_get_header_size ()); + if (sz <= 0 || sz <= image_get_header_size ()) { debug ("%s not found\n", aufile[i]); continue; } diff --git a/common/Makefile b/common/Makefile index 533c415..d3a4a85 100644 --- a/common/Makefile +++ b/common/Makefile @@ -36,6 +36,7 @@ COBJS-y += cmd_autoscript.o 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 += cmd_boot.o COBJS-y += cmd_bootm.o COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c index a6038a6..3e68ced 100644 --- a/common/cmd_autoscript.c +++ b/common/cmd_autoscript.c @@ -49,56 +49,44 @@ #if defined(CONFIG_AUTOSCRIPT) || defined(CONFIG_CMD_AUTOSCRIPT) -extern image_header_t header; /* from cmd_bootm.c */ int autoscript (ulong addr) { - ulong crc, data, len; - image_header_t *hdr = &header; + ulong len; + image_header_t *hdr = (image_header_t *)addr; ulong *len_ptr; char *cmd; int rcode = 0; int verify; - cmd = getenv ("verify"); - verify = (cmd && (*cmd == 'n')) ? 0 : 1; + verify = getenv_verify (); - - memmove (hdr, (char *)addr, sizeof(image_header_t)); - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { puts ("Bad magic number\n"); return 1; } - crc = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - len = sizeof (image_header_t); - data = (ulong)hdr; - if (crc32(0, (uchar *)data, len) != crc) { + if (!image_check_hcrc (hdr)) { puts ("Bad header crc\n"); return 1; } - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); - if (verify) { - if (crc32(0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { + if (!image_check_dcrc (hdr)) { puts ("Bad data crc\n"); return 1; } } - if (hdr->ih_type != IH_TYPE_SCRIPT) { + if (!image_check_type (hdr, IH_TYPE_SCRIPT)) { puts ("Bad image type\n"); return 1; } /* get length of script */ - len_ptr = (ulong *)data; + len_ptr = (ulong *)image_get_data (hdr); - if ((len = ntohl(*len_ptr)) == 0) { + if ((len = image_to_cpu (*len_ptr)) == 0) { puts ("Empty Script\n"); return 1; } diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 9546729..be8589d 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -21,6 +21,8 @@ * MA 02111-1307 USA */ +#define DEBUG + /* * Boot support */ @@ -73,9 +75,7 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); * we must make sure to split long operations like memmove() or * crc32() into reasonable chunks. */ -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) -# define CHUNKSZ (64 * 1024) -#endif +#define CHUNKSZ (64 * 1024) int gunzip (void *, int, unsigned char *, unsigned long *); @@ -152,7 +152,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong iflag; ulong addr; - ulong data, len, checksum; + ulong data, len; ulong *len_ptr; uint unc_len = CFG_BOOTM_LEN; int i, verify; @@ -160,8 +160,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int (*appl)(int, char *[]); image_header_t *hdr = &header; - s = getenv ("verify"); - verify = (s && (*s == 'n')) ? 0 : 1; + verify = getenv_verify (); if (argc < 2) { addr = load_addr; @@ -175,16 +174,16 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* Copy header so we can blank CRC field for re-calculation */ #ifdef CONFIG_HAS_DATAFLASH if (addr_dataflash(addr)){ - read_dataflash(addr, sizeof(image_header_t), (char *)&header); + read_dataflash (addr, image_get_header_size (), (char *)&header); } else #endif - memmove (&header, (char *)addr, sizeof(image_header_t)); + memmove (&header, (char *)addr, image_get_header_size ()); - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + 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 -= sizeof(image_header_t); + addr -= image_get_header_size (); /* turnof verify, * fake_header() does not fake the data crc */ @@ -199,13 +198,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (2); - data = (ulong)&header; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)data, len) != checksum) { + if (!image_check_hcrc (hdr)) { puts ("Bad Header Checksum\n"); show_boot_progress (-2); return 1; @@ -214,7 +207,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #ifdef CONFIG_HAS_DATAFLASH if (addr_dataflash(addr)){ - len = ntohl(hdr->ih_size) + sizeof(image_header_t); + len = image_get_image_size (hdr); read_dataflash(addr, len, (char *)CFG_LOAD_ADDR); addr = CFG_LOAD_ADDR; } @@ -224,12 +217,13 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* for multi-file images we need the data part, too */ print_image_hdr ((image_header_t *)addr); - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); + len = image_get_data_size (hdr); + data = addr + image_get_header_size (); + len_ptr = (ulong *)data; if (verify) { puts (" Verifying Checksum ... "); - if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { + if (!image_check_dcrc ((image_header_t *)addr)) { printf ("Bad Data CRC\n"); show_boot_progress (-3); return 1; @@ -238,46 +232,19 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (4); - len_ptr = (ulong *)data; - -#if defined(__ARM__) - if (hdr->ih_arch != IH_CPU_ARM) -#elif defined(__avr32__) - if (hdr->ih_arch != IH_CPU_AVR32) -#elif defined(__bfin__) - if (hdr->ih_arch != IH_CPU_BLACKFIN) -#elif defined(__I386__) - if (hdr->ih_arch != IH_CPU_I386) -#elif defined(__M68K__) - if (hdr->ih_arch != IH_CPU_M68K) -#elif defined(__microblaze__) - if (hdr->ih_arch != IH_CPU_MICROBLAZE) -#elif defined(__mips__) - if (hdr->ih_arch != IH_CPU_MIPS) -#elif defined(__nios__) - if (hdr->ih_arch != IH_CPU_NIOS) -#elif defined(__nios2__) - if (hdr->ih_arch != IH_CPU_NIOS2) -#elif defined(__PPC__) - if (hdr->ih_arch != IH_CPU_PPC) -#elif defined(__sh__) - if (hdr->ih_arch != IH_CPU_SH) -#else -# error Unknown CPU type -#endif - { - printf ("Unsupported Architecture 0x%x\n", hdr->ih_arch); + if (!image_check_target_arch (hdr)) { + printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr)); show_boot_progress (-4); return 1; } show_boot_progress (5); - switch (hdr->ih_type) { + switch (image_get_type (hdr)) { case IH_TYPE_STANDALONE: name = "Standalone Application"; /* A second argument overwrites the load address */ if (argc > 2) { - hdr->ih_load = htonl(simple_strtoul(argv[2], NULL, 16)); + image_set_load (hdr, simple_strtoul (argv[2], NULL, 16)); } break; case IH_TYPE_KERNEL: @@ -285,7 +252,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; case IH_TYPE_MULTI: name = "Multi-File Image"; - len = ntohl(len_ptr[0]); + len = image_to_cpu (len_ptr[0]); /* OS kernel is always the first image */ data += 8; /* kernel_len + terminator */ for (i=1; len_ptr[i]; ++i) @@ -316,14 +283,14 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) dcache_disable(); #endif - switch (hdr->ih_comp) { + switch (image_get_comp (hdr)) { case IH_COMP_NONE: - if(ntohl(hdr->ih_load) == addr) { + 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 *)ntohl(hdr->ih_load); + void *to = (void *)image_get_load (hdr); void *from = (void *)data; printf (" Loading %s ... ", name); @@ -337,13 +304,13 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) l -= tail; } #else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len); + memmove ((void *)image_get_load (hdr), (uchar *)data, len); #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ } break; case IH_COMP_GZIP: printf (" Uncompressing %s ... ", name); - if (gunzip ((void *)ntohl(hdr->ih_load), unc_len, + 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); @@ -358,7 +325,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * use slower decompression algorithm which requires * at most 2300 KB of memory. */ - i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load), + i = BZ2_bzBuffToBuffDecompress ((char*)image_get_load (hdr), &unc_len, (char *)data, len, CFG_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { @@ -371,14 +338,14 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) default: if (iflag) enable_interrupts(); - printf ("Unimplemented compression type %d\n", hdr->ih_comp); + printf ("Unimplemented compression type %d\n", image_get_comp (hdr)); show_boot_progress (-7); return 1; } puts ("OK\n"); show_boot_progress (7); - switch (hdr->ih_type) { + switch (image_get_type (hdr)) { case IH_TYPE_STANDALONE: if (iflag) enable_interrupts(); @@ -392,7 +359,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) setenv("filesize", buf); return 0; } - appl = (int (*)(int, char *[]))ntohl(hdr->ih_ep); + appl = (int (*)(int, char *[]))image_get_ep (hdr); (*appl)(argc-1, &argv[1]); return 0; case IH_TYPE_KERNEL: @@ -402,13 +369,13 @@ 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", hdr->ih_type); + printf ("Can't boot image type %d\n", image_get_type (hdr)); show_boot_progress (-8); return 1; } show_boot_progress (8); - switch (hdr->ih_os) { + switch (image_get_os (hdr)) { default: /* handled by (original) Linux case */ case IH_OS_LINUX: #ifdef CONFIG_SILENT_CONSOLE @@ -517,7 +484,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int verify) { ulong sp; - ulong len, checksum; + ulong len; ulong initrd_start, initrd_end; ulong cmd_start, cmd_end; ulong initrd_high; @@ -615,7 +582,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, #endif /* CONFIG_MPC5xxx */ } - kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong)) ntohl(hdr->ih_ep); + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); /* * Check if there is an initrd image @@ -636,60 +603,27 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, addr = simple_strtoul(argv[2], NULL, 16); printf ("## Loading RAMDisk Image at %08lx ...\n", addr); + hdr = (image_header_t *)addr; - /* Copy header so we can blank CRC field for re-calculation */ - memmove (&header, (char *)addr, sizeof(image_header_t)); - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { puts ("Bad Magic Number\n"); show_boot_progress (-10); do_reset (cmdtp, flag, argc, argv); } - data = (ulong)&header; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)data, len) != checksum) { + 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); - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); - if (verify) { - ulong csum = 0; -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - ulong cdata = data, edata = cdata + len; -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - puts (" Verifying Checksum ... "); -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - - while (cdata < edata) { - ulong chunk = edata - cdata; - - if (chunk > CHUNKSZ) - chunk = CHUNKSZ; - csum = crc32 (csum, (uchar *)cdata, chunk); - cdata += chunk; - - WATCHDOG_RESET(); - } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - csum = crc32 (0, (uchar *)data, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - - if (csum != ntohl(hdr->ih_dcrc)) { + if (!image_check_dcrc_wd (hdr, CHUNKSZ)) { puts ("Bad Data CRC\n"); show_boot_progress (-12); do_reset (cmdtp, flag, argc, argv); @@ -699,19 +633,22 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, show_boot_progress (11); - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_PPC) || - (hdr->ih_type != IH_TYPE_RAMDISK) ) { + 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 ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) { - u_long tail = ntohl(len_ptr[0]) % 4; + } 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); @@ -722,12 +659,12 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, for (i=1; len_ptr[i]; ++i) data += 4; /* add kernel length, and align */ - data += ntohl(len_ptr[0]); + data += image_to_cpu (len_ptr[0]); if (tail) { data += 4 - tail; } - len = ntohl(len_ptr[1]); + len = image_to_cpu (len_ptr[1]); } else { /* @@ -743,70 +680,64 @@ 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 + sizeof(image_header_t))) != OF_DT_HEADER) { + if (*((ulong *)(of_flat_tree + image_get_header_size ())) != OF_DT_HEADER) { #else - if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) != 0) { + 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 (ntohl(hdr->ih_magic) == IH_MAGIC) { + } else if (image_check_magic (hdr)) { printf("## Flat Device Tree at %08lX\n", hdr); - print_image_hdr(hdr); + print_image_hdr (hdr); - if ((ntohl(hdr->ih_load) < ((unsigned long)hdr + ntohl(hdr->ih_size) + sizeof(hdr))) && - ((ntohl(hdr->ih_load) + ntohl(hdr->ih_size)) > (unsigned long)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 ... "); - memmove (&header, (char *)hdr, sizeof(image_header_t)); - checksum = ntohl(header.ih_hcrc); - header.ih_hcrc = 0; - - if(checksum != crc32(0, (uchar *)&header, sizeof(image_header_t))) { + if (!image_check_hcrc (hdr)) { puts ("ERROR: fdt header checksum invalid - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); } - checksum = ntohl(hdr->ih_dcrc); - addr = (ulong)((uchar *)(hdr) + sizeof(image_header_t)); - - if(checksum != crc32(0, (uchar *)addr, ntohl(hdr->ih_size))) { + 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 (ntohl(hdr->ih_type) != IH_TYPE_FLATDT) { + 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 (ntohl(hdr->ih_comp) != IH_COMP_NONE) { + 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 + sizeof(image_header_t))) != OF_DT_HEADER) { + if (*((ulong *)(of_flat_tree + image_get_header_size ())) != OF_DT_HEADER) { #else - if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) != 0) { + 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 *)ntohl(hdr->ih_load), - (void *)(of_flat_tree + sizeof(image_header_t)), - ntohl(hdr->ih_size)); - of_flat_tree = (char *)ntohl(hdr->ih_load); + 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"); @@ -814,8 +745,8 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, } printf (" Booting using the fdt at 0x%x\n", of_flat_tree); - } else if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1]) && (len_ptr[2])) { - u_long tail = ntohl(len_ptr[0]) % 4; + } 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 */ @@ -824,14 +755,14 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, for (i=2; len_ptr[i]; ++i) of_flat_tree += 4; /* add kernel length, and align */ - of_flat_tree += ntohl(len_ptr[0]); + of_flat_tree += image_to_cpu (len_ptr[0]); if (tail) { of_flat_tree += 4 - tail; } /* add initrd length, and align */ - tail = ntohl(len_ptr[1]) % 4; - of_flat_tree += ntohl(len_ptr[1]); + tail = image_to_cpu (len_ptr[1]) % 4; + of_flat_tree += image_to_cpu (len_ptr[1]); if (tail) { of_flat_tree += 4 - tail; } @@ -855,10 +786,10 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_OF_FLAT_TREE) if (((struct boot_param_header *)of_flat_tree)->totalsize != - ntohl (len_ptr[2])) { + image_to_cpu (len_ptr[2])) { #else if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != - ntohl(len_ptr[2])) { + image_to_cpu (len_ptr[2])) { #endif puts ("ERROR: fdt size != image size - " "must RESET the board to recover.\n"); @@ -1098,7 +1029,7 @@ do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, */ img_addr = 0; - if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) + if ((image_check_type (hdr, IH_TYPE_MULTI)) && (len_ptr[1])) img_addr = (image_header_t *) addr; @@ -1131,7 +1062,7 @@ do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, cmdline = ""; } - loader = (void (*)(bd_t *, image_header_t *, char *, char *)) ntohl(hdr->ih_ep); + 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); @@ -1234,7 +1165,7 @@ do_bootm_artos (cmd_tbl_t *cmdtp, int flag, } *ss++ = NULL; /* terminate */ - entry = (void (*)(bd_t *, char *, char **, ulong))ntohl(hdr->ih_ep); + entry = (void (*)(bd_t *, char *, char **, ulong))image_get_ep (hdr); (*entry)(kbd, cmdline, fwenv, top); } #endif @@ -1288,38 +1219,24 @@ int do_iminfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) static int image_info (ulong addr) { - ulong data, len, checksum; - image_header_t *hdr = &header; + image_header_t *hdr = (image_header_t *)addr; printf ("\n## Checking Image at %08lx ...\n", addr); - /* Copy header so we can blank CRC field for re-calculation */ - memmove (&header, (char *)addr, sizeof(image_header_t)); - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { puts (" Bad Magic Number\n"); return 1; } - data = (ulong)&header; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)data, len) != checksum) { + if (!image_check_hcrc (hdr)) { puts (" Bad Header Checksum\n"); return 1; } - /* for multi-file images we need the data part, too */ - print_image_hdr ((image_header_t *)addr); - - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); + print_image_hdr (hdr); puts (" Verifying Checksum ... "); - if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { + if (!image_check_dcrc (hdr)) { puts (" Bad Data CRC\n"); return 1; } @@ -1347,38 +1264,29 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) flash_info_t *info; int i, j; image_header_t *hdr; - ulong data, len, checksum; for (i=0, info=&flash_info[0]; iflash_id == FLASH_UNKNOWN) goto next_bank; for (j=0; jsector_count; ++j) { - if (!(hdr=(image_header_t *)info->start[j]) || - (ntohl(hdr->ih_magic) != IH_MAGIC)) - goto next_sector; + hdr = (image_header_t *)info->start[j]; - /* Copy header so we can blank CRC field for re-calculation */ - memmove (&header, (char *)hdr, sizeof(image_header_t)); - - checksum = ntohl(header.ih_hcrc); - header.ih_hcrc = 0; + if (!hdr || !image_check_magic (hdr)) + goto next_sector; - if (crc32 (0, (uchar *)&header, sizeof(image_header_t)) - != checksum) + if (!image_check_hcrc (hdr)) goto next_sector; printf ("Image at %08lX:\n", (ulong)hdr); - print_image_hdr( hdr ); - - data = (ulong)hdr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); + print_image_hdr (hdr); puts (" Verifying Checksum ... "); - if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { - puts (" Bad Data CRC\n"); + if (!image_check_dcrc (hdr)) { + puts ("Bad Data CRC\n"); + } else { + puts ("OK\n"); } - puts ("OK\n"); next_sector: ; } next_bank: ; @@ -1400,11 +1308,11 @@ void print_image_hdr (image_header_t *hdr) { #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) - time_t timestamp = (time_t)ntohl(hdr->ih_time); + time_t timestamp = (time_t)image_get_time (hdr); struct rtc_time tm; #endif - printf (" Image Name: %.*s\n", IH_NMLEN, hdr->ih_name); + 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", @@ -1412,19 +1320,19 @@ print_image_hdr (image_header_t *hdr) tm.tm_hour, tm.tm_min, tm.tm_sec); #endif puts (" Image Type: "); print_type(hdr); - printf ("\n Data Size: %d Bytes = ", ntohl(hdr->ih_size)); - print_size (ntohl(hdr->ih_size), "\n"); + 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", - ntohl(hdr->ih_load), ntohl(hdr->ih_ep)); + image_get_load (hdr), image_get_ep (hdr)); - if (hdr->ih_type == IH_TYPE_MULTI) { + if (image_check_type (hdr, IH_TYPE_MULTI)) { int i; ulong len; - ulong *len_ptr = (ulong *)((ulong)hdr + sizeof(image_header_t)); + ulong *len_ptr = (ulong *)((ulong)hdr + image_get_header_size ()); puts (" Contents:\n"); - for (i=0; (len = ntohl(*len_ptr)); ++i, ++len_ptr) { + for (i=0; (len = image_to_cpu (*len_ptr)); ++i, ++len_ptr) { printf (" Image %d: %8ld Bytes = ", i, len); print_size (len, "\n"); } @@ -1437,7 +1345,7 @@ print_type (image_header_t *hdr) { char *os, *arch, *type, *comp; - switch (hdr->ih_os) { + switch (image_get_os (hdr)) { case IH_OS_INVALID: os = "Invalid OS"; break; case IH_OS_NETBSD: os = "NetBSD"; break; case IH_OS_LINUX: os = "Linux"; break; @@ -1454,29 +1362,29 @@ print_type (image_header_t *hdr) default: os = "Unknown OS"; break; } - switch (hdr->ih_arch) { - case IH_CPU_INVALID: arch = "Invalid CPU"; break; - case IH_CPU_ALPHA: arch = "Alpha"; break; - case IH_CPU_ARM: arch = "ARM"; break; - case IH_CPU_AVR32: arch = "AVR32"; break; - case IH_CPU_BLACKFIN: arch = "Blackfin"; break; - case IH_CPU_I386: arch = "Intel x86"; break; - case IH_CPU_IA64: arch = "IA64"; break; - case IH_CPU_M68K: arch = "M68K"; break; - case IH_CPU_MICROBLAZE: arch = "Microblaze"; break; - case IH_CPU_MIPS64: arch = "MIPS 64 Bit"; break; - case IH_CPU_MIPS: arch = "MIPS"; break; - case IH_CPU_NIOS2: arch = "Nios-II"; break; - case IH_CPU_NIOS: arch = "Nios"; break; - case IH_CPU_PPC: arch = "PowerPC"; break; - case IH_CPU_S390: arch = "IBM S390"; break; - case IH_CPU_SH: arch = "SuperH"; break; - case IH_CPU_SPARC64: arch = "SPARC 64 Bit"; break; - case IH_CPU_SPARC: arch = "SPARC"; break; + switch (image_get_arch (hdr)) { + case IH_ARCH_INVALID: arch = "Invalid CPU"; break; + case IH_ARCH_ALPHA: arch = "Alpha"; break; + case IH_ARCH_ARM: arch = "ARM"; break; + case IH_ARCH_AVR32: arch = "AVR32"; break; + case IH_ARCH_BLACKFIN: arch = "Blackfin"; break; + case IH_ARCH_I386: arch = "Intel x86"; break; + case IH_ARCH_IA64: arch = "IA64"; break; + case IH_ARCH_M68K: arch = "M68K"; break; + case IH_ARCH_MICROBLAZE:arch = "Microblaze"; break; + case IH_ARCH_MIPS64: arch = "MIPS 64 Bit"; break; + case IH_ARCH_MIPS: arch = "MIPS"; break; + case IH_ARCH_NIOS2: arch = "Nios-II"; break; + case IH_ARCH_NIOS: arch = "Nios"; break; + case IH_ARCH_PPC: arch = "PowerPC"; break; + case IH_ARCH_S390: arch = "IBM S390"; break; + case IH_ARCH_SH: arch = "SuperH"; break; + case IH_ARCH_SPARC64: arch = "SPARC 64 Bit"; break; + case IH_ARCH_SPARC: arch = "SPARC"; break; default: arch = "Unknown Architecture"; break; } - switch (hdr->ih_type) { + switch (image_get_type (hdr)) { case IH_TYPE_INVALID: type = "Invalid Image"; break; case IH_TYPE_STANDALONE:type = "Standalone Program"; break; case IH_TYPE_KERNEL: type = "Kernel Image"; break; @@ -1488,7 +1396,7 @@ print_type (image_header_t *hdr) default: type = "Unknown Image"; break; } - switch (hdr->ih_comp) { + switch (image_get_comp (hdr)) { case IH_COMP_NONE: comp = "uncompressed"; break; case IH_COMP_GZIP: comp = "gzip compressed"; break; case IH_COMP_BZIP2: comp = "bzip2 compressed"; break; @@ -1594,7 +1502,7 @@ do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], image_header_t *hdr = &header; void (*entry_point)(bd_t *); - entry_point = (void (*)(bd_t *)) ntohl(hdr->ih_ep); + entry_point = (void (*)(bd_t *))image_get_ep (hdr); printf ("## Transferring control to RTEMS (at address %08lx) ...\n", (ulong)entry_point); @@ -1617,7 +1525,7 @@ do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], image_header_t *hdr = &header; char str[80]; - sprintf(str, "%x", ntohl(hdr->ih_ep)); /* write entry-point into string */ + sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */ setenv("loadaddr", str); do_bootvx(cmdtp, 0, 0, NULL); } @@ -1630,7 +1538,7 @@ do_bootm_qnxelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char *local_args[2]; char str[16]; - sprintf(str, "%x", ntohl(hdr->ih_ep)); /* write entry-point into string */ + sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */ local_args[0] = argv[0]; local_args[1] = str; /* and provide it via the arguments */ do_bootelf(cmdtp, 0, 2, local_args); diff --git a/common/cmd_doc.c b/common/cmd_doc.c index 3d717c0..b20a2e1 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -263,11 +263,11 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) hdr = (image_header_t *)addr; - if (hdr->ih_magic == IH_MAGIC) { + if (image_check_magic (hdr)) { print_image_hdr (hdr); - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); + cnt = image_get_image_size (hdr); cnt -= SECTORSIZE; } else { puts ("\n** Bad Magic Number **\n"); diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index 7349412..3b8f80b 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -836,13 +836,13 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + if (!image_get_magic (hdr)) { printf ("Bad Magic Number\n"); return 1; } - print_image_hdr(hdr); + print_image_hdr (hdr); - imsize= ntohl(hdr->ih_size)+sizeof(image_header_t); + imsize= image_get_image_size (hdr); nrofblk=imsize/512; if((imsize%512)>0) nrofblk++; @@ -861,7 +861,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* Loading ok, update default load address */ load_addr = addr; - if(hdr->ih_type == IH_TYPE_KERNEL) { + if(image_check_type (hdr, IH_TYPE_KERNEL)) { /* Check if we should attempt an auto-start */ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { char *local_args[2]; diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index f55447a..4030d04 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -221,13 +221,13 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) image_header_t *hdr = &header; ulong data; - memmove (&header, (char *)fpga_data, sizeof(image_header_t)); - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + memmove (&header, (char *)fpga_data, image_get_header_size ()); + if (!image_check_magic (hdr)) { puts ("Bad Magic Number\n"); return 1; } - data = ((ulong)fpga_data + sizeof(image_header_t)); - data_size = ntohl(hdr->ih_size); + data = ((ulong)fpga_data + image_get_header_size ()); + data_size = image_get_data_size (hdr); rc = fpga_load (dev, (void *)data, data_size); } break; diff --git a/common/cmd_ide.c b/common/cmd_ide.c index c38be4f..bcd1325 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -366,7 +366,7 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *boot_device = NULL; char *ep; int dev, part = 0; - ulong addr, cnt, checksum; + ulong addr, cnt; disk_partition_t info; image_header_t *hdr; int rcode = 0; @@ -448,27 +448,23 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { printf("\n** Bad Magic Number **\n"); show_boot_progress (-49); return 1; } show_boot_progress (49); - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) { + if (!image_check_hcrc (hdr)) { puts ("\n** Bad Header Checksum **\n"); show_boot_progress (-50); return 1; } show_boot_progress (50); - hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */ print_image_hdr (hdr); - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); + cnt = image_get_image_size (hdr); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 8d6c959..bfa39d7 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -514,16 +514,16 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, hdr = (image_header_t *) addr; - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); + if (!image_check_magic (hdr)) { + printf("\n** Bad Magic Number 0x%x **\n", image_get_magic (hdr)); show_boot_progress (-57); return 1; } show_boot_progress (57); - print_image_hdr(hdr); + print_image_hdr (hdr); - cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t)); + cnt = image_get_image_size (hdr); if (jffs2) { nand_read_options_t opts; memset(&opts, 0, sizeof(opts)); @@ -982,14 +982,14 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) == IH_MAGIC) { + if (image_check_magic (hdr)) { print_image_hdr (hdr); - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); + cnt = image_get_image_size (hdr); cnt -= SECTORSIZE; } else { - printf ("\n** Bad Magic Number 0x%x **\n", ntohl(hdr->ih_magic)); + printf ("\n** Bad Magic Number 0x%x **\n", image_get_magic (hdr)); show_boot_progress (-57); return 1; } diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 1cdec15..c2b27a5 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -207,7 +207,7 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *boot_device = NULL; char *ep; int dev, part = 0; - ulong addr, cnt, checksum; + ulong addr, cnt; disk_partition_t info; image_header_t *hdr; int rcode = 0; @@ -275,22 +275,18 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) == IH_MAGIC) { + if (!image_check_magic (hdr)) { printf("\n** Bad Magic Number **\n"); return 1; } - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) { + if (!image_check_hcrc (hdr)) { puts ("\n** Bad Header Checksum **\n"); return 1; } - hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */ print_image_hdr (hdr); - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); + cnt = image_get_image_size (hdr); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; diff --git a/common/cmd_usb.c b/common/cmd_usb.c index c6b17c2..db2e754 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -311,7 +311,7 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *boot_device = NULL; char *ep; int dev, part=1, rcode; - ulong addr, cnt, checksum; + ulong addr, cnt; disk_partition_t info; image_header_t *hdr; block_dev_desc_t *stor_dev; @@ -388,23 +388,19 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + if (!image_get_magic (hdr)) { printf("\n** Bad Magic Number **\n"); return 1; } - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) { + if (!image_check_hcrc (hdr)) { puts ("\n** Bad Header Checksum **\n"); return 1; } - hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */ print_image_hdr (hdr); - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); + cnt = image_get_image_size (hdr); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index 52e0614..ab579cd 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -38,14 +38,13 @@ int do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { ulong addr = load_addr, dest = 0; - ulong data, len, checksum; + ulong data, len; ulong *len_ptr; int i, verify, part = 0; char pbuf[10], *s; - image_header_t header; + image_header_t *hdr; - s = getenv("verify"); - verify = (s && (*s == 'n')) ? 0 : 1; + verify = getenv_verify (); if (argc > 1) { addr = simple_strtoul(argv[1], NULL, 16); @@ -59,50 +58,41 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) printf("## Copying from image at %08lx ...\n", addr); - /* Copy header so we can blank CRC field for re-calculation */ - memmove(&header, (char *) addr, sizeof (image_header_t)); + hdr = (image_header_t *)addr; - if (ntohl(header.ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { printf("Bad Magic Number\n"); return 1; } - data = (ulong) & header; - len = sizeof (image_header_t); - - checksum = ntohl(header.ih_hcrc); - header.ih_hcrc = 0; - - if (crc32(0, (char *) data, len) != checksum) { + if (!image_check_hcrc (hdr)) { printf("Bad Header Checksum\n"); return 1; } #ifdef DEBUG - print_image_hdr((image_header_t *) addr); + print_image_hdr (hdr); #endif - data = addr + sizeof (image_header_t); - len = ntohl(header.ih_size); - - if (header.ih_type != IH_TYPE_MULTI) { + if (!image_check_type (hdr, IH_TYPE_MULTI)) { printf("Wrong Image Type for %s command\n", cmdtp->name); return 1; } - if (header.ih_comp != IH_COMP_NONE) { + if (image_get_comp (hdr) != IH_COMP_NONE) { printf("Wrong Compression Type for %s command\n", cmdtp->name); return 1; } if (verify) { printf(" Verifying Checksum ... "); - if (crc32(0, (char *) data, len) != ntohl(header.ih_dcrc)) { + if (!image_check_dcrc (hdr)) { printf("Bad Data CRC\n"); return 1; } printf("OK\n"); } + data = image_get_data (hdr); len_ptr = (ulong *) data; data += 4; /* terminator */ @@ -110,7 +100,7 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) data += 4; if (argc > 2 && part > i) { u_long tail; - len = ntohl(len_ptr[i]); + len = image_to_cpu (len_ptr[i]); tail = len % 4; data += len; if (tail) { @@ -122,7 +112,7 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) printf("Bad Image Part\n"); return 1; } - len = ntohl(len_ptr[part]); + len = image_to_cpu (len_ptr[part]); if (argc > 3) { memcpy((char *) dest, (char *) data, len); diff --git a/common/image.c b/common/image.c new file mode 100644 index 0000000..7a0a3d2 --- /dev/null +++ b/common/image.c @@ -0,0 +1,91 @@ +/* + * (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 + */ +#ifndef USE_HOSTCC +# include +# include +#else +# include "mkimage.h" +#endif + +#include + +unsigned long crc32 (unsigned long, const unsigned char *, unsigned int); + +int image_check_hcrc (image_header_t *hdr) +{ + ulong hcrc; + ulong len = image_get_header_size (); + image_header_t header; + + /* Copy header so we can blank CRC field for re-calculation */ + memmove (&header, (char *)hdr, image_get_header_size ()); + image_set_hcrc (&header, 0); + + hcrc = crc32 (0, (unsigned char *)&header, len); + + return (hcrc == image_get_hcrc (hdr)); +} + +int image_check_dcrc (image_header_t *hdr) +{ + ulong data = image_get_data (hdr); + ulong len = image_get_data_size (hdr); + ulong dcrc = crc32 (0, (unsigned char *)data, len); + + return (dcrc == image_get_dcrc (hdr)); +} + +int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz) +{ + ulong dcrc = 0; + ulong len = image_get_data_size (hdr); + ulong data = image_get_data (hdr); + +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + ulong cdata = data; + ulong edata = cdata + len; + + while (cdata < edata) { + ulong chunk = edata - cdata; + + if (chunk > chunksz) + chunk = chunksz; + dcrc = crc32 (dcrc, (unsigned char *)cdata, chunk); + cdata += chunk; + + WATCHDOG_RESET (); + } +#else + dcrc = crc32 (0, (unsigned char *)data, len); +#endif + + return (dcrc == image_get_dcrc (hdr)); +} + +int getenv_verify (void) +{ + char *s = getenv ("verify"); + return (s && (*s == 'n')) ? 0 : 1; +} diff --git a/common/lynxkdi.c b/common/lynxkdi.c index 76a271b..16dc968 100644 --- a/common/lynxkdi.c +++ b/common/lynxkdi.c @@ -25,10 +25,10 @@ DECLARE_GLOBAL_DATA_PTR; #if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR) void lynxkdi_boot ( image_header_t *hdr ) { - void (*lynxkdi)(void) = (void(*)(void)) ntohl(hdr->ih_ep); + void (*lynxkdi)(void) = (void(*)(void))image_get_ep (hdr); lynxos_bootparms_t *parms = (lynxos_bootparms_t *)0x0020; bd_t *kbd; - u32 *psz = (u32 *)(ntohl(hdr->ih_load) + 0x0204); + u32 *psz = (u32 *)(image_get_load (hdr) + 0x0204); memset( parms, 0, sizeof(*parms)); kbd = gd->bd; @@ -40,9 +40,9 @@ 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) == ntohl(hdr->ih_size) ){ /* FIXME: NOT SURE HERE ! */ + if( le32_to_cpu(*psz) == image_get_data_size (hdr) ){ /* FIXME: NOT SURE HERE ! */ char *args; - char *cmdline = (char *)(ntohl(hdr->ih_load) + 0x020c); + char *cmdline = (char *)(image_get_load (hdr) + 0x020c); int len; printf("Booting Bluecat KDI ...\n"); diff --git a/examples/eepro100_eeprom.c b/examples/eepro100_eeprom.c index a52e68d..2b15d05 100644 --- a/examples/eepro100_eeprom.c +++ b/examples/eepro100_eeprom.c @@ -17,8 +17,9 @@ * and release the resulting code under the GPL. */ -#define _PPC_STRING_H_ /* avoid unnecessary str/mem functions */ -#define _LINUX_STRING_H_ /* avoid unnecessary str/mem functions */ +/* avoid unnecessary memcpy function */ +#define __HAVE_ARCH_MEMCPY +#define _PPC_STRING_H_ #include #include diff --git a/include/image.h b/include/image.h index 432fa22..c9f4298 100644 --- a/include/image.h +++ b/include/image.h @@ -1,4 +1,6 @@ /* + * (C) Copyright 2008 Semihalf + * * (C) Copyright 2000-2005 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * @@ -31,6 +33,11 @@ #ifndef __IMAGE_H__ #define __IMAGE_H__ +#include +#ifndef USE_HOSTCC +#include +#endif + /* * Operating System Codes */ @@ -59,25 +66,25 @@ /* * CPU Architecture Codes (supported by Linux) */ -#define IH_CPU_INVALID 0 /* Invalid CPU */ -#define IH_CPU_ALPHA 1 /* Alpha */ -#define IH_CPU_ARM 2 /* ARM */ -#define IH_CPU_I386 3 /* Intel x86 */ -#define IH_CPU_IA64 4 /* IA64 */ -#define IH_CPU_MIPS 5 /* MIPS */ -#define IH_CPU_MIPS64 6 /* MIPS 64 Bit */ -#define IH_CPU_PPC 7 /* PowerPC */ -#define IH_CPU_S390 8 /* IBM S390 */ -#define IH_CPU_SH 9 /* SuperH */ -#define IH_CPU_SPARC 10 /* Sparc */ -#define IH_CPU_SPARC64 11 /* Sparc 64 Bit */ -#define IH_CPU_M68K 12 /* M68K */ -#define IH_CPU_NIOS 13 /* Nios-32 */ -#define IH_CPU_MICROBLAZE 14 /* MicroBlaze */ -#define IH_CPU_NIOS2 15 /* Nios-II */ -#define IH_CPU_BLACKFIN 16 /* Blackfin */ -#define IH_CPU_AVR32 17 /* AVR32 */ -#define IH_CPU_ST200 18 /* STMicroelectronics ST200 */ +#define IH_ARCH_INVALID 0 /* Invalid CPU */ +#define IH_ARCH_ALPHA 1 /* Alpha */ +#define IH_ARCH_ARM 2 /* ARM */ +#define IH_ARCH_I386 3 /* Intel x86 */ +#define IH_ARCH_IA64 4 /* IA64 */ +#define IH_ARCH_MIPS 5 /* MIPS */ +#define IH_ARCH_MIPS64 6 /* MIPS 64 Bit */ +#define IH_ARCH_PPC 7 /* PowerPC */ +#define IH_ARCH_S390 8 /* IBM S390 */ +#define IH_ARCH_SH 9 /* SuperH */ +#define IH_ARCH_SPARC 10 /* Sparc */ +#define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */ +#define IH_ARCH_M68K 12 /* M68K */ +#define IH_ARCH_NIOS 13 /* Nios-32 */ +#define IH_ARCH_MICROBLAZE 14 /* MicroBlaze */ +#define IH_ARCH_NIOS2 15 /* Nios-II */ +#define IH_ARCH_BLACKFIN 16 /* Blackfin */ +#define IH_ARCH_AVR32 17 /* AVR32 */ +#define IH_ARCH_ST200 18 /* STMicroelectronics ST200 */ /* * Image Types @@ -157,5 +164,137 @@ typedef struct image_header { uint8_t ih_name[IH_NMLEN]; /* Image Name */ } image_header_t; +#define image_to_cpu(x) ntohl(x) +#define cpu_to_image(x) htonl(x) + +static inline uint32_t image_get_header_size (void) +{ + return (sizeof (image_header_t)); +} + +#define image_get_hdr_l(f) \ + static inline uint32_t image_get_##f(image_header_t *hdr) \ + { \ + return image_to_cpu (hdr->ih_##f); \ + } +image_get_hdr_l (magic); +image_get_hdr_l (hcrc); +image_get_hdr_l (time); +image_get_hdr_l (size); +image_get_hdr_l (load); +image_get_hdr_l (ep); +image_get_hdr_l (dcrc); + +#define image_get_hdr_b(f) \ + static inline uint8_t image_get_##f(image_header_t *hdr) \ + { \ + return hdr->ih_##f; \ + } +image_get_hdr_b (os); +image_get_hdr_b (arch); +image_get_hdr_b (type); +image_get_hdr_b (comp); + +static inline char *image_get_name (image_header_t *hdr) +{ + return (char *)hdr->ih_name; +} + +static inline uint32_t image_get_data_size (image_header_t *hdr) +{ + return image_get_size (hdr); +} +static inline uint32_t image_get_image_size (image_header_t *hdr) +{ + return (image_get_size (hdr) + image_get_header_size ()); +} +static inline ulong image_get_data (image_header_t *hdr) +{ + return ((ulong)hdr + image_get_header_size ()); +} + +#define image_set_hdr_l(f) \ + static inline void image_set_##f(image_header_t *hdr, uint32_t val) \ + { \ + hdr->ih_##f = cpu_to_image (val); \ + } +image_set_hdr_l (magic); +image_set_hdr_l (hcrc); +image_set_hdr_l (time); +image_set_hdr_l (size); +image_set_hdr_l (load); +image_set_hdr_l (ep); +image_set_hdr_l (dcrc); + +#define image_set_hdr_b(f) \ + static inline void image_set_##f(image_header_t *hdr, uint8_t val) \ + { \ + hdr->ih_##f = val; \ + } +image_set_hdr_b (os); +image_set_hdr_b (arch); +image_set_hdr_b (type); +image_set_hdr_b (comp); + +static inline void image_set_name (image_header_t *hdr, const char *name) +{ + strncpy (image_get_name (hdr), name, IH_NMLEN); +} + +int image_check_hcrc (image_header_t *hdr); +int image_check_dcrc (image_header_t *hdr); +int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize); +int getenv_verify (void); + +static inline int image_check_magic (image_header_t *hdr) +{ + return (image_get_magic (hdr) == IH_MAGIC); +} +static inline int image_check_type (image_header_t *hdr, uint8_t type) +{ + return (image_get_type (hdr) == type); +} +static inline int image_check_arch (image_header_t *hdr, uint8_t arch) +{ + return (image_get_arch (hdr) == arch); +} +static inline int image_check_os (image_header_t *hdr, uint8_t os) +{ + return (image_get_os (hdr) == os); +} + +#ifndef USE_HOSTCC +static inline int image_check_target_arch (image_header_t *hdr) +{ +#if defined(__ARM__) + if (!image_check_arch (hdr, IH_ARCH_ARM)) +#elif defined(__avr32__) + if (!image_check_arch (hdr, IH_ARCH_AVR32)) +#elif defined(__bfin__) + if (!image_check_arch (hdr, IH_ARCH_BLACKFIN)) +#elif defined(__I386__) + if (!image_check_arch (hdr, IH_ARCH_I386)) +#elif defined(__M68K__) + if (!image_check_arch (hdr, IH_ARCH_M68K)) +#elif defined(__microblaze__) + if (!image_check_arch (hdr, IH_ARCH_MICROBLAZE)) +#elif defined(__mips__) + if (!image_check_arch (hdr, IH_ARCH_MIPS)) +#elif defined(__nios__) + if (!image_check_arch (hdr, IH_ARCH_NIOS)) +#elif defined(__nios2__) + if (!image_check_arch (hdr, IH_ARCH_NIOS2)) +#elif defined(__PPC__) + if (!image_check_arch (hdr, IH_ARCH_PPC)) +#elif defined(__sh__) + if (!image_check_arch (hdr, IH_ARCH_SH)) +#else +# error Unknown CPU type +#endif + return 0; + + return 1; +} +#endif -#endif /* __IMAGE_H__ */ +#endif /* __IMAGE_H__ */ diff --git a/lib_arm/armlinux.c b/lib_arm/armlinux.c index 6d32a41..09038cc 100644 --- a/lib_arm/armlinux.c +++ b/lib_arm/armlinux.c @@ -72,7 +72,7 @@ extern image_header_t header; /* from cmd_bootm.c */ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong addr, ulong *len_ptr, int verify) { - ulong len = 0, checksum; + ulong len = 0; ulong initrd_start, initrd_end; ulong data; void (*theKernel)(int zero, int arch, uint params); @@ -83,7 +83,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char *commandline = getenv ("bootargs"); #endif - theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep); + theKernel = (void (*)(int, int, uint))image_get_ep (hdr); /* * Check if there is an initrd image @@ -98,26 +98,20 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* Copy header so we can blank CRC field for re-calculation */ #ifdef CONFIG_HAS_DATAFLASH if (addr_dataflash (addr)) { - read_dataflash (addr, sizeof (image_header_t), + read_dataflash (addr, image_get_header_size (), (char *) &header); } else #endif memcpy (&header, (char *) addr, - sizeof (image_header_t)); + image_get_header_size ()); - if (ntohl (hdr->ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { printf ("Bad Magic Number\n"); show_boot_progress (-10); do_reset (cmdtp, flag, argc, argv); } - data = (ulong) & header; - len = sizeof (image_header_t); - - checksum = ntohl (hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (unsigned char *) data, len) != checksum) { + if (!image_check_hcrc (hdr)) { printf ("Bad Header Checksum\n"); show_boot_progress (-11); do_reset (cmdtp, flag, argc, argv); @@ -127,8 +121,8 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], print_image_hdr (hdr); - data = addr + sizeof (image_header_t); - len = ntohl (hdr->ih_size); + data = image_get_data (hdr); + len = image_get_data_size (hdr); #ifdef CONFIG_HAS_DATAFLASH if (addr_dataflash (addr)) { @@ -138,11 +132,8 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #endif if (verify) { - ulong csum = 0; - printf (" Verifying Checksum ... "); - csum = crc32 (0, (unsigned char *) data, len); - if (csum != ntohl (hdr->ih_dcrc)) { + if (!image_get_dcrc (hdr)) { printf ("Bad Data CRC\n"); show_boot_progress (-12); do_reset (cmdtp, flag, argc, argv); @@ -152,9 +143,9 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], show_boot_progress (11); - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_ARM) || - (hdr->ih_type != IH_TYPE_RAMDISK)) { + if (!image_check_os (hdr, IH_OS_LINUX) || + !image_check_arch (hdr, IH_ARCH_ARM) || + !image_check_type (hdr, IH_TYPE_RAMDISK)) { printf ("No Linux ARM Ramdisk Image\n"); show_boot_progress (-13); do_reset (cmdtp, flag, argc, argv); @@ -164,15 +155,15 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* *we need to copy the ramdisk to SRAM to let Linux boot */ - memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len); - data = ntohl(hdr->ih_load); + memmove ((void *)image_get_load (hdr), (uchar *)data, len); + data = image_get_load (hdr); #endif /* CONFIG_B2 || CONFIG_EVB4510 */ /* * Now check if we have a multifile image */ - } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = ntohl (len_ptr[0]) % 4; + } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) { + ulong tail = image_to_cpu (len_ptr[0]) % 4; int i; show_boot_progress (13); @@ -183,12 +174,12 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], for (i = 1; len_ptr[i]; ++i) data += 4; /* add kernel length, and align */ - data += ntohl (len_ptr[0]); + data += image_to_cpu (len_ptr[0]); if (tail) { data += 4 - tail; } - len = ntohl (len_ptr[1]); + len = image_to_cpu (len_ptr[1]); } else { /* diff --git a/lib_avr32/avr32_linux.c b/lib_avr32/avr32_linux.c index 62afbd2..44827ec 100644 --- a/lib_avr32/avr32_linux.c +++ b/lib_avr32/avr32_linux.c @@ -36,8 +36,6 @@ extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* CPU-specific hook to allow flushing of caches, etc. */ extern void prepare_to_boot(void); -extern image_header_t header; /* from cmd_bootm.c */ - static struct tag *setup_start_tag(struct tag *params) { params->hdr.tag = ATAG_CORE; @@ -181,7 +179,6 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], unsigned long data, len = 0; unsigned long initrd_start, initrd_end; unsigned long image_start, image_end; - unsigned long checksum; void (*theKernel)(int magic, void *tagtable); image_header_t *hdr; struct tag *params, *params_start; @@ -189,9 +186,9 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], hdr = (image_header_t *)addr; image_start = addr; - image_end = addr + hdr->ih_size; + image_end = addr + image_get_data_size (hdr); - theKernel = (void *)ntohl(hdr->ih_ep); + theKernel = (void *)image_get_ep (hdr); /* * Check if there is an initrd image @@ -200,42 +197,28 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], show_boot_progress (9); addr = simple_strtoul(argv[2], NULL, 16); + hdr = (image_header_t *)addr; printf("## Loading RAMDISK image at %08lx ...\n", addr); - memcpy(&header, (char *)addr, sizeof(header)); - hdr = &header; - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { puts("Bad Magic Number\n"); show_boot_progress (-10); do_reset(cmdtp, flag, argc, argv); } - data = (unsigned long)hdr; - len = sizeof(*hdr); - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32(0, (unsigned char *)data, len) != checksum) { + 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); - - data = addr + sizeof(header); - len = ntohl(hdr->ih_size); + print_image_hdr (hdr); if (verify) { - unsigned long csum = 0; - puts(" Verifying Checksum ... "); - csum = crc32(0, (unsigned char *)data, len); - if (csum != ntohl(hdr->ih_dcrc)) { + if (!image_check_dcrc (hdr)) { puts("Bad Data CRC\n"); show_boot_progress (-12); do_reset(cmdtp, flag, argc, argv); @@ -245,15 +228,19 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], show_boot_progress (11); - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_AVR32) || - (hdr->ih_type != IH_TYPE_RAMDISK)) { + if (!image_check_os (hdr, IH_OS_LINUX) || + !image_check_arch (hdr, IH_ARCH_AVR32) || + !image_check_type (hdr, IH_TYPE_RAMDISK)) { puts("Not a Linux/AVR32 RAMDISK image\n"); show_boot_progress (-13); do_reset(cmdtp, flag, argc, argv); } - } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = ntohl (len_ptr[0]) % 4; + + data = image_get_data (hdr); + len = image_get_data_size (hdr); + + } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) { + ulong tail = image_to_cpu (len_ptr[0]) % 4; int i; show_boot_progress (13); @@ -264,12 +251,12 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], for (i = 1; len_ptr[i]; ++i) data += 4; /* add kernel length, and align */ - data += ntohl (len_ptr[0]); + data += image_to_cpu (len_ptr[0]); if (tail) { data += 4 - tail; } - len = ntohl (len_ptr[1]); + len = image_to_cpu (len_ptr[1]); } else { /* no initrd image */ show_boot_progress (14); diff --git a/lib_blackfin/bf533_linux.c b/lib_blackfin/bf533_linux.c index 80a3dc7..26c6534 100644 --- a/lib_blackfin/bf533_linux.c +++ b/lib_blackfin/bf533_linux.c @@ -52,12 +52,13 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], { int (*appl) (char *cmdline); char *cmdline; + image_header_t *hdr = &header; #ifdef SHARED_RESOURCES swap_to(FLASH); #endif - appl = (int (*)(char *))ntohl(header.ih_ep); + appl = (int (*)(char *))image_get_ep (hdr); printf("Starting Kernel at = %x\n", appl); cmdline = make_command_line(); if (icache_status()) { diff --git a/lib_i386/i386_linux.c b/lib_i386/i386_linux.c index b4a6f5a..67a78c4 100644 --- a/lib_i386/i386_linux.c +++ b/lib_i386/i386_linux.c @@ -50,7 +50,7 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], { void *base_ptr; - ulong len = 0, checksum; + ulong len = 0; ulong initrd_start, initrd_end; ulong data; image_header_t *hdr = &header; @@ -60,48 +60,37 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], */ if (argc >= 3) { addr = simple_strtoul(argv[2], NULL, 16); + hdr = (image_header_t *)addr; printf ("## Loading Ramdisk Image at %08lx ...\n", addr); - /* Copy header so we can blank CRC field for re-calculation */ - memcpy (&header, (char *)addr, sizeof(image_header_t)); - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { printf ("Bad Magic Number\n"); do_reset (cmdtp, flag, argc, argv); } - data = (ulong)&header; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (char *)data, len) != checksum) { + if (!image_check_hcrc (hdr)) { printf ("Bad Header Checksum\n"); do_reset (cmdtp, flag, argc, argv); } print_image_hdr (hdr); - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); + data = image_get_data (hdr); + len = image_get_data_size (hdr); if (verify) { - ulong csum = 0; - printf (" Verifying Checksum ... "); - csum = crc32 (0, (char *)data, len); - if (csum != ntohl(hdr->ih_dcrc)) { + if (!image_check_dcrc (hdr)) { printf ("Bad Data CRC\n"); do_reset (cmdtp, flag, argc, argv); } printf ("OK\n"); } - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_I386) || - (hdr->ih_type != IH_TYPE_RAMDISK) ) { + if (!image_check_os (hdr, IH_OS_LINUX) || + !image_check_arch (hdr, IH_ARCH_I386) || + !image_check_type (hdr, IH_TYPE_RAMDISK)) { printf ("No Linux i386 Ramdisk Image\n"); do_reset (cmdtp, flag, argc, argv); } @@ -109,8 +98,8 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* * Now check if we have a multifile image */ - } else if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = ntohl(len_ptr[0]) % 4; + } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) { + ulong tail = image_to_cpu (len_ptr[0]) % 4; int i; /* skip kernel length and terminator */ @@ -119,12 +108,12 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], for (i=1; len_ptr[i]; ++i) data += 4; /* add kernel length, and align */ - data += ntohl(len_ptr[0]); + data += image_to_cpu (len_ptr[0]); if (tail) { data += 4 - tail; } - len = ntohl(len_ptr[1]); + len = image_to_cpu (len_ptr[1]); } else { /* @@ -152,12 +141,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 ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) { + if (image_check_type (hdr, 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 + sizeof(image_header_t), ntohl(hdr->ih_size), + base_ptr = load_zimage((void*)addr + image_get_header_size (), + image_get_data_size (hdr), initrd_start, initrd_end-initrd_start, 0); if (NULL == base_ptr) { diff --git a/lib_i386/zimage.c b/lib_i386/zimage.c index 3510f2f..20f9f8d 100644 --- a/lib_i386/zimage.c +++ b/lib_i386/zimage.c @@ -251,25 +251,24 @@ image_header_t *fake_zimage_header(image_header_t *hdr, void *ptr, int size) #else checksum = 0; #endif - memset(hdr, 0, sizeof(image_header_t)); + memset(hdr, 0, image_get_header_size ()); /* Build new header */ - hdr->ih_magic = htonl(IH_MAGIC); - hdr->ih_time = 0; - hdr->ih_size = htonl(size); - hdr->ih_load = htonl(ZIMAGE_LOAD); - hdr->ih_ep = 0; - hdr->ih_dcrc = htonl(checksum); - hdr->ih_os = IH_OS_LINUX; - hdr->ih_arch = IH_CPU_I386; - hdr->ih_type = IH_TYPE_KERNEL; - hdr->ih_comp = IH_COMP_NONE; - - strncpy((char *)hdr->ih_name, "(none)", IH_NMLEN); - - checksum = crc32(0,(const char *)hdr,sizeof(image_header_t)); - - hdr->ih_hcrc = htonl(checksum); + 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; } diff --git a/lib_m68k/m68k_linux.c b/lib_m68k/m68k_linux.c index cc974c2..3759fd2 100644 --- a/lib_m68k/m68k_linux.c +++ b/lib_m68k/m68k_linux.c @@ -48,12 +48,14 @@ DECLARE_GLOBAL_DATA_PTR; extern image_header_t header; +int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], ulong addr, ulong * len_ptr, int verify) { ulong sp; - ulong len, checksum; + ulong len; ulong initrd_start, initrd_end; ulong cmd_start, cmd_end; ulong initrd_high; @@ -131,7 +133,7 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, } kernel = - (void (*)(bd_t *, ulong, ulong, ulong, ulong))ntohl(hdr->ih_ep); + (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); /* * Check if there is an initrd image @@ -142,25 +144,17 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, SHOW_BOOT_PROGRESS(9); addr = simple_strtoul(argv[2], NULL, 16); + hdr = (image_header_t *)addr; printf("## Loading RAMDisk Image at %08lx ...\n", addr); - /* Copy header so we can blank CRC field for re-calculation */ - memmove(&header, (char *)addr, sizeof(image_header_t)); - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { puts("Bad Magic Number\n"); SHOW_BOOT_PROGRESS(-10); do_reset(cmdtp, flag, argc, argv); } - data = (ulong) & header; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32(0, (uchar *) data, len) != checksum) { + if (!image_check_hcrc (hdr)) { puts("Bad Header Checksum\n"); SHOW_BOOT_PROGRESS(-11); do_reset(cmdtp, flag, argc, argv); @@ -168,36 +162,14 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, SHOW_BOOT_PROGRESS(10); - print_image_hdr(hdr); + print_image_hdr (hdr); - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); + data = image_get_data (hdr); + len = image_get_data_size (hdr); if (verify) { - ulong csum = 0; -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - ulong cdata = data, edata = cdata + len; -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - puts(" Verifying Checksum ... "); - -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - - while (cdata < edata) { - ulong chunk = edata - cdata; - - if (chunk > CHUNKSZ) - chunk = CHUNKSZ; - csum = crc32(csum, (uchar *) cdata, chunk); - cdata += chunk; - - WATCHDOG_RESET(); - } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - csum = crc32(0, (uchar *) data, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - - if (csum != ntohl(hdr->ih_dcrc)) { + if (!image_check_dcrc_wd (hdr, CHUNKSZ)) { puts("Bad Data CRC\n"); SHOW_BOOT_PROGRESS(-12); do_reset(cmdtp, flag, argc, argv); @@ -207,9 +179,9 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, SHOW_BOOT_PROGRESS(11); - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_M68K) || - (hdr->ih_type != IH_TYPE_RAMDISK)) { + if (!image_check_os (hdr, IH_OS_LINUX) || + !image_check_arch (hdr, IH_ARCH_M68K) || + !image_check_type (hdr, IH_TYPE_RAMDISK)) { puts("No Linux ColdFire Ramdisk Image\n"); SHOW_BOOT_PROGRESS(-13); do_reset(cmdtp, flag, argc, argv); @@ -218,8 +190,8 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, /* * Now check if we have a multifile image */ - } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) { - u_long tail = ntohl(len_ptr[0]) % 4; + } 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); @@ -230,12 +202,12 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, for (i = 1; len_ptr[i]; ++i) data += 4; /* add kernel length, and align */ - data += ntohl(len_ptr[0]); + data += image_to_cpu (len_ptr[0]); if (tail) { data += 4 - tail; } - len = ntohl(len_ptr[1]); + len = image_to_cpu (len_ptr[1]); } else { /* diff --git a/lib_microblaze/microblaze_linux.c b/lib_microblaze/microblaze_linux.c index 68b58d4..7cd9799 100644 --- a/lib_microblaze/microblaze_linux.c +++ b/lib_microblaze/microblaze_linux.c @@ -48,32 +48,24 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], char *commandline = getenv ("bootargs"); int i; - theKernel = (void (*)(char *))ntohl (hdr->ih_ep); + theKernel = (void (*)(char *))image_get_ep (hdr); /* Check if there is an initrd image */ if (argc >= 3) { show_boot_progress (9); addr = simple_strtoul (argv[2], NULL, 16); + hdr = (image_header_t *)addr; printf ("## Loading Ramdisk Image at %08lx ...\n", addr); - /* Copy header so we can blank CRC field for re-calculation */ - memcpy (&header, (char *)addr, sizeof (image_header_t)); - - if (ntohl (hdr->ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { printf ("Bad Magic Number\n"); show_boot_progress (-10); do_reset (cmdtp, flag, argc, argv); } - data = (ulong) & header; - len = sizeof (image_header_t); - - checksum = ntohl (hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (char *)data, len) != checksum) { + if (!image_check_magic (hdr)) { printf ("Bad Header Checksum\n"); show_boot_progress (-11); do_reset (cmdtp, flag, argc, argv); @@ -83,15 +75,12 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], print_image_hdr (hdr); - data = addr + sizeof (image_header_t); - len = ntohl (hdr->ih_size); + data = image_get_data (hdr); + len = image_get_data_size (hdr); if (verify) { - ulong csum = 0; - printf (" Verifying Checksum ... "); - csum = crc32 (0, (char *)data, len); - if (csum != ntohl (hdr->ih_dcrc)) { + if (!image_check_dcrc (hdr)) { printf ("Bad Data CRC\n"); show_boot_progress (-12); do_reset (cmdtp, flag, argc, argv); @@ -101,9 +90,9 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], show_boot_progress (11); - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_MICROBLAZE) || - (hdr->ih_type != IH_TYPE_RAMDISK)) { + if (!image_check_os (hdr, IH_OS_LINUX) || + !image_check_arch (hdr, IH_ARCH_MICROBLAZE) || + !image_check_type (hdr, IH_TYPE_RAMDISK)) { printf ("No Linux Microblaze Ramdisk Image\n"); show_boot_progress (-13); do_reset (cmdtp, flag, argc, argv); @@ -112,8 +101,8 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], /* * Now check if we have a multifile image */ - } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = ntohl (len_ptr[0]) % 4; + } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) { + ulong tail = image_to_cpu (len_ptr[0]) % 4; show_boot_progress (13); @@ -123,12 +112,12 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], for (i = 1; len_ptr[i]; ++i) data += 4; /* add kernel length, and align */ - data += ntohl (len_ptr[0]); + data += image_to_cpu (len_ptr[0]); if (tail) { data += 4 - tail; } - len = ntohl (len_ptr[1]); + len = image_to_cpu (len_ptr[1]); } else { /* diff --git a/lib_mips/mips_linux.c b/lib_mips/mips_linux.c index 556b180..0881b6d 100644 --- a/lib_mips/mips_linux.c +++ b/lib_mips/mips_linux.c @@ -51,7 +51,7 @@ static void linux_env_set (char * env_name, char * env_val); void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], ulong addr, ulong * len_ptr, int verify) { - ulong len = 0, checksum; + ulong len = 0; ulong initrd_start, initrd_end; ulong data; void (*theKernel) (int, char **, char **, int *); @@ -60,7 +60,7 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], char env_buf[12]; theKernel = - (void (*)(int, char **, char **, int *)) ntohl (hdr->ih_ep); + (void (*)(int, char **, char **, int *))image_get_ep (hdr); /* * Check if there is an initrd image @@ -69,25 +69,17 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], show_boot_progress (9); addr = simple_strtoul (argv[2], NULL, 16); + hdr = (image_header_t *)addr; printf ("## Loading Ramdisk Image at %08lx ...\n", addr); - /* Copy header so we can blank CRC field for re-calculation */ - memcpy (&header, (char *) addr, sizeof (image_header_t)); - - if (ntohl (hdr->ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { printf ("Bad Magic Number\n"); show_boot_progress (-10); do_reset (cmdtp, flag, argc, argv); } - data = (ulong) & header; - len = sizeof (image_header_t); - - checksum = ntohl (hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *) data, len) != checksum) { + if (!image_check_hcrc (hdr)) { printf ("Bad Header Checksum\n"); show_boot_progress (-11); do_reset (cmdtp, flag, argc, argv); @@ -97,15 +89,12 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], print_image_hdr (hdr); - data = addr + sizeof (image_header_t); - len = ntohl (hdr->ih_size); + data = image_get_data (hdr); + len = image_get_data_size (hdr); if (verify) { - ulong csum = 0; - printf (" Verifying Checksum ... "); - csum = crc32 (0, (uchar *) data, len); - if (csum != ntohl (hdr->ih_dcrc)) { + if (!image_check_dcrc (hdr)) { printf ("Bad Data CRC\n"); show_boot_progress (-12); do_reset (cmdtp, flag, argc, argv); @@ -115,9 +104,9 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], show_boot_progress (11); - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_MIPS) || - (hdr->ih_type != IH_TYPE_RAMDISK)) { + if (!image_check_os (hdr, IH_OS_LINUX) || + !image_check_arch (hdr, IH_ARCH_MIPS) || + !image_check_type (hdr, IH_TYPE_RAMDISK)) { printf ("No Linux MIPS Ramdisk Image\n"); show_boot_progress (-13); do_reset (cmdtp, flag, argc, argv); @@ -126,8 +115,8 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], /* * Now check if we have a multifile image */ - } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = ntohl (len_ptr[0]) % 4; + } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) { + ulong tail = image_to_cpu (len_ptr[0]) % 4; int i; show_boot_progress (13); @@ -138,12 +127,12 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], for (i = 1; len_ptr[i]; ++i) data += 4; /* add kernel length, and align */ - data += ntohl (len_ptr[0]); + data += image_to_cpu (len_ptr[0]); if (tail) { data += 4 - tail; } - len = ntohl (len_ptr[1]); + len = image_to_cpu (len_ptr[1]); } else { /* diff --git a/lib_nios2/nios_linux.c b/lib_nios2/nios_linux.c index 9eb3426..dea1ec1 100644 --- a/lib_nios2/nios_linux.c +++ b/lib_nios2/nios_linux.c @@ -31,7 +31,7 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong addr, ulong *len_ptr, int verify) { image_header_t *hdr = &header; - void (*kernel)(void) = (void (*)(void))ntohl (hdr->ih_ep); + void (*kernel)(void) = (void (*)(void))image_get_ep (hdr); /* For now we assume the Microtronix linux ... which only * needs to be called ;-) diff --git a/tools/Makefile b/tools/Makefile index af0de47..cbfca6d 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -23,7 +23,7 @@ BIN_FILES = img2srec$(SFX) mkimage$(SFX) envcrc$(SFX) ubsha1$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX) -OBJ_LINKS = environment.o crc32.o sha1.o +OBJ_LINKS = environment.o crc32.o sha1.o image.o OBJ_FILES = img2srec.o mkimage.o envcrc.o ubsha1.o gen_eth_addr.o bmp_logo.o ifeq ($(ARCH),mips) @@ -137,7 +137,7 @@ $(obj)img2srec$(SFX): $(obj)img2srec.o $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(STRIP) $@ -$(obj)mkimage$(SFX): $(obj)mkimage.o $(obj)crc32.o +$(obj)mkimage$(SFX): $(obj)mkimage.o $(obj)crc32.o $(obj)image.o $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(STRIP) $@ @@ -173,6 +173,9 @@ $(obj)crc32.o: $(obj)crc32.c $(obj)sha1.o: $(obj)sha1.c $(CC) -g $(CFLAGS) -c -o $@ $< +$(obj)image.o: $(obj)image.c + $(CC) -g $(CFLAGS) -c -o $@ $< + $(obj)mkimage.o: $(src)mkimage.c $(CC) -g $(CFLAGS) -c -o $@ $< @@ -217,6 +220,10 @@ $(obj)sha1.c: @rm -f $(obj)sha1.c ln -s $(src)../lib_generic/sha1.c $(obj)sha1.c +$(obj)image.c: + @rm -f $(obj)image.c + ln -s $(src)../common/image.c $(obj)image.c + $(LOGO_H): $(obj)bmp_logo $(LOGO_BMP) $(obj)./bmp_logo $(LOGO_BMP) >$@ diff --git a/tools/mkimage.c b/tools/mkimage.c index 2125130..8ced970 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -20,44 +20,7 @@ * MA 02111-1307 USA */ -#include -#include -#include -#include -#include -#ifndef __WIN32__ -#include /* for host / network byte order conversions */ -#endif -#include -#include -#include -#include - -#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__) -#include -#endif - -#ifdef __WIN32__ -typedef unsigned int __u32; - -#define SWAP_LONG(x) \ - ((__u32)( \ - (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ - (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ - (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ - (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; - -#define ntohl(a) SWAP_LONG(a) -#define htonl(a) SWAP_LONG(a) -#endif /* __WIN32__ */ - -#ifndef O_BINARY /* should be define'd on __WIN32__ */ -#define O_BINARY 0 -#endif - +#include "mkimage.h" #include extern int errno; @@ -77,24 +40,24 @@ typedef struct table_entry { } table_entry_t; table_entry_t arch_name[] = { - { IH_CPU_INVALID, NULL, "Invalid CPU", }, - { IH_CPU_ALPHA, "alpha", "Alpha", }, - { IH_CPU_ARM, "arm", "ARM", }, - { IH_CPU_I386, "x86", "Intel x86", }, - { IH_CPU_IA64, "ia64", "IA64", }, - { IH_CPU_M68K, "m68k", "MC68000", }, - { IH_CPU_MICROBLAZE, "microblaze", "MicroBlaze", }, - { IH_CPU_MIPS, "mips", "MIPS", }, - { IH_CPU_MIPS64, "mips64", "MIPS 64 Bit", }, - { IH_CPU_NIOS, "nios", "NIOS", }, - { IH_CPU_NIOS2, "nios2", "NIOS II", }, - { IH_CPU_PPC, "ppc", "PowerPC", }, - { IH_CPU_S390, "s390", "IBM S390", }, - { IH_CPU_SH, "sh", "SuperH", }, - { IH_CPU_SPARC, "sparc", "SPARC", }, - { IH_CPU_SPARC64, "sparc64", "SPARC 64 Bit", }, - { IH_CPU_BLACKFIN, "blackfin", "Blackfin", }, - { IH_CPU_AVR32, "avr32", "AVR32", }, + { IH_ARCH_INVALID, NULL, "Invalid CPU", }, + { IH_ARCH_ALPHA, "alpha", "Alpha", }, + { IH_ARCH_ARM, "arm", "ARM", }, + { IH_ARCH_I386, "x86", "Intel x86", }, + { IH_ARCH_IA64, "ia64", "IA64", }, + { IH_ARCH_M68K, "m68k", "MC68000", }, + { IH_ARCH_MICROBLAZE, "microblaze", "MicroBlaze", }, + { IH_ARCH_MIPS, "mips", "MIPS", }, + { IH_ARCH_MIPS64, "mips64", "MIPS 64 Bit", }, + { IH_ARCH_NIOS, "nios", "NIOS", }, + { IH_ARCH_NIOS2, "nios2", "NIOS II", }, + { IH_ARCH_PPC, "ppc", "PowerPC", }, + { IH_ARCH_S390, "s390", "IBM S390", }, + { IH_ARCH_SH, "sh", "SuperH", }, + { IH_ARCH_SPARC, "sparc", "SPARC", }, + { IH_ARCH_SPARC64, "sparc64", "SPARC 64 Bit", }, + { IH_ARCH_BLACKFIN, "blackfin", "Blackfin", }, + { IH_ARCH_AVR32, "avr32", "AVR32", }, { -1, "", "", }, }; @@ -167,7 +130,7 @@ int lflag = 0; int vflag = 0; int xflag = 0; int opt_os = IH_OS_LINUX; -int opt_arch = IH_CPU_PPC; +int opt_arch = IH_ARCH_PPC; int opt_type = IH_TYPE_KERNEL; int opt_comp = IH_COMP_GZIP; @@ -270,7 +233,7 @@ NXTARG: ; ep = addr; /* If XIP, entry point must be after the U-Boot header */ if (xflag) - ep += sizeof(image_header_t); + ep += image_get_header_size (); } /* @@ -278,11 +241,11 @@ NXTARG: ; * the size of the U-Boot header. */ if (xflag) { - if (ep != addr + sizeof(image_header_t)) { + if (ep != addr + image_get_header_size ()) { fprintf (stderr, "%s: For XIP, the entry point must be the load addr + %lu\n", cmdname, - (unsigned long)sizeof(image_header_t)); + (unsigned long)image_get_header_size ()); exit (EXIT_FAILURE); } } @@ -313,7 +276,7 @@ NXTARG: ; exit (EXIT_FAILURE); } - if ((unsigned)sbuf.st_size < sizeof(image_header_t)) { + if ((unsigned)sbuf.st_size < image_get_header_size ()) { fprintf (stderr, "%s: Bad size: \"%s\" is no valid image\n", cmdname, imagefile); @@ -329,36 +292,30 @@ NXTARG: ; } /* - * create copy of header so that we can blank out the - * checksum field for checking - this can't be done - * on the PROT_READ mapped data. + * image_check_hcrc() creates copy of header so that + * we can blank out the checksum field for checking - + * this can't be done on the PROT_READ mapped data. */ - memcpy (hdr, ptr, sizeof(image_header_t)); + hdr = (image_header_t *)ptr; - if (ntohl(hdr->ih_magic) != IH_MAGIC) { + if (!image_check_magic (hdr)) { fprintf (stderr, "%s: Bad Magic Number: \"%s\" is no valid image\n", cmdname, imagefile); exit (EXIT_FAILURE); } - data = (char *)hdr; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = htonl(0); /* clear for re-calculation */ - - if (crc32 (0, data, len) != checksum) { + if (!image_check_hcrc (hdr)) { fprintf (stderr, "%s: ERROR: \"%s\" has bad header checksum!\n", cmdname, imagefile); exit (EXIT_FAILURE); } - data = (char *)(ptr + sizeof(image_header_t)); - len = sbuf.st_size - sizeof(image_header_t) ; + data = (char *)image_get_data (hdr); + len = sbuf.st_size - image_get_header_size (); - if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) { + if (crc32(0, data, len) != image_get_dcrc (hdr)) { fprintf (stderr, "%s: ERROR: \"%s\" has corrupted data!\n", cmdname, imagefile); @@ -379,9 +336,9 @@ NXTARG: ; * * write dummy header, to be fixed later */ - memset (hdr, 0, sizeof(image_header_t)); + memset (hdr, 0, image_get_header_size ()); - if (write(ifd, hdr, sizeof(image_header_t)) != sizeof(image_header_t)) { + if (write(ifd, hdr, image_get_header_size ()) != image_get_header_size ()) { fprintf (stderr, "%s: Write error on %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); @@ -404,7 +361,7 @@ NXTARG: ; cmdname, file, strerror(errno)); exit (EXIT_FAILURE); } - size = htonl(sbuf.st_size); + size = cpu_to_image (sbuf.st_size); } else { size = 0; } @@ -469,27 +426,27 @@ NXTARG: ; hdr = (image_header_t *)ptr; checksum = crc32 (0, - (const char *)(ptr + sizeof(image_header_t)), - sbuf.st_size - sizeof(image_header_t) + (const char *)(ptr + image_get_header_size ()), + sbuf.st_size - image_get_header_size () ); /* Build new header */ - hdr->ih_magic = htonl(IH_MAGIC); - hdr->ih_time = htonl(sbuf.st_mtime); - hdr->ih_size = htonl(sbuf.st_size - sizeof(image_header_t)); - hdr->ih_load = htonl(addr); - hdr->ih_ep = htonl(ep); - hdr->ih_dcrc = htonl(checksum); - hdr->ih_os = opt_os; - hdr->ih_arch = opt_arch; - hdr->ih_type = opt_type; - hdr->ih_comp = opt_comp; + image_set_magic (hdr, IH_MAGIC); + image_set_time (hdr, sbuf.st_mtime); + image_set_size (hdr, sbuf.st_size - image_get_header_size ()); + image_set_load (hdr, addr); + image_set_ep (hdr, ep); + image_set_dcrc (hdr, checksum); + image_set_os (hdr, opt_os); + image_set_arch (hdr, opt_arch); + image_set_type (hdr, opt_type); + image_set_comp (hdr, opt_comp); - strncpy((char *)hdr->ih_name, name, IH_NMLEN); + image_set_name (hdr, name); - checksum = crc32(0,(const char *)hdr,sizeof(image_header_t)); + checksum = crc32 (0, (const char *)hdr, image_get_header_size ()); - hdr->ih_hcrc = htonl(checksum); + image_set_hcrc (hdr, checksum); print_header (hdr); @@ -554,14 +511,14 @@ copy_file (int ifd, const char *datafile, int pad) * reserved for it. */ - if ((unsigned)sbuf.st_size < sizeof(image_header_t)) { + if ((unsigned)sbuf.st_size < image_get_header_size ()) { fprintf (stderr, "%s: Bad size: \"%s\" is too small for XIP\n", cmdname, datafile); exit (EXIT_FAILURE); } - for (p=ptr; p < ptr+sizeof(image_header_t); p++) { + for (p = ptr; p < ptr + image_get_header_size (); p++) { if ( *p != 0xff ) { fprintf (stderr, "%s: Bad file: \"%s\" has invalid buffer for XIP\n", @@ -570,7 +527,7 @@ copy_file (int ifd, const char *datafile, int pad) } } - offset = sizeof(image_header_t); + offset = image_get_header_size (); } size = sbuf.st_size - offset; @@ -620,22 +577,23 @@ print_header (image_header_t *hdr) time_t timestamp; uint32_t size; - timestamp = (time_t)ntohl(hdr->ih_time); - size = ntohl(hdr->ih_size); + timestamp = (time_t)image_get_time (hdr); + size = image_get_data_size (hdr); - printf ("Image Name: %.*s\n", IH_NMLEN, hdr->ih_name); + printf ("Image Name: %.*s\n", IH_NMLEN, image_get_name (hdr)); printf ("Created: %s", ctime(×tamp)); printf ("Image Type: "); print_type(hdr); printf ("Data Size: %d Bytes = %.2f kB = %.2f MB\n", size, (double)size / 1.024e3, (double)size / 1.048576e6 ); - printf ("Load Address: 0x%08X\n", ntohl(hdr->ih_load)); - printf ("Entry Point: 0x%08X\n", ntohl(hdr->ih_ep)); + printf ("Load Address: 0x%08X\n", image_get_load (hdr)); + printf ("Entry Point: 0x%08X\n", image_get_ep (hdr)); - if (hdr->ih_type == IH_TYPE_MULTI || hdr->ih_type == IH_TYPE_SCRIPT) { + if (image_check_type (hdr, IH_TYPE_MULTI) || + image_check_type (hdr, IH_TYPE_SCRIPT)) { int i, ptrs; uint32_t pos; uint32_t *len_ptr = (uint32_t *) ( - (unsigned long)hdr + sizeof(image_header_t) + (unsigned long)hdr + image_get_header_size () ); /* determine number of images first (to calculate image offsets) */ @@ -643,14 +601,14 @@ print_header (image_header_t *hdr) ; ptrs = i; /* null pointer terminates list */ - pos = sizeof(image_header_t) + ptrs * sizeof(long); + pos = image_get_header_size () + ptrs * sizeof(long); printf ("Contents:\n"); for (i=0; len_ptr[i]; ++i) { - size = ntohl(len_ptr[i]); + size = image_to_cpu (len_ptr[i]); printf (" Image %d: %8d Bytes = %4d kB = %d MB\n", i, size, size>>10, size>>20); - if (hdr->ih_type == IH_TYPE_SCRIPT && i > 0) { + if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) { /* * the user may need to know offsets * if planning to do something with @@ -671,10 +629,10 @@ static void print_type (image_header_t *hdr) { printf ("%s %s %s (%s)\n", - put_arch (hdr->ih_arch), - put_os (hdr->ih_os ), - put_type (hdr->ih_type), - put_comp (hdr->ih_comp) + put_arch (image_get_arch (hdr)), + put_os (image_get_os (hdr)), + put_type (image_get_type (hdr)), + put_comp (image_get_comp (hdr)) ); } diff --git a/tools/mkimage.h b/tools/mkimage.h new file mode 100644 index 0000000..8b05bb1 --- /dev/null +++ b/tools/mkimage.h @@ -0,0 +1,59 @@ +/* + * (C) Copyright 2000-2004 + * DENX Software Engineering + * Wolfgang Denk, wd@denx.de + * All rights reserved. + * + * 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 +#include +#include +#include +#include +#ifndef __WIN32__ +#include /* for host / network byte order conversions */ +#endif +#include +#include +#include +#include + +#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__) +#include +#endif + +#ifdef __WIN32__ +typedef unsigned int __u32; + +#define SWAP_LONG(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ + (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ + (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ + (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; + +#define ntohl(a) SWAP_LONG(a) +#define htonl(a) SWAP_LONG(a) +#endif /* __WIN32__ */ + +#ifndef O_BINARY /* should be define'd on __WIN32__ */ +#define O_BINARY 0 +#endif -- cgit v0.10.2 From 5d3cc55ecbae277e08f5ff771da20b1d6a36ec36 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:43 +0100 Subject: [new uImage] Move PPC do_bootm_linux() to lib_ppc/ppc_linux.c PPC implementation of do_bootm_linux() routine is moved to a dedicated file lib_ppc/ppc_linux.c Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index be8589d..e61a304 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 #endif -#ifdef CFG_INIT_RAM_LOCK -#include -#endif - -#ifdef CONFIG_LOGBUFFER -#include -#endif - #ifdef CONFIG_HAS_DATAFLASH #include #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..ff2a3e5 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_OF_LIBFDT) +#include +#include +#include +#endif +#if defined(CONFIG_OF_FLAT_TREE) +#include +#endif + +#ifdef CONFIG_LOGBUFFER +#include +#endif + +#ifdef CFG_INIT_RAM_LOCK +#include +#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[]); + +#if defined(CONFIG_CMD_BDI) +extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +#endif + +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); + +#if defined(CONFIG_CMD_BDI) + do_bdinfo (NULL, 0, 0, NULL); +#endif +#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 */ +} -- cgit v0.10.2 From d45d5a18b6b36688f2365623f9d550566c664b5b Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:43 +0100 Subject: [new uImage] Cleanup OF/FDT #if/#elif/#endif use in do_bootm_linux() 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 diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index e61a304..5f1b6b6 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -40,8 +40,7 @@ #include #include #include -#endif -#if defined(CONFIG_OF_FLAT_TREE) +#elif defined(CONFIG_OF_FLAT_TREE) #include #endif diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index ff2a3e5..94872a6 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -37,8 +37,7 @@ #include #include #include -#endif -#if defined(CONFIG_OF_FLAT_TREE) +#elif defined(CONFIG_OF_FLAT_TREE) #include #endif @@ -269,7 +268,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 @@ -313,7 +312,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 - " @@ -364,7 +363,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 - " @@ -375,7 +374,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 @@ -518,8 +517,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, @@ -552,7 +552,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); -- cgit v0.10.2 From 321359f20823e0b8c5ad38b64d007a6c48cda16e Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:43 +0100 Subject: [new uImage] Move gunzip() common code to common/gunzip.c Move gunzip(), zalloc() and zfree() to a separate file. Share zalloc() and zfree() with cramfs uncompress routine. Signed-off-by: Marian Balakowicz diff --git a/common/Makefile b/common/Makefile index d3a4a85..fa5c619 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 5f1b6b6..67f555e 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); @@ -864,95 +865,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 +#include +#include +#include +#include +#include + +#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 ---*/ -- cgit v0.10.2 From 559316faf7eae0614c91d77f509b57d6c4c091ba Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:44 +0100 Subject: [new uImage] Move CHUNKSZ definition to image.h 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 diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 67f555e..fbe81d3 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 #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 c9f4298..aab3f44 100644 --- a/include/image.h +++ b/include/image.h @@ -164,6 +164,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 3759fd2..f865c0c 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 # define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 94872a6..4e7734c 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -49,8 +49,6 @@ #include #endif -#define CHUNKSZ (64 * 1024) - DECLARE_GLOBAL_DATA_PTR; extern image_header_t header; -- cgit v0.10.2 From 261dcf4624b25f3c551efcf8634e9194fabba9c3 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:44 +0100 Subject: [new uImage] Remove I386 uImage fake_header() routine 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 diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index fbe81d3..aa7c0f5 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' @@ -157,22 +153,10 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #endif 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__ */ - { + if (!image_check_magic(hdr)) { 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 67a78c4..6cb021a 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 20f9f8d..c3b4e59 100644 --- a/lib_i386/zimage.c +++ b/lib_i386/zimage.c @@ -212,7 +212,6 @@ void *load_zimage(char *image, unsigned long kernel_size, return setup_base; } - void boot_zimage(void *setup_base) { struct pt_regs regs; @@ -224,51 +223,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; -} -- cgit v0.10.2 From 15158971f49255ccef54f0979a942cfd3de2ae52 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:44 +0100 Subject: [new uImage] Fix uImage header pointer use in i386 do_bootm_linux() Use image header copy instead of a (possibly corrupted) pointer to a initial image location. Signed-off-by: Marian Balakowicz diff --git a/lib_i386/i386_linux.c b/lib_i386/i386_linux.c index 6cb021a..b0cf263 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), + base_ptr = load_zimage ((void*)addr + image_get_header_size (), + image_get_data_size (&header), initrd_start, initrd_end-initrd_start, 0); if (NULL == base_ptr) { -- cgit v0.10.2 From 958fc48abddeab513ea4847e34f22a2e9fe67fe1 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:44 +0100 Subject: [new uImage] Fix FDT header verification in PPC do_boot_linux() routine Signed-off-by: Marian Balakowicz diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 4e7734c..671673f 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -265,9 +265,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) -- cgit v0.10.2 From af13cdbc01eaf88880978bfb4f603e012818ba24 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:11:45 +0100 Subject: [new uImage] Add memmove_wd() common routine Move common, watchdog sensible memmove code to a helper memmmove_wd() routine. Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index aa7c0f5..b059336 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 7a0a3d2..048b866 100644 --- a/common/image.c +++ b/common/image.c @@ -57,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 +90,20 @@ int getenv_verify (void) char *s = getenv ("verify"); 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 aab3f44..9dc0343 100644 --- a/include/image.h +++ b/include/image.h @@ -250,8 +250,11 @@ static inline void image_set_name (image_header_t *hdr, const char *name) int image_check_hcrc (image_header_t *hdr); int image_check_dcrc (image_header_t *hdr); +#ifndef USE_HOSTCC int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize); int getenv_verify (void); +void memmove_wd (void *to, void *from, size_t len, ulong chunksz); +#endif 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 f865c0c..0af2eae 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 671673f..6e2afed 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -426,24 +426,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 { -- cgit v0.10.2 From 1ee1180b6e93e56d0282ac8d943e448e9d0eab20 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:17:10 +0100 Subject: [new uImage] Cleanup cmd_bootm.c - sort and cleanup headers, declarations, etc. - group related routines - cleanup indentation, white spaces Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index b059336..2de1329 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -44,11 +44,6 @@ #include #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 #endif @@ -61,7 +56,12 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #include #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); @@ -77,7 +77,12 @@ extern flash_info_t flash_info[]; /* info for FLASH chips */ 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); +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* * Continue booting an OS image; caller already has: @@ -87,41 +92,38 @@ 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 */ + +/*******************************************************************/ +/* bootm - boot application image from image in memory */ +/*******************************************************************/ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong iflag; @@ -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); @@ -220,7 +221,8 @@ 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); + default: + printf ("Wrong Image Type for %s command\n", cmdtp->name); show_boot_progress (-5); return 1; } @@ -231,7 +233,6 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ - iflag = disable_interrupts(); #ifdef CONFIG_AMIGAONEG3SE @@ -334,6 +335,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) 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); @@ -361,6 +363,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) addr, len_ptr, verify); break; #endif + #ifdef CONFIG_ARTOS case IH_OS_ARTOS: do_bootm_artos (cmdtp, flag, argc, argv, @@ -378,11 +381,11 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } 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,251 +395,59 @@ 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 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 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; + if (parse_string_outer (getenv ("bootcmd"), + 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 rcode = 0; if (argc < 2) { return image_info (load_addr); } - for (arg=1; arg flash_id == FLASH_UNKNOWN) goto next_bank; - for (j=0; jsector_count; ++j) { + for (j = 0; j < info->sector_count; ++j) { hdr = (image_header_t *)info->start[j]; @@ -728,8 +541,10 @@ 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); @@ -737,13 +552,16 @@ print_image_hdr (image_header_t *hdr) #endif 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", 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); + 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" @@ -756,16 +574,14 @@ print_image_hdr (image_header_t *hdr) 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) { + 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; @@ -830,12 +646,134 @@ print_type (image_header_t *hdr) printf ("%s %s %s (%s)", arch, os, type, comp); } -static void -do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) +#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 (*entry_point)(bd_t *); + + 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) +{ + image_header_t *hdr = &header; + void (*entry_point)(bd_t *); entry_point = (void (*)(bd_t *))image_get_ep (hdr); @@ -848,14 +786,14 @@ do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * 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]; @@ -865,9 +803,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]; @@ -880,15 +819,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 16dc968..a5dc887 100644 --- a/common/lynxkdi.c +++ b/common/lynxkdi.c @@ -23,45 +23,45 @@ 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; - memcpy(parms->ethaddr, kbd->bi_enetaddr, 6); - mtspr(SPRN_SPRG2, 0x0020); + memcpy (parms->ethaddr, kbd->bi_enetaddr, 6); + mtspr (SPRN_SPRG2, 0x0020); /* 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(); + lynxkdi (); } #else #error "Lynx KDI support not implemented for configured CPU" -- cgit v0.10.2 From f13e7b2e993c61fed1f607962501e051940d6e80 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 8 Jan 2008 18:12:17 +0100 Subject: [new uImage] Cleanup image header pointer use in bootm code - 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 diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c index 3e68ced..53f8e83 100644 --- a/common/cmd_autoscript.c +++ b/common/cmd_autoscript.c @@ -54,7 +54,7 @@ autoscript (ulong addr) { ulong len; image_header_t *hdr = (image_header_t *)addr; - ulong *len_ptr; + ulong *data; char *cmd; int rcode = 0; int verify; @@ -84,9 +84,9 @@ autoscript (ulong addr) } /* get length of script */ - len_ptr = (ulong *)image_get_data (hdr); + data = (ulong *)image_get_data (hdr); - if ((len = image_to_cpu (*len_ptr)) == 0) { + if ((len = image_to_cpu (*data)) == 0) { puts ("Empty Script\n"); return 1; } @@ -97,10 +97,10 @@ autoscript (ulong addr) return 1; } - while (*len_ptr++); + while (*data++); /* make sure cmd is null terminated */ - memmove (cmd, (char *)len_ptr, len); + memmove (cmd, (char *)data, len); *(cmd + len) = 0; #ifdef CFG_HUSH_PARSER /*?? */ diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 2de1329..2d17bdd 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -93,14 +93,13 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); * - disabled interrupts. */ 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' */ + int argc, char *argv[], + image_header_t *hdr, /* of image to boot */ + int verify); /* getenv("verify")[0] != 'n' */ extern boot_os_fn do_bootm_linux; static boot_os_fn do_bootm_netbsd; -#ifdef CONFIG_LYNXKDI +#if defined(CONFIG_LYNXKDI) static boot_os_fn do_bootm_lynxkdi; extern void lynxkdi_boot (image_header_t *); #endif @@ -116,8 +115,6 @@ 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 */ @@ -126,34 +123,32 @@ ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ /*******************************************************************/ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - ulong iflag; - ulong addr; - ulong data, len; - ulong *len_ptr; - uint unc_len = CFG_BOOTM_LEN; - int i, verify; - char *name, *s; - int (*appl)(int, char *[]); - image_header_t *hdr = &header; + ulong iflag; + char *name, *s; + int (*appl)(int, char *[]); + uint unc_len = CFG_BOOTM_LEN; + int verify = getenv_verify(); - verify = getenv_verify (); + image_header_t *hdr; + ulong img_addr; + ulong os_data, os_len; if (argc < 2) { - addr = load_addr; + img_addr = load_addr; } else { - addr = simple_strtoul(argv[1], NULL, 16); + img_addr = simple_strtoul(argv[1], NULL, 16); } show_boot_progress (1); - printf ("## Booting image at %08lx ...\n", addr); + printf ("## Booting image at %08lx ...\n", img_addr); - /* Copy header so we can blank CRC field for re-calculation */ #ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash(addr)){ - read_dataflash (addr, image_get_header_size (), (char *)&header); + if (addr_dataflash (img_addr)){ + hdr = (image_header_t *)CFG_LOAD_ADDR; + read_dataflash (img_addr, image_get_header_size (), (char *)hdr); } else #endif - memmove (&header, (char *)addr, image_get_header_size ()); + hdr = (image_header_t *)img_addr; if (!image_check_magic(hdr)) { puts ("Bad Magic Number\n"); @@ -170,23 +165,18 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress (3); #ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash(addr)){ - len = image_get_image_size (hdr); - read_dataflash(addr, len, (char *)CFG_LOAD_ADDR); - addr = CFG_LOAD_ADDR; - } + if (addr_dataflash (img_addr)) + read_dataflash (img_addr + image_get_header_size (), + image_get_data_size (hdr), + (char *)image_get_data (hdr)); #endif - /* for multi-file images we need the data part, too */ - print_image_hdr ((image_header_t *)addr); - - len = image_get_data_size (hdr); - data = addr + image_get_header_size (); - len_ptr = (ulong *)data; + /* uImage is in a system RAM, pointed to by hdr */ + print_image_hdr (hdr); if (verify) { puts (" Verifying Checksum ... "); - if (!image_check_dcrc ((image_header_t *)addr)) { + if (!image_check_dcrc (hdr)) { printf ("Bad Data CRC\n"); show_boot_progress (-3); return 1; @@ -212,14 +202,12 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; case IH_TYPE_KERNEL: name = "Kernel Image"; + os_data = image_get_data (hdr); + os_len = image_get_data_size (hdr); break; case IH_TYPE_MULTI: name = "Multi-File Image"; - len = image_to_cpu (len_ptr[0]); - /* OS kernel is always the first image */ - data += 8; /* kernel_len + terminator */ - for (i=1; len_ptr[i]; ++i) - data += 4; + image_multi_getimg (hdr, 0, &os_data, &os_len); break; default: printf ("Wrong Image Type for %s command\n", cmdtp->name); @@ -248,13 +236,13 @@ 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) { + if (image_get_load (hdr) == img_addr) { printf (" XIP %s ... ", name); } else { printf (" Loading %s ... ", name); memmove_wd ((void *)image_get_load (hdr), - (void *)data, len, CHUNKSZ); + (void *)os_data, os_len, CHUNKSZ); puts("OK\n"); } @@ -262,7 +250,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) case IH_COMP_GZIP: printf (" Uncompressing %s ... ", name); if (gunzip ((void *)image_get_load (hdr), unc_len, - (uchar *)data, &len) != 0) { + (uchar *)os_data, &os_len) != 0) { puts ("GUNZIP ERROR - must RESET board to recover\n"); show_boot_progress (-6); do_reset (cmdtp, flag, argc, argv); @@ -276,9 +264,9 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * use slower decompression algorithm which requires * at most 2300 KB of memory. */ - i = BZ2_bzBuffToBuffDecompress ((char*)image_get_load (hdr), - &unc_len, (char *)data, len, - CFG_MALLOC_LEN < (4096 * 1024), 0); + int i = BZ2_bzBuffToBuffDecompress ((char*)image_get_load (hdr), + &unc_len, (char *)os_data, os_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); @@ -306,7 +294,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ if (((s = getenv("autostart")) != NULL) && (strcmp(s,"no") == 0)) { char buf[32]; - sprintf(buf, "%lX", len); + sprintf(buf, "%lX", image_get_data_size(hdr)); setenv("filesize", buf); return 0; } @@ -332,42 +320,36 @@ 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, hdr, verify); break; case IH_OS_NETBSD: - do_bootm_netbsd (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_netbsd (cmdtp, flag, argc, argv, hdr, 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, hdr, 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, hdr, 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, hdr, verify); break; + case IH_OS_QNX: - do_bootm_qnxelf (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_qnxelf (cmdtp, flag, argc, argv, hdr, 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, hdr, verify); break; #endif } @@ -570,11 +552,12 @@ void print_image_hdr (image_header_t *hdr) if (image_check_type (hdr, IH_TYPE_MULTI)) { int i; - ulong len; - ulong *len_ptr = (ulong *)((ulong)hdr + image_get_header_size ()); + ulong data, len; + ulong count = image_multi_count (hdr); puts (" Contents:\n"); - for (i = 0; (len = image_to_cpu (*len_ptr)); ++i, ++len_ptr) { + for (i = 0; i < count; i++) { + image_multi_getimg (hdr, i, &data, &len); printf (" Image %d: %8ld Bytes = ", i, len); print_size (len, "\n"); } @@ -684,14 +667,12 @@ static void fixup_silent_linux () /*******************************************************************/ static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, ulong *len_ptr, - int verify) + int argc, char *argv[], + image_header_t *hdr, int verify) { - image_header_t *hdr = &header; - void (*loader)(bd_t *, image_header_t *, char *, char *); image_header_t *img_addr; + ulong kernel_data, kernel_len; char *consdev; char *cmdline; @@ -708,8 +689,11 @@ static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, */ img_addr = 0; - if ((image_check_type (hdr, IH_TYPE_MULTI)) && (len_ptr[1])) - img_addr = (image_header_t *)addr; + if (image_check_type (hdr, IH_TYPE_MULTI)) { + image_multi_getimg (hdr, 1, &kernel_data, &kernel_len); + if (kernel_len) + img_addr = hdr; + } consdev = ""; #if defined (CONFIG_8xx_CONS_SMC1) @@ -760,19 +744,16 @@ static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, #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) + image_header_t *hdr, int verify) { - lynxkdi_boot (&header); + lynxkdi_boot (hdr); } #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) + image_header_t *hdr, int verify) { - image_header_t *hdr = &header; void (*entry_point)(bd_t *); entry_point = (void (*)(bd_t *))image_get_ep (hdr); @@ -792,10 +773,8 @@ static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, #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) + image_header_t *hdr, int verify) { - image_header_t *hdr = &header; char str[80]; sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */ @@ -803,12 +782,10 @@ static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, 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[], + image_header_t *hdr, int verify) { - image_header_t *hdr = &header; char *local_args[2]; char str[16]; @@ -822,8 +799,7 @@ static void do_bootm_qnxelf (cmd_tbl_t *cmdtp, int flag, #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) + image_header_t *hdr, int verify) { ulong top; char *s, *cmdline; @@ -831,7 +807,6 @@ static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag, int i, j, nxt, len, envno, envsz; bd_t *kbd; void (*entry)(bd_t *bd, char *cmdline, char **fwenv, ulong top); - image_header_t *hdr = &header; /* * Booting an ARTOS kernel image + application diff --git a/common/image.c b/common/image.c index 048b866..6eee83d 100644 --- a/common/image.c +++ b/common/image.c @@ -107,3 +107,89 @@ void memmove_wd (void *to, void *from, size_t len, ulong chunksz) #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ } #endif /* USE_HOSTCC */ + +/** + * image_multi_count - get component (sub-image) count + * @hdr: pointer to the header of the multi component image + * + * image_multi_count() returns number of components in a multi + * component image. + * + * Note: no checking of the image type is done, caller must pass + * a valid multi component image. + * + * returns: + * number of components + */ +ulong image_multi_count (image_header_t *hdr) +{ + ulong i, count = 0; + ulong *size; + + /* get start of the image payload, which in case of multi + * component images that points to a table of component sizes */ + size = (ulong *)image_get_data (hdr); + + /* count non empty slots */ + for (i = 0; size[i]; ++i) + count++; + + return count; +} + +/** + * image_multi_getimg - get component data address and size + * @hdr: pointer to the header of the multi component image + * @idx: index of the requested component + * @data: pointer to a ulong variable, will hold component data address + * @len: pointer to a ulong variable, will hold component size + * + * image_multi_getimg() returns size and data address for the requested + * component in a multi component image. + * + * Note: no checking of the image type is done, caller must pass + * a valid multi component image. + * + * returns: + * data address and size of the component, if idx is valid + * 0 in data and len, if idx is out of range + */ +void image_multi_getimg (image_header_t *hdr, ulong idx, + ulong *data, ulong *len) +{ + int i; + ulong *size; + ulong offset, tail, count, img_data; + + /* get number of component */ + count = image_multi_count (hdr); + + /* get start of the image payload, which in case of multi + * component images that points to a table of component sizes */ + size = (ulong *)image_get_data (hdr); + + /* get address of the proper component data start, which means + * skipping sizes table (add 1 for last, null entry) */ + img_data = image_get_data (hdr) + (count + 1) * sizeof (ulong); + + if (idx < count) { + *len = size[idx]; + offset = 0; + tail = 0; + + /* go over all indices preceding requested component idx */ + for (i = 0; i < idx; i++) { + /* add up i-th component size */ + offset += size[i]; + + /* add up alignment for i-th component */ + tail += (4 - size[i] % 4); + } + + /* calculate idx-th component data address */ + *data = img_data + offset + tail; + } else { + *len = 0; + *data = 0; + } +} diff --git a/include/image.h b/include/image.h index 9dc0343..c605d66 100644 --- a/include/image.h +++ b/include/image.h @@ -211,13 +211,30 @@ static inline uint32_t image_get_data_size (image_header_t *hdr) { return image_get_size (hdr); } + +/** + * image_get_data - get image payload start address + * @hdr: image header + * + * image_get_data() returns address of the image payload. For single + * component images it is image data start. For multi component + * images it points to the null terminated table of sub-images sizes. + * + * returns: + * image payload data start address + */ +static inline ulong image_get_data (image_header_t *hdr) +{ + return ((ulong)hdr + image_get_header_size ()); +} + static inline uint32_t image_get_image_size (image_header_t *hdr) { return (image_get_size (hdr) + image_get_header_size ()); } -static inline ulong image_get_data (image_header_t *hdr) +static inline ulong image_get_image_end (image_header_t *hdr) { - return ((ulong)hdr + image_get_header_size ()); + return ((ulong)hdr + image_get_image_size (hdr)); } #define image_set_hdr_l(f) \ @@ -307,4 +324,8 @@ static inline int image_check_target_arch (image_header_t *hdr) } #endif -#endif /* __IMAGE_H__ */ +ulong image_multi_count (image_header_t *hdr); +void image_multi_getimg (image_header_t *hdr, ulong idx, + ulong *data, ulong *len); + +#endif /* __IMAGE_H__ */ diff --git a/lib_arm/armlinux.c b/lib_arm/armlinux.c index 09038cc..4f9aae6 100644 --- a/lib_arm/armlinux.c +++ b/lib_arm/armlinux.c @@ -66,17 +66,14 @@ static void setup_videolfb_tag (gd_t *gd); static struct tag *params; #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ -extern image_header_t header; /* from cmd_bootm.c */ - - void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) + image_header_t *hdr, int verify) { - ulong len = 0; + ulong rd_addr; + ulong rd_data, rd_len = 0; ulong initrd_start, initrd_end; - ulong data; + image_header_t *rd_hdr; void (*theKernel)(int zero, int arch, uint params); - image_header_t *hdr = &header; bd_t *bd = gd->bd; #ifdef CONFIG_CMDLINE_TAG @@ -91,27 +88,26 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (argc >= 3) { show_boot_progress (9); - addr = simple_strtoul (argv[2], NULL, 16); - - printf ("## Loading Ramdisk Image at %08lx ...\n", addr); + rd_addr = simple_strtoul (argv[2], NULL, 16); + printf ("## Loading Ramdisk Image at %08lx ...\n", rd_addr); /* Copy header so we can blank CRC field for re-calculation */ #ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (addr)) { - read_dataflash (addr, image_get_header_size (), - (char *) &header); + if (addr_dataflash (rd_addr)) { + rd_hdr = (image_header_t *)CFG_LOAD_ADDR; + read_dataflash (rd_addr, image_get_header_size (), + (char *)rd_hdr); } else #endif - memcpy (&header, (char *) addr, - image_get_header_size ()); + rd_hdr = (image_header_t *)rd_addr; - if (!image_check_magic (hdr)) { + if (!image_check_magic (rd_hdr)) { printf ("Bad Magic Number\n"); show_boot_progress (-10); do_reset (cmdtp, flag, argc, argv); } - if (!image_check_hcrc (hdr)) { + if (!image_check_hcrc (rd_hdr)) { printf ("Bad Header Checksum\n"); show_boot_progress (-11); do_reset (cmdtp, flag, argc, argv); @@ -119,21 +115,20 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], show_boot_progress (10); - print_image_hdr (hdr); + print_image_hdr (rd_hdr); - data = image_get_data (hdr); - len = image_get_data_size (hdr); + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); #ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (addr)) { - read_dataflash (data, len, (char *) CFG_LOAD_ADDR); - data = CFG_LOAD_ADDR; - } + if (addr_dataflash (rd_addr)) + read_dataflash (rd_addr + image_get_header_size (), + rd_len, (char *)rd_data); #endif if (verify) { printf (" Verifying Checksum ... "); - if (!image_get_dcrc (hdr)) { + if (!image_get_dcrc (rd_hdr)) { printf ("Bad Data CRC\n"); show_boot_progress (-12); do_reset (cmdtp, flag, argc, argv); @@ -143,9 +138,9 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], show_boot_progress (11); - if (!image_check_os (hdr, IH_OS_LINUX) || - !image_check_arch (hdr, IH_ARCH_ARM) || - !image_check_type (hdr, IH_TYPE_RAMDISK)) { + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_ARM) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { printf ("No Linux ARM Ramdisk Image\n"); show_boot_progress (-13); do_reset (cmdtp, flag, argc, argv); @@ -155,50 +150,37 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* *we need to copy the ramdisk to SRAM to let Linux boot */ - memmove ((void *)image_get_load (hdr), (uchar *)data, len); - data = image_get_load (hdr); + memmove ((void *)image_get_load (rd_hdr), (uchar *)rd_data, rd_len); + rd_data = image_get_load (rd_hdr); #endif /* CONFIG_B2 || CONFIG_EVB4510 */ /* * Now check if we have a multifile image */ - } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = image_to_cpu (len_ptr[0]) % 4; - int i; - + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ 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]); - + image_multi_getimg (hdr, 1, &rd_data, &rd_len); } else { /* * no initrd image */ show_boot_progress (14); - len = data = 0; + rd_len = rd_data = 0; } #ifdef DEBUG - if (!data) { + if (!rd_data) { printf ("No initrd\n"); } #endif - if (data) { - initrd_start = data; - initrd_end = initrd_start + len; + if (rd_data) { + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; } else { initrd_start = 0; initrd_end = 0; diff --git a/lib_avr32/avr32_linux.c b/lib_avr32/avr32_linux.c index 44827ec..455590e 100644 --- a/lib_avr32/avr32_linux.c +++ b/lib_avr32/avr32_linux.c @@ -174,20 +174,16 @@ static void setup_end_tag(struct tag *params) } void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - unsigned long addr, unsigned long *len_ptr, int verify) + image_header_t *hdr, int verify) { - unsigned long data, len = 0; - unsigned long initrd_start, initrd_end; - unsigned long image_start, image_end; + ulong rd_data, rd_len = 0; + ulong initrd_start, initrd_end; + image_header_t *rd_hdr; + void (*theKernel)(int magic, void *tagtable); - image_header_t *hdr; struct tag *params, *params_start; char *commandline = getenv("bootargs"); - hdr = (image_header_t *)addr; - image_start = addr; - image_end = addr + image_get_data_size (hdr); - theKernel = (void *)image_get_ep (hdr); /* @@ -196,29 +192,27 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (argc >= 3) { show_boot_progress (9); - addr = simple_strtoul(argv[2], NULL, 16); - hdr = (image_header_t *)addr; + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading RAMDISK image at %08lx ...\n", rd_hdr); - printf("## Loading RAMDISK image at %08lx ...\n", addr); - - if (!image_check_magic (hdr)) { + if (!image_check_magic (rd_hdr)) { puts("Bad Magic Number\n"); show_boot_progress (-10); do_reset(cmdtp, flag, argc, argv); } - if (!image_check_hcrc (hdr)) { + if (!image_check_hcrc (rd_hdr)) { puts("Bad Header Checksum\n"); show_boot_progress (-11); do_reset(cmdtp, flag, argc, argv); } show_boot_progress (10); - print_image_hdr (hdr); + print_image_hdr (rd_hdr); if (verify) { puts(" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { + if (!image_check_dcrc (rd_hdr)) { puts("Bad Data CRC\n"); show_boot_progress (-12); do_reset(cmdtp, flag, argc, argv); @@ -228,44 +222,32 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], show_boot_progress (11); - if (!image_check_os (hdr, IH_OS_LINUX) || - !image_check_arch (hdr, IH_ARCH_AVR32) || - !image_check_type (hdr, IH_TYPE_RAMDISK)) { + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_AVR32) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { puts("Not a Linux/AVR32 RAMDISK image\n"); show_boot_progress (-13); do_reset(cmdtp, flag, argc, argv); } - data = image_get_data (hdr); - len = image_get_data_size (hdr); - - } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = image_to_cpu (len_ptr[0]) % 4; - int i; + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ 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]); + image_multi_getimg (hdr, 1, &rd_data, &rd_len); } else { /* no initrd image */ show_boot_progress (14); - len = data = 0; + rd_len = rd_data = 0; } - if (data) { - initrd_start = data; - initrd_end = initrd_start + len; + if (rd_data) { + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; } else { initrd_start = 0; initrd_end = 0; diff --git a/lib_blackfin/bf533_linux.c b/lib_blackfin/bf533_linux.c index 26c6534..6299415 100644 --- a/lib_blackfin/bf533_linux.c +++ b/lib_blackfin/bf533_linux.c @@ -42,17 +42,15 @@ extern void swap_to(int device_id); #endif -extern image_header_t header; extern void flush_instruction_cache(void); extern void flush_data_cache(void); static char *make_command_line(void); void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong * len_ptr, int verify) + image_header_t *hdr, int verify) { int (*appl) (char *cmdline); char *cmdline; - image_header_t *hdr = &header; #ifdef SHARED_RESOURCES swap_to(FLASH); diff --git a/lib_i386/i386_linux.c b/lib_i386/i386_linux.c index b0cf263..27a2b0d 100644 --- a/lib_i386/i386_linux.c +++ b/lib_i386/i386_linux.c @@ -31,54 +31,50 @@ /*cmd_boot.c*/ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); -extern image_header_t header; /* from cmd_bootm.c */ - void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) + image_header_t *hdr, int verify) { void *base_ptr; - ulong len = 0; + ulong os_data, os_len; + ulong rd_data, rd_len; ulong initrd_start, initrd_end; - ulong data; - image_header_t *hdr = &header; + image_header_t *rd_hdr; /* * Check if there is an initrd image */ if (argc >= 3) { - addr = simple_strtoul(argv[2], NULL, 16); - hdr = (image_header_t *)addr; - - printf ("## Loading Ramdisk Image at %08lx ...\n", addr); + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr); - if (!image_check_magic (hdr)) { + if (!image_check_magic (rd_hdr)) { printf ("Bad Magic Number\n"); do_reset (cmdtp, flag, argc, argv); } - if (!image_check_hcrc (hdr)) { + if (!image_check_hcrc (rd_hdr)) { printf ("Bad Header Checksum\n"); do_reset (cmdtp, flag, argc, argv); } - print_image_hdr (hdr); + print_image_hdr (rd_hdr); - data = image_get_data (hdr); - len = image_get_data_size (hdr); + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); if (verify) { printf (" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { + if (!image_check_dcrc (rd_hdr)) { printf ("Bad Data CRC\n"); do_reset (cmdtp, flag, argc, argv); } printf ("OK\n"); } - if (!image_check_os (hdr, IH_OS_LINUX) || - !image_check_arch (hdr, IH_ARCH_I386) || - !image_check_type (hdr, IH_TYPE_RAMDISK)) { + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_I386) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { printf ("No Linux i386 Ramdisk Image\n"); do_reset (cmdtp, flag, argc, argv); } @@ -86,42 +82,30 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* * Now check if we have a multifile image */ - } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = image_to_cpu (len_ptr[0]) % 4; - int i; - - /* 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 if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ + image_multi_getimg (hdr, 1, &rd_data, &rd_len); } else { /* * no initrd image */ - data = 0; + rd_data = rd_len = 0; } #ifdef DEBUG - if (!data) { + if (!rd_data) { printf ("No initrd\n"); } #endif - if (data) { - initrd_start = data; - initrd_end = initrd_start + len; + if (rd_data) { + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; printf (" Loading Ramdisk to %08lx, end %08lx ... ", initrd_start, initrd_end); - memmove ((void *)initrd_start, (void *)data, len); + memmove ((void *)initrd_start, (void *)rd_data, rd_len); printf ("OK\n"); } else { initrd_start = 0; @@ -129,14 +113,15 @@ 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 (&header, IH_TYPE_MULTI) && (len_ptr[1])) { - int i; - for (i=0, addr+=sizeof(int); len_ptr[i++]; addr+=sizeof(int)); + if (image_check_type (hdr, IH_TYPE_MULTI)) { + image_multi_getimg (hdr, 0, &os_data, &os_len); + } else { + os_data = image_get_data (hdr); + os_len = image_get_data_size (hdr); } - base_ptr = load_zimage ((void*)addr + image_get_header_size (), - image_get_data_size (&header), - initrd_start, initrd_end-initrd_start, 0); + base_ptr = load_zimage ((void*)os_data, os_len, + initrd_start, rd_len, 0); if (NULL == base_ptr) { printf ("## Kernel loading failed ...\n"); diff --git a/lib_m68k/m68k_linux.c b/lib_m68k/m68k_linux.c index 0af2eae..b135556 100644 --- a/lib_m68k/m68k_linux.c +++ b/lib_m68k/m68k_linux.c @@ -44,26 +44,25 @@ DECLARE_GLOBAL_DATA_PTR; # define SHOW_BOOT_PROGRESS(arg) #endif -extern image_header_t header; - int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong * len_ptr, int verify) + image_header_t *hdr, int verify) { ulong sp; - ulong len; - ulong initrd_start, initrd_end; - ulong cmd_start, cmd_end; + + ulong rd_data, rd_len; ulong initrd_high; - ulong data; + ulong initrd_start, initrd_end; + image_header_t *rd_hdr; int initrd_copy_to_ram = 1; + + ulong cmd_start, cmd_end; char *cmdline; char *s; bd_t *kbd; void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); - image_header_t *hdr = &header; if ((s = getenv("initrd_high")) != NULL) { /* a value of "no" or a similar string will act like 0, @@ -141,18 +140,16 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, debug("Not skipping initrd\n"); SHOW_BOOT_PROGRESS(9); - addr = simple_strtoul(argv[2], NULL, 16); - hdr = (image_header_t *)addr; + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading RAMDisk Image at %08lx ...\n", rd_hdr); - printf("## Loading RAMDisk Image at %08lx ...\n", addr); - - if (!image_check_magic (hdr)) { + if (!image_check_magic (rd_hdr)) { puts("Bad Magic Number\n"); SHOW_BOOT_PROGRESS(-10); do_reset(cmdtp, flag, argc, argv); } - if (!image_check_hcrc (hdr)) { + if (!image_check_hcrc (rd_hdr)) { puts("Bad Header Checksum\n"); SHOW_BOOT_PROGRESS(-11); do_reset(cmdtp, flag, argc, argv); @@ -160,14 +157,14 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, SHOW_BOOT_PROGRESS(10); - print_image_hdr (hdr); + print_image_hdr (rd_hdr); - data = image_get_data (hdr); - len = image_get_data_size (hdr); + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); if (verify) { puts(" Verifying Checksum ... "); - if (!image_check_dcrc_wd (hdr, CHUNKSZ)) { + if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) { puts("Bad Data CRC\n"); SHOW_BOOT_PROGRESS(-12); do_reset(cmdtp, flag, argc, argv); @@ -177,9 +174,9 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, SHOW_BOOT_PROGRESS(11); - if (!image_check_os (hdr, IH_OS_LINUX) || - !image_check_arch (hdr, IH_ARCH_M68K) || - !image_check_type (hdr, IH_TYPE_RAMDISK)) { + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_M68K) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { puts("No Linux ColdFire Ramdisk Image\n"); SHOW_BOOT_PROGRESS(-13); do_reset(cmdtp, flag, argc, argv); @@ -188,44 +185,31 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, /* * 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 if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ + SHOW_BOOT_PROGRESS (13); + image_multi_getimg (hdr, 1, &rd_data, &rd_len); } else { /* * no initrd image */ SHOW_BOOT_PROGRESS(14); - len = data = 0; + rd_len = rd_data = 0; } - if (!data) { + if (!rd_data) { debug("No initrd\n"); } - if (data) { + if (rd_data) { if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = data; - initrd_end = initrd_start + len; + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; } else { - initrd_start = (ulong) kbd - len; + initrd_start = (ulong) kbd - rd_len; initrd_start &= ~(4096 - 1); /* align on page */ if (initrd_high) { @@ -250,7 +234,7 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, if (nsp > initrd_high) /* limit as specified */ nsp = initrd_high; - nsp -= len; + nsp -= rd_len; nsp &= ~(4096 - 1); /* align on page */ if (nsp >= sp) @@ -261,14 +245,14 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - data, data + len - 1, len, len); + rd_data, rd_data + rd_len - 1, rd_len, rd_len); - initrd_end = initrd_start + len; + initrd_end = initrd_start + rd_len; printf(" Loading Ramdisk to %08lx, end %08lx ... ", initrd_start, initrd_end); memmove_wd((void *)initrd_start, - (void *)data, len, CHUNKSZ); + (void *)rd_data, rd_len, CHUNKSZ); puts("OK\n"); } diff --git a/lib_microblaze/microblaze_linux.c b/lib_microblaze/microblaze_linux.c index 7cd9799..a4fce5a 100644 --- a/lib_microblaze/microblaze_linux.c +++ b/lib_microblaze/microblaze_linux.c @@ -32,21 +32,21 @@ DECLARE_GLOBAL_DATA_PTR; -extern image_header_t header; /* from cmd_bootm.c */ -/*cmd_boot.c*/ extern int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong * len_ptr, int verify) + image_header_t *hdr, int verify) { - ulong len = 0, checksum; + int i; + ulong checksum; + + ulong rd_data, rd_len; ulong initrd_start, initrd_end; - ulong data; + image_header_t *rd_hdr; + /* First parameter is mapped to $r5 for kernel boot args */ void (*theKernel) (char *); - image_header_t *hdr = &header; char *commandline = getenv ("bootargs"); - int i; theKernel = (void (*)(char *))image_get_ep (hdr); @@ -54,33 +54,30 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], if (argc >= 3) { show_boot_progress (9); - addr = simple_strtoul (argv[2], NULL, 16); - hdr = (image_header_t *)addr; + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr); - printf ("## Loading Ramdisk Image at %08lx ...\n", addr); - - if (!image_check_magic (hdr)) { + if (!image_check_magic (rd_hdr)) { printf ("Bad Magic Number\n"); show_boot_progress (-10); do_reset (cmdtp, flag, argc, argv); } - if (!image_check_magic (hdr)) { + if (!image_check_magic (rd_hdr)) { printf ("Bad Header Checksum\n"); show_boot_progress (-11); do_reset (cmdtp, flag, argc, argv); } show_boot_progress (10); + print_image_hdr (rd_hdr); - print_image_hdr (hdr); - - data = image_get_data (hdr); - len = image_get_data_size (hdr); + rd_data = image_get_data (rd_hdr); + rd_en = image_get_data_size (rd_hdr); if (verify) { printf (" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { + if (!image_check_dcrc (rd_hdr)) { printf ("Bad Data CRC\n"); show_boot_progress (-12); do_reset (cmdtp, flag, argc, argv); @@ -90,9 +87,9 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], show_boot_progress (11); - if (!image_check_os (hdr, IH_OS_LINUX) || - !image_check_arch (hdr, IH_ARCH_MICROBLAZE) || - !image_check_type (hdr, IH_TYPE_RAMDISK)) { + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_MICROBLAZE) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { printf ("No Linux Microblaze Ramdisk Image\n"); show_boot_progress (-13); do_reset (cmdtp, flag, argc, argv); @@ -101,42 +98,30 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], /* * Now check if we have a multifile image */ - } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = image_to_cpu (len_ptr[0]) % 4; - + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ 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]); - + image_multi_getimg (hdr, 1, &rd_data, &rd_len); } else { /* * no initrd image */ show_boot_progress (14); - data = 0; + rd_data = rd_len = 0; } #ifdef DEBUG - if (!data) { + if (!rd_data) { printf ("No initrd\n"); } #endif - if (data) { - initrd_start = data; - initrd_end = initrd_start + len; + if (rd_data) { + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; } else { initrd_start = 0; initrd_end = 0; diff --git a/lib_mips/mips_linux.c b/lib_mips/mips_linux.c index 0881b6d..7ea7571 100644 --- a/lib_mips/mips_linux.c +++ b/lib_mips/mips_linux.c @@ -33,8 +33,6 @@ DECLARE_GLOBAL_DATA_PTR; #define LINUX_MAX_ENVS 256 #define LINUX_MAX_ARGS 256 -extern image_header_t header; /* from cmd_bootm.c */ - extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); static int linux_argc; @@ -49,13 +47,13 @@ static void linux_env_set (char * env_name, char * env_val); void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong * len_ptr, int verify) + image_header_t *hdr, int verify) { - ulong len = 0; + ulong rd_data, rd_len; ulong initrd_start, initrd_end; - ulong data; + image_header_t *rd_hdr; + void (*theKernel) (int, char **, char **, int *); - image_header_t *hdr = &header; char *commandline = getenv ("bootargs"); char env_buf[12]; @@ -68,33 +66,30 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], if (argc >= 3) { show_boot_progress (9); - addr = simple_strtoul (argv[2], NULL, 16); - hdr = (image_header_t *)addr; - - printf ("## Loading Ramdisk Image at %08lx ...\n", addr); + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr); - if (!image_check_magic (hdr)) { + if (!image_check_magic (rd_hdr)) { printf ("Bad Magic Number\n"); show_boot_progress (-10); do_reset (cmdtp, flag, argc, argv); } - if (!image_check_hcrc (hdr)) { + if (!image_check_hcrc (rd_hdr)) { printf ("Bad Header Checksum\n"); show_boot_progress (-11); do_reset (cmdtp, flag, argc, argv); } show_boot_progress (10); + print_image_hdr (rd_hdr); - print_image_hdr (hdr); - - data = image_get_data (hdr); - len = image_get_data_size (hdr); + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); if (verify) { printf (" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { + if (!image_check_dcrc (rd_hdr)) { printf ("Bad Data CRC\n"); show_boot_progress (-12); do_reset (cmdtp, flag, argc, argv); @@ -104,9 +99,9 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], show_boot_progress (11); - if (!image_check_os (hdr, IH_OS_LINUX) || - !image_check_arch (hdr, IH_ARCH_MIPS) || - !image_check_type (hdr, IH_TYPE_RAMDISK)) { + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_MIPS) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { printf ("No Linux MIPS Ramdisk Image\n"); show_boot_progress (-13); do_reset (cmdtp, flag, argc, argv); @@ -115,43 +110,30 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], /* * Now check if we have a multifile image */ - } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = image_to_cpu (len_ptr[0]) % 4; - int i; - + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ 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]); - + image_multi_getimg (hdr, 1, &rd_data, &rd_len); } else { /* * no initrd image */ show_boot_progress (14); - data = 0; + rd_data = rd_len = 0; } #ifdef DEBUG - if (!data) { + if (!rd_data) { printf ("No initrd\n"); } #endif - if (data) { - initrd_start = data; - initrd_end = initrd_start + len; + if (rd_data) { + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; } else { initrd_start = 0; initrd_end = 0; diff --git a/lib_nios/nios_linux.c b/lib_nios/nios_linux.c index eef1757..55f7e3a 100644 --- a/lib_nios/nios_linux.c +++ b/lib_nios/nios_linux.c @@ -29,6 +29,6 @@ * */ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) + image__header_t *hdr, int verify) { } diff --git a/lib_nios2/nios_linux.c b/lib_nios2/nios_linux.c index dea1ec1..cb84324 100644 --- a/lib_nios2/nios_linux.c +++ b/lib_nios2/nios_linux.c @@ -25,12 +25,9 @@ #include #include -extern image_header_t header; /* common/cmd_bootm.c */ - void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) + image_header_t *hdr, int verify) { - image_header_t *hdr = &header; void (*kernel)(void) = (void (*)(void))image_get_ep (hdr); /* For now we assume the Microtronix linux ... which only diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c index 6e2afed..0a625fc 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -50,9 +50,7 @@ #endif 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[]); #if defined(CONFIG_CMD_BDI) @@ -60,25 +58,27 @@ extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #endif void __attribute__((noinline)) -do_bootm_linux (cmd_tbl_t *cmdtp, int flag, +do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, - ulong *len_ptr, + image_header_t *hdr, 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; + ulong initrd_start, initrd_end; + ulong rd_data, rd_len; + image_header_t *rd_hdr; + + ulong cmd_start, cmd_end; char *cmdline; + + ulong sp; 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) + image_header_t *fdt_hdr; char *of_flat_tree = NULL; ulong of_data = 0; #endif @@ -177,7 +177,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, /* Look for a '-' which indicates to ignore the ramdisk argument */ if (argc >= 3 && strcmp(argv[2], "-") == 0) { debug ("Skipping initrd\n"); - len = data = 0; + rd_len = rd_data = 0; } else #endif @@ -185,30 +185,28 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, debug ("Not skipping initrd\n"); show_boot_progress (9); - addr = simple_strtoul(argv[2], NULL, 16); + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading RAMDisk Image at %08lx ...\n", (ulong)rd_hdr); - printf ("## Loading RAMDisk Image at %08lx ...\n", addr); - hdr = (image_header_t *)addr; - - if (!image_check_magic (hdr)) { + if (!image_check_magic (rd_hdr)) { puts ("Bad Magic Number\n"); show_boot_progress (-10); do_reset (cmdtp, flag, argc, argv); } - if (!image_check_hcrc (hdr)) { + if (!image_check_hcrc (rd_hdr)) { puts ("Bad Header Checksum\n"); show_boot_progress (-11); do_reset (cmdtp, flag, argc, argv); } show_boot_progress (10); - print_image_hdr (hdr); + print_image_hdr (rd_hdr); if (verify) { puts (" Verifying Checksum ... "); - if (!image_check_dcrc_wd (hdr, CHUNKSZ)) { + if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) { puts ("Bad Data CRC\n"); show_boot_progress (-12); do_reset (cmdtp, flag, argc, argv); @@ -218,52 +216,39 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, 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)) { + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_PPC) || + !image_check_type (rd_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); + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_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; - + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ + image_multi_getimg (hdr, 1, &rd_data, &rd_len); 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 + * No initrd image */ show_boot_progress (14); - len = data = 0; + rd_len = rd_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; + fdt_hdr = (image_header_t *)of_flat_tree; #if defined(CONFIG_OF_FLAT_TREE) if (*((ulong *)(of_flat_tree)) == OF_DT_HEADER) { #elif defined(CONFIG_OF_LIBFDT) @@ -273,37 +258,37 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, 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); + } else if (image_check_magic (fdt_hdr)) { + printf ("## Flat Device Tree at %08lX\n", fdt_hdr); + print_image_hdr (fdt_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)) { + 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)) { 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)) { + if (!image_check_hcrc (fdt_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)) { + if (!image_check_dcrc (fdt_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)) { + if (!image_check_type (fdt_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) { + if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { puts ("ERROR: uImage is compressed - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); @@ -318,11 +303,11 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, do_reset (cmdtp, flag, argc, argv); } - memmove ((void *)image_get_load (hdr), + memmove ((void *)image_get_load (fdt_hdr), (void *)(of_flat_tree + image_get_header_size ()), - image_get_data_size (hdr)); + image_get_data_size (fdt_hdr)); - of_flat_tree = (char *)image_get_load (hdr); + of_flat_tree = (char *)image_get_load (fdt_hdr); } else { puts ("Did not find a flat Flat Device Tree.\n" "Must RESET the board to recover.\n"); @@ -330,68 +315,52 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, } 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; - } + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + ulong fdt_data, fdt_len; - /* 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; - } + image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); + if (fdt_len) { + + of_flat_tree = (char *)fdt_data; #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; + /* 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) { + if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { #elif defined(CONFIG_OF_LIBFDT) - if (fdt_check_header (of_flat_tree) != 0) { + 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); - } + 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])) { + if (((struct boot_param_header *)of_flat_tree)->totalsize != fdt_len) { #elif defined(CONFIG_OF_LIBFDT) - if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != - image_to_cpu (len_ptr[2])) { + if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) { #endif - puts ("ERROR: fdt size != image size - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); + puts ("ERROR: fdt size != image size - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } } } #endif - if (!data) { + if (!rd_data) { debug ("No initrd\n"); } - if (data) { + if (rd_data) { if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = data; - initrd_end = initrd_start + len; + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; } else { - initrd_start = (ulong)kbd - len; + initrd_start = (ulong)kbd - rd_len; initrd_start &= ~(4096 - 1); /* align on page */ if (initrd_high) { @@ -412,7 +381,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, nsp &= ~0xF; if (nsp > initrd_high) /* limit as specified */ nsp = initrd_high; - nsp -= len; + nsp -= rd_len; nsp &= ~(4096 - 1); /* align on page */ if (nsp >= sp) initrd_start = nsp; @@ -421,14 +390,14 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, show_boot_progress (12); debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - data, data + len - 1, len, len); + rd_data, rd_data + rd_len - 1, rd_len, rd_len); - initrd_end = initrd_start + len; + initrd_end = initrd_start + rd_len; printf (" Loading Ramdisk to %08lx, end %08lx ... ", initrd_start, initrd_end); memmove_wd((void *)initrd_start, - (void *)data, len, CHUNKSZ); + (void *)rd_data, rd_len, CHUNKSZ); puts ("OK\n"); } -- cgit v0.10.2 From 7582438c285bf0cef82909d0f232de64ec567a8a Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:20:06 +0100 Subject: [new uImage] Return error on image move/uncompress overwrites 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 diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 2d17bdd..f441e0e 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 { @@ -234,6 +238,11 @@ 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) { @@ -244,6 +253,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) memmove_wd ((void *)image_get_load (hdr), (void *)os_data, os_len, CHUNKSZ); + load_end = load_start + os_len; puts("OK\n"); } break; @@ -255,6 +265,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: @@ -272,6 +284,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: @@ -284,6 +298,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 0a625fc..3911687 100644 --- a/lib_ppc/ppc_linux.c +++ b/lib_ppc/ppc_linux.c @@ -23,6 +23,8 @@ * MA 02111-1307 USA */ +#define DEBUG + #include #include #include @@ -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); -- cgit v0.10.2 From 4a995edec1ac163d9326d143ffe2b47e7543407f Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:20:06 +0100 Subject: [new uImage] Rename architecture specific bootm code files Implementation of the do_bootm_linux() and other bootm helper routines is architecture specific code. As such it resides in lib_ directories in files named _linux.c This patch renames those files to a more clear and accurate lib_/bootm.c form. List of the renamed files: lib_arm/armlinux.c -> lib_arm/bootm.c lib_avr32/avr32_linux.c -> lib_avr32/bootm.c lib_blackfin/bf533_linux.c -> lib_blackfin/bootm.c lib_i386/i386_linux.c -> lib_i386/bootm.c lib_m68k/m68k_linux.c -> lib_m68k/bootm.c lib_microblaze/microblaze_linux.c -> lib_microblaze/bootm.c lib_mips/mips_linux.c -> lib_mips/bootm.c lib_nios/nios_linux.c -> lib_nios/bootm.c lib_nios2/nios_linux.c -> lib_nios2/bootm.c lib_ppc/ppc_linux.c -> lib_ppc/bootm.c lib_sh/sh_linux.c -> lib_sh/bootm.c Signed-off-by: Marian Balakowicz diff --git a/lib_arm/Makefile b/lib_arm/Makefile index 037c475..aa9bee7 100644 --- a/lib_arm/Makefile +++ b/lib_arm/Makefile @@ -27,7 +27,7 @@ LIB = $(obj)lib$(ARCH).a SOBJS = _ashldi3.o _ashrdi3.o _divsi3.o _modsi3.o _udivsi3.o _umodsi3.o -COBJS = armlinux.o board.o \ +COBJS = bootm.o board.o \ cache.o div0.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/lib_arm/armlinux.c b/lib_arm/armlinux.c deleted file mode 100644 index 4f9aae6..0000000 --- a/lib_arm/armlinux.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) - * - * 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 -#include -#include -#include -#include -#ifdef CONFIG_HAS_DATAFLASH -#include -#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_SETUP_MEMORY_TAGS) || \ - defined (CONFIG_CMDLINE_TAG) || \ - defined (CONFIG_INITRD_TAG) || \ - defined (CONFIG_SERIAL_TAG) || \ - defined (CONFIG_REVISION_TAG) || \ - defined (CONFIG_VFD) || \ - defined (CONFIG_LCD) -static void setup_start_tag (bd_t *bd); - -# ifdef CONFIG_SETUP_MEMORY_TAGS -static void setup_memory_tags (bd_t *bd); -# endif -static void setup_commandline_tag (bd_t *bd, char *commandline); - -#if 0 -static void setup_ramdisk_tag (bd_t *bd); -#endif -# ifdef CONFIG_INITRD_TAG -static void setup_initrd_tag (bd_t *bd, ulong initrd_start, - ulong initrd_end); -# endif -static void setup_end_tag (bd_t *bd); - -# if defined (CONFIG_VFD) || defined (CONFIG_LCD) -static void setup_videolfb_tag (gd_t *gd); -# endif - - -static struct tag *params; -#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ - -void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) -{ - ulong rd_addr; - ulong rd_data, rd_len = 0; - ulong initrd_start, initrd_end; - image_header_t *rd_hdr; - void (*theKernel)(int zero, int arch, uint params); - bd_t *bd = gd->bd; - -#ifdef CONFIG_CMDLINE_TAG - char *commandline = getenv ("bootargs"); -#endif - - theKernel = (void (*)(int, int, uint))image_get_ep (hdr); - - /* - * Check if there is an initrd image - */ - if (argc >= 3) { - show_boot_progress (9); - - rd_addr = simple_strtoul (argv[2], NULL, 16); - printf ("## Loading Ramdisk Image at %08lx ...\n", rd_addr); - - /* Copy header so we can blank CRC field for re-calculation */ -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (rd_addr)) { - rd_hdr = (image_header_t *)CFG_LOAD_ADDR; - read_dataflash (rd_addr, image_get_header_size (), - (char *)rd_hdr); - } else -#endif - rd_hdr = (image_header_t *)rd_addr; - - if (!image_check_magic (rd_hdr)) { - printf ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - printf ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - - print_image_hdr (rd_hdr); - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (rd_addr)) - read_dataflash (rd_addr + image_get_header_size (), - rd_len, (char *)rd_data); -#endif - - if (verify) { - printf (" Verifying Checksum ... "); - if (!image_get_dcrc (rd_hdr)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - printf ("OK\n"); - } - - show_boot_progress (11); - - if (!image_check_os (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_ARM) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - printf ("No Linux ARM Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - -#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO) - /* - *we need to copy the ramdisk to SRAM to let Linux boot - */ - memmove ((void *)image_get_load (rd_hdr), (uchar *)rd_data, rd_len); - rd_data = image_get_load (rd_hdr); -#endif /* CONFIG_B2 || CONFIG_EVB4510 */ - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - show_boot_progress (13); - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - } else { - /* - * no initrd image - */ - show_boot_progress (14); - - rd_len = rd_data = 0; - } - -#ifdef DEBUG - if (!rd_data) { - printf ("No initrd\n"); - } -#endif - - if (rd_data) { - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - } else { - initrd_start = 0; - initrd_end = 0; - } - - show_boot_progress (15); - - debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) theKernel); - -#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ - defined (CONFIG_CMDLINE_TAG) || \ - defined (CONFIG_INITRD_TAG) || \ - defined (CONFIG_SERIAL_TAG) || \ - defined (CONFIG_REVISION_TAG) || \ - defined (CONFIG_LCD) || \ - defined (CONFIG_VFD) - setup_start_tag (bd); -#ifdef CONFIG_SERIAL_TAG - setup_serial_tag (¶ms); -#endif -#ifdef CONFIG_REVISION_TAG - setup_revision_tag (¶ms); -#endif -#ifdef CONFIG_SETUP_MEMORY_TAGS - setup_memory_tags (bd); -#endif -#ifdef CONFIG_CMDLINE_TAG - setup_commandline_tag (bd, commandline); -#endif -#ifdef CONFIG_INITRD_TAG - if (initrd_start && initrd_end) - setup_initrd_tag (bd, initrd_start, initrd_end); -#endif -#if defined (CONFIG_VFD) || defined (CONFIG_LCD) - setup_videolfb_tag ((gd_t *) gd); -#endif - setup_end_tag (bd); -#endif - - /* we assume that the kernel is in place */ - printf ("\nStarting kernel ...\n\n"); - -#ifdef CONFIG_USB_DEVICE - { - extern void udc_disconnect (void); - udc_disconnect (); - } -#endif - - cleanup_before_linux (); - - theKernel (0, bd->bi_arch_number, bd->bi_boot_params); -} - - -#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ - defined (CONFIG_CMDLINE_TAG) || \ - defined (CONFIG_INITRD_TAG) || \ - defined (CONFIG_SERIAL_TAG) || \ - defined (CONFIG_REVISION_TAG) || \ - defined (CONFIG_LCD) || \ - defined (CONFIG_VFD) -static void setup_start_tag (bd_t *bd) -{ - params = (struct tag *) bd->bi_boot_params; - - params->hdr.tag = ATAG_CORE; - params->hdr.size = tag_size (tag_core); - - params->u.core.flags = 0; - params->u.core.pagesize = 0; - params->u.core.rootdev = 0; - - params = tag_next (params); -} - - -#ifdef CONFIG_SETUP_MEMORY_TAGS -static void setup_memory_tags (bd_t *bd) -{ - int i; - - for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { - params->hdr.tag = ATAG_MEM; - params->hdr.size = tag_size (tag_mem32); - - params->u.mem.start = bd->bi_dram[i].start; - params->u.mem.size = bd->bi_dram[i].size; - - params = tag_next (params); - } -} -#endif /* CONFIG_SETUP_MEMORY_TAGS */ - - -static void setup_commandline_tag (bd_t *bd, char *commandline) -{ - char *p; - - if (!commandline) - return; - - /* eat leading white space */ - for (p = commandline; *p == ' '; p++); - - /* skip non-existent command lines so the kernel will still - * use its default command line. - */ - if (*p == '\0') - return; - - params->hdr.tag = ATAG_CMDLINE; - params->hdr.size = - (sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2; - - strcpy (params->u.cmdline.cmdline, p); - - params = tag_next (params); -} - - -#ifdef CONFIG_INITRD_TAG -static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end) -{ - /* an ATAG_INITRD node tells the kernel where the compressed - * ramdisk can be found. ATAG_RDIMG is a better name, actually. - */ - params->hdr.tag = ATAG_INITRD2; - params->hdr.size = tag_size (tag_initrd); - - params->u.initrd.start = initrd_start; - params->u.initrd.size = initrd_end - initrd_start; - - params = tag_next (params); -} -#endif /* CONFIG_INITRD_TAG */ - - -#if defined (CONFIG_VFD) || defined (CONFIG_LCD) -extern ulong calc_fbsize (void); -static void setup_videolfb_tag (gd_t *gd) -{ - /* An ATAG_VIDEOLFB node tells the kernel where and how large - * the framebuffer for video was allocated (among other things). - * Note that a _physical_ address is passed ! - * - * We only use it to pass the address and size, the other entries - * in the tag_videolfb are not of interest. - */ - params->hdr.tag = ATAG_VIDEOLFB; - params->hdr.size = tag_size (tag_videolfb); - - params->u.videolfb.lfb_base = (u32) gd->fb_base; - /* Fb size is calculated according to parameters for our panel - */ - params->u.videolfb.lfb_size = calc_fbsize(); - - params = tag_next (params); -} -#endif /* CONFIG_VFD || CONFIG_LCD */ - -#ifdef CONFIG_SERIAL_TAG -void setup_serial_tag (struct tag **tmp) -{ - struct tag *params = *tmp; - struct tag_serialnr serialnr; - void get_board_serial(struct tag_serialnr *serialnr); - - get_board_serial(&serialnr); - params->hdr.tag = ATAG_SERIAL; - params->hdr.size = tag_size (tag_serialnr); - params->u.serialnr.low = serialnr.low; - params->u.serialnr.high= serialnr.high; - params = tag_next (params); - *tmp = params; -} -#endif - -#ifdef CONFIG_REVISION_TAG -void setup_revision_tag(struct tag **in_params) -{ - u32 rev = 0; - u32 get_board_rev(void); - - rev = get_board_rev(); - params->hdr.tag = ATAG_REVISION; - params->hdr.size = tag_size (tag_revision); - params->u.revision.rev = rev; - params = tag_next (params); -} -#endif /* CONFIG_REVISION_TAG */ - - -static void setup_end_tag (bd_t *bd) -{ - params->hdr.tag = ATAG_NONE; - params->hdr.size = 0; -} - -#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c new file mode 100644 index 0000000..4f9aae6 --- /dev/null +++ b/lib_arm/bootm.c @@ -0,0 +1,384 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) + * + * 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 +#include +#include +#include +#include +#ifdef CONFIG_HAS_DATAFLASH +#include +#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_SETUP_MEMORY_TAGS) || \ + defined (CONFIG_CMDLINE_TAG) || \ + defined (CONFIG_INITRD_TAG) || \ + defined (CONFIG_SERIAL_TAG) || \ + defined (CONFIG_REVISION_TAG) || \ + defined (CONFIG_VFD) || \ + defined (CONFIG_LCD) +static void setup_start_tag (bd_t *bd); + +# ifdef CONFIG_SETUP_MEMORY_TAGS +static void setup_memory_tags (bd_t *bd); +# endif +static void setup_commandline_tag (bd_t *bd, char *commandline); + +#if 0 +static void setup_ramdisk_tag (bd_t *bd); +#endif +# ifdef CONFIG_INITRD_TAG +static void setup_initrd_tag (bd_t *bd, ulong initrd_start, + ulong initrd_end); +# endif +static void setup_end_tag (bd_t *bd); + +# if defined (CONFIG_VFD) || defined (CONFIG_LCD) +static void setup_videolfb_tag (gd_t *gd); +# endif + + +static struct tag *params; +#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ + +void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + image_header_t *hdr, int verify) +{ + ulong rd_addr; + ulong rd_data, rd_len = 0; + ulong initrd_start, initrd_end; + image_header_t *rd_hdr; + void (*theKernel)(int zero, int arch, uint params); + bd_t *bd = gd->bd; + +#ifdef CONFIG_CMDLINE_TAG + char *commandline = getenv ("bootargs"); +#endif + + theKernel = (void (*)(int, int, uint))image_get_ep (hdr); + + /* + * Check if there is an initrd image + */ + if (argc >= 3) { + show_boot_progress (9); + + rd_addr = simple_strtoul (argv[2], NULL, 16); + printf ("## Loading Ramdisk Image at %08lx ...\n", rd_addr); + + /* Copy header so we can blank CRC field for re-calculation */ +#ifdef CONFIG_HAS_DATAFLASH + if (addr_dataflash (rd_addr)) { + rd_hdr = (image_header_t *)CFG_LOAD_ADDR; + read_dataflash (rd_addr, image_get_header_size (), + (char *)rd_hdr); + } else +#endif + rd_hdr = (image_header_t *)rd_addr; + + if (!image_check_magic (rd_hdr)) { + printf ("Bad Magic Number\n"); + show_boot_progress (-10); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_hcrc (rd_hdr)) { + printf ("Bad Header Checksum\n"); + show_boot_progress (-11); + do_reset (cmdtp, flag, argc, argv); + } + + show_boot_progress (10); + + print_image_hdr (rd_hdr); + + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); + +#ifdef CONFIG_HAS_DATAFLASH + if (addr_dataflash (rd_addr)) + read_dataflash (rd_addr + image_get_header_size (), + rd_len, (char *)rd_data); +#endif + + if (verify) { + printf (" Verifying Checksum ... "); + if (!image_get_dcrc (rd_hdr)) { + printf ("Bad Data CRC\n"); + show_boot_progress (-12); + do_reset (cmdtp, flag, argc, argv); + } + printf ("OK\n"); + } + + show_boot_progress (11); + + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_ARM) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { + printf ("No Linux ARM Ramdisk Image\n"); + show_boot_progress (-13); + do_reset (cmdtp, flag, argc, argv); + } + +#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO) + /* + *we need to copy the ramdisk to SRAM to let Linux boot + */ + memmove ((void *)image_get_load (rd_hdr), (uchar *)rd_data, rd_len); + rd_data = image_get_load (rd_hdr); +#endif /* CONFIG_B2 || CONFIG_EVB4510 */ + + /* + * Now check if we have a multifile image + */ + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ + show_boot_progress (13); + image_multi_getimg (hdr, 1, &rd_data, &rd_len); + } else { + /* + * no initrd image + */ + show_boot_progress (14); + + rd_len = rd_data = 0; + } + +#ifdef DEBUG + if (!rd_data) { + printf ("No initrd\n"); + } +#endif + + if (rd_data) { + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; + } else { + initrd_start = 0; + initrd_end = 0; + } + + show_boot_progress (15); + + debug ("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) theKernel); + +#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ + defined (CONFIG_CMDLINE_TAG) || \ + defined (CONFIG_INITRD_TAG) || \ + defined (CONFIG_SERIAL_TAG) || \ + defined (CONFIG_REVISION_TAG) || \ + defined (CONFIG_LCD) || \ + defined (CONFIG_VFD) + setup_start_tag (bd); +#ifdef CONFIG_SERIAL_TAG + setup_serial_tag (¶ms); +#endif +#ifdef CONFIG_REVISION_TAG + setup_revision_tag (¶ms); +#endif +#ifdef CONFIG_SETUP_MEMORY_TAGS + setup_memory_tags (bd); +#endif +#ifdef CONFIG_CMDLINE_TAG + setup_commandline_tag (bd, commandline); +#endif +#ifdef CONFIG_INITRD_TAG + if (initrd_start && initrd_end) + setup_initrd_tag (bd, initrd_start, initrd_end); +#endif +#if defined (CONFIG_VFD) || defined (CONFIG_LCD) + setup_videolfb_tag ((gd_t *) gd); +#endif + setup_end_tag (bd); +#endif + + /* we assume that the kernel is in place */ + printf ("\nStarting kernel ...\n\n"); + +#ifdef CONFIG_USB_DEVICE + { + extern void udc_disconnect (void); + udc_disconnect (); + } +#endif + + cleanup_before_linux (); + + theKernel (0, bd->bi_arch_number, bd->bi_boot_params); +} + + +#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ + defined (CONFIG_CMDLINE_TAG) || \ + defined (CONFIG_INITRD_TAG) || \ + defined (CONFIG_SERIAL_TAG) || \ + defined (CONFIG_REVISION_TAG) || \ + defined (CONFIG_LCD) || \ + defined (CONFIG_VFD) +static void setup_start_tag (bd_t *bd) +{ + params = (struct tag *) bd->bi_boot_params; + + params->hdr.tag = ATAG_CORE; + params->hdr.size = tag_size (tag_core); + + params->u.core.flags = 0; + params->u.core.pagesize = 0; + params->u.core.rootdev = 0; + + params = tag_next (params); +} + + +#ifdef CONFIG_SETUP_MEMORY_TAGS +static void setup_memory_tags (bd_t *bd) +{ + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + params->hdr.tag = ATAG_MEM; + params->hdr.size = tag_size (tag_mem32); + + params->u.mem.start = bd->bi_dram[i].start; + params->u.mem.size = bd->bi_dram[i].size; + + params = tag_next (params); + } +} +#endif /* CONFIG_SETUP_MEMORY_TAGS */ + + +static void setup_commandline_tag (bd_t *bd, char *commandline) +{ + char *p; + + if (!commandline) + return; + + /* eat leading white space */ + for (p = commandline; *p == ' '; p++); + + /* skip non-existent command lines so the kernel will still + * use its default command line. + */ + if (*p == '\0') + return; + + params->hdr.tag = ATAG_CMDLINE; + params->hdr.size = + (sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2; + + strcpy (params->u.cmdline.cmdline, p); + + params = tag_next (params); +} + + +#ifdef CONFIG_INITRD_TAG +static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end) +{ + /* an ATAG_INITRD node tells the kernel where the compressed + * ramdisk can be found. ATAG_RDIMG is a better name, actually. + */ + params->hdr.tag = ATAG_INITRD2; + params->hdr.size = tag_size (tag_initrd); + + params->u.initrd.start = initrd_start; + params->u.initrd.size = initrd_end - initrd_start; + + params = tag_next (params); +} +#endif /* CONFIG_INITRD_TAG */ + + +#if defined (CONFIG_VFD) || defined (CONFIG_LCD) +extern ulong calc_fbsize (void); +static void setup_videolfb_tag (gd_t *gd) +{ + /* An ATAG_VIDEOLFB node tells the kernel where and how large + * the framebuffer for video was allocated (among other things). + * Note that a _physical_ address is passed ! + * + * We only use it to pass the address and size, the other entries + * in the tag_videolfb are not of interest. + */ + params->hdr.tag = ATAG_VIDEOLFB; + params->hdr.size = tag_size (tag_videolfb); + + params->u.videolfb.lfb_base = (u32) gd->fb_base; + /* Fb size is calculated according to parameters for our panel + */ + params->u.videolfb.lfb_size = calc_fbsize(); + + params = tag_next (params); +} +#endif /* CONFIG_VFD || CONFIG_LCD */ + +#ifdef CONFIG_SERIAL_TAG +void setup_serial_tag (struct tag **tmp) +{ + struct tag *params = *tmp; + struct tag_serialnr serialnr; + void get_board_serial(struct tag_serialnr *serialnr); + + get_board_serial(&serialnr); + params->hdr.tag = ATAG_SERIAL; + params->hdr.size = tag_size (tag_serialnr); + params->u.serialnr.low = serialnr.low; + params->u.serialnr.high= serialnr.high; + params = tag_next (params); + *tmp = params; +} +#endif + +#ifdef CONFIG_REVISION_TAG +void setup_revision_tag(struct tag **in_params) +{ + u32 rev = 0; + u32 get_board_rev(void); + + rev = get_board_rev(); + params->hdr.tag = ATAG_REVISION; + params->hdr.size = tag_size (tag_revision); + params->u.revision.rev = rev; + params = tag_next (params); +} +#endif /* CONFIG_REVISION_TAG */ + + +static void setup_end_tag (bd_t *bd) +{ + params->hdr.tag = ATAG_NONE; + params->hdr.size = 0; +} + +#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ diff --git a/lib_avr32/Makefile b/lib_avr32/Makefile index bb2938f..ebe237b 100644 --- a/lib_avr32/Makefile +++ b/lib_avr32/Makefile @@ -29,7 +29,7 @@ LIB = $(obj)lib$(ARCH).a SOBJS = memset.o -COBJS = board.o interrupts.o avr32_linux.o +COBJS = board.o interrupts.o bootm.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/lib_avr32/avr32_linux.c b/lib_avr32/avr32_linux.c deleted file mode 100644 index 455590e..0000000 --- a/lib_avr32/avr32_linux.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - -/* CPU-specific hook to allow flushing of caches, etc. */ -extern void prepare_to_boot(void); - -static struct tag *setup_start_tag(struct tag *params) -{ - params->hdr.tag = ATAG_CORE; - params->hdr.size = tag_size(tag_core); - - params->u.core.flags = 0; - params->u.core.pagesize = 4096; - params->u.core.rootdev = 0; - - return tag_next(params); -} - -static struct tag *setup_memory_tags(struct tag *params) -{ - bd_t *bd = gd->bd; - int i; - - for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { - params->hdr.tag = ATAG_MEM; - params->hdr.size = tag_size(tag_mem_range); - - params->u.mem_range.addr = bd->bi_dram[i].start; - params->u.mem_range.size = bd->bi_dram[i].size; - - params = tag_next(params); - } - - return params; -} - -static struct tag *setup_commandline_tag(struct tag *params, char *cmdline) -{ - if (!cmdline) - return params; - - /* eat leading white space */ - while (*cmdline == ' ') cmdline++; - - /* - * Don't include tags for empty command lines; let the kernel - * use its default command line. - */ - if (*cmdline == '\0') - return params; - - params->hdr.tag = ATAG_CMDLINE; - params->hdr.size = - (sizeof (struct tag_header) + strlen(cmdline) + 1 + 3) >> 2; - strcpy(params->u.cmdline.cmdline, cmdline); - - return tag_next(params); -} - -static struct tag *setup_ramdisk_tag(struct tag *params, - unsigned long rd_start, - unsigned long rd_end) -{ - if (rd_start == rd_end) - return params; - - params->hdr.tag = ATAG_RDIMG; - params->hdr.size = tag_size(tag_mem_range); - - params->u.mem_range.addr = rd_start; - params->u.mem_range.size = rd_end - rd_start; - - return tag_next(params); -} - -static struct tag *setup_clock_tags(struct tag *params) -{ - params->hdr.tag = ATAG_CLOCK; - params->hdr.size = tag_size(tag_clock); - params->u.clock.clock_id = ACLOCK_BOOTCPU; - params->u.clock.clock_flags = 0; - params->u.clock.clock_hz = gd->cpu_hz; - -#ifdef CONFIG_AT32AP7000 - /* - * New kernels don't need this, but we should be backwards - * compatible for a while... - */ - params = tag_next(params); - - params->hdr.tag = ATAG_CLOCK; - params->hdr.size = tag_size(tag_clock); - params->u.clock.clock_id = ACLOCK_HSB; - params->u.clock.clock_flags = 0; - params->u.clock.clock_hz = get_hsb_clk_rate(); -#endif - - return tag_next(params); -} - -static struct tag *setup_ethernet_tag(struct tag *params, - char *addr, int index) -{ - char *s, *e; - int i; - - params->hdr.tag = ATAG_ETHERNET; - params->hdr.size = tag_size(tag_ethernet); - - params->u.ethernet.mac_index = index; - params->u.ethernet.mii_phy_addr = gd->bd->bi_phy_id[index]; - - s = addr; - for (i = 0; i < 6; i++) { - params->u.ethernet.hw_address[i] = simple_strtoul(s, &e, 16); - s = e + 1; - } - - return tag_next(params); -} - -static struct tag *setup_ethernet_tags(struct tag *params) -{ - char name[16] = "ethaddr"; - char *addr; - int i = 0; - - do { - addr = getenv(name); - if (addr) - params = setup_ethernet_tag(params, addr, i); - sprintf(name, "eth%daddr", ++i); - } while (i < 4); - - return params; -} - -static void setup_end_tag(struct tag *params) -{ - params->hdr.tag = ATAG_NONE; - params->hdr.size = 0; -} - -void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) -{ - ulong rd_data, rd_len = 0; - ulong initrd_start, initrd_end; - image_header_t *rd_hdr; - - void (*theKernel)(int magic, void *tagtable); - struct tag *params, *params_start; - char *commandline = getenv("bootargs"); - - theKernel = (void *)image_get_ep (hdr); - - /* - * Check if there is an initrd image - */ - if (argc >= 3) { - show_boot_progress (9); - - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading RAMDISK image at %08lx ...\n", rd_hdr); - - if (!image_check_magic (rd_hdr)) { - puts("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset(cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - puts("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset(cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - print_image_hdr (rd_hdr); - - if (verify) { - puts(" Verifying Checksum ... "); - if (!image_check_dcrc (rd_hdr)) { - 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 (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_AVR32) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - puts("Not a Linux/AVR32 RAMDISK image\n"); - show_boot_progress (-13); - do_reset(cmdtp, flag, argc, argv); - } - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - show_boot_progress (13); - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - } else { - /* no initrd image */ - show_boot_progress (14); - rd_len = rd_data = 0; - } - - if (rd_data) { - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - } else { - initrd_start = 0; - initrd_end = 0; - } - - show_boot_progress (15); - - params = params_start = (struct tag *)gd->bd->bi_boot_params; - params = setup_start_tag(params); - params = setup_memory_tags(params); - if (initrd_start) { - params = setup_ramdisk_tag(params, - PHYSADDR(initrd_start), - PHYSADDR(initrd_end)); - } - params = setup_commandline_tag(params, commandline); - params = setup_clock_tags(params); - params = setup_ethernet_tags(params); - setup_end_tag(params); - - printf("\nStarting kernel at %p (params at %p)...\n\n", - theKernel, params_start); - - prepare_to_boot(); - - theKernel(ATAG_MAGIC, params_start); -} diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c new file mode 100644 index 0000000..455590e --- /dev/null +++ b/lib_avr32/bootm.c @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +/* CPU-specific hook to allow flushing of caches, etc. */ +extern void prepare_to_boot(void); + +static struct tag *setup_start_tag(struct tag *params) +{ + params->hdr.tag = ATAG_CORE; + params->hdr.size = tag_size(tag_core); + + params->u.core.flags = 0; + params->u.core.pagesize = 4096; + params->u.core.rootdev = 0; + + return tag_next(params); +} + +static struct tag *setup_memory_tags(struct tag *params) +{ + bd_t *bd = gd->bd; + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + params->hdr.tag = ATAG_MEM; + params->hdr.size = tag_size(tag_mem_range); + + params->u.mem_range.addr = bd->bi_dram[i].start; + params->u.mem_range.size = bd->bi_dram[i].size; + + params = tag_next(params); + } + + return params; +} + +static struct tag *setup_commandline_tag(struct tag *params, char *cmdline) +{ + if (!cmdline) + return params; + + /* eat leading white space */ + while (*cmdline == ' ') cmdline++; + + /* + * Don't include tags for empty command lines; let the kernel + * use its default command line. + */ + if (*cmdline == '\0') + return params; + + params->hdr.tag = ATAG_CMDLINE; + params->hdr.size = + (sizeof (struct tag_header) + strlen(cmdline) + 1 + 3) >> 2; + strcpy(params->u.cmdline.cmdline, cmdline); + + return tag_next(params); +} + +static struct tag *setup_ramdisk_tag(struct tag *params, + unsigned long rd_start, + unsigned long rd_end) +{ + if (rd_start == rd_end) + return params; + + params->hdr.tag = ATAG_RDIMG; + params->hdr.size = tag_size(tag_mem_range); + + params->u.mem_range.addr = rd_start; + params->u.mem_range.size = rd_end - rd_start; + + return tag_next(params); +} + +static struct tag *setup_clock_tags(struct tag *params) +{ + params->hdr.tag = ATAG_CLOCK; + params->hdr.size = tag_size(tag_clock); + params->u.clock.clock_id = ACLOCK_BOOTCPU; + params->u.clock.clock_flags = 0; + params->u.clock.clock_hz = gd->cpu_hz; + +#ifdef CONFIG_AT32AP7000 + /* + * New kernels don't need this, but we should be backwards + * compatible for a while... + */ + params = tag_next(params); + + params->hdr.tag = ATAG_CLOCK; + params->hdr.size = tag_size(tag_clock); + params->u.clock.clock_id = ACLOCK_HSB; + params->u.clock.clock_flags = 0; + params->u.clock.clock_hz = get_hsb_clk_rate(); +#endif + + return tag_next(params); +} + +static struct tag *setup_ethernet_tag(struct tag *params, + char *addr, int index) +{ + char *s, *e; + int i; + + params->hdr.tag = ATAG_ETHERNET; + params->hdr.size = tag_size(tag_ethernet); + + params->u.ethernet.mac_index = index; + params->u.ethernet.mii_phy_addr = gd->bd->bi_phy_id[index]; + + s = addr; + for (i = 0; i < 6; i++) { + params->u.ethernet.hw_address[i] = simple_strtoul(s, &e, 16); + s = e + 1; + } + + return tag_next(params); +} + +static struct tag *setup_ethernet_tags(struct tag *params) +{ + char name[16] = "ethaddr"; + char *addr; + int i = 0; + + do { + addr = getenv(name); + if (addr) + params = setup_ethernet_tag(params, addr, i); + sprintf(name, "eth%daddr", ++i); + } while (i < 4); + + return params; +} + +static void setup_end_tag(struct tag *params) +{ + params->hdr.tag = ATAG_NONE; + params->hdr.size = 0; +} + +void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + image_header_t *hdr, int verify) +{ + ulong rd_data, rd_len = 0; + ulong initrd_start, initrd_end; + image_header_t *rd_hdr; + + void (*theKernel)(int magic, void *tagtable); + struct tag *params, *params_start; + char *commandline = getenv("bootargs"); + + theKernel = (void *)image_get_ep (hdr); + + /* + * Check if there is an initrd image + */ + if (argc >= 3) { + show_boot_progress (9); + + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading RAMDISK image at %08lx ...\n", rd_hdr); + + if (!image_check_magic (rd_hdr)) { + puts("Bad Magic Number\n"); + show_boot_progress (-10); + do_reset(cmdtp, flag, argc, argv); + } + + if (!image_check_hcrc (rd_hdr)) { + puts("Bad Header Checksum\n"); + show_boot_progress (-11); + do_reset(cmdtp, flag, argc, argv); + } + + show_boot_progress (10); + print_image_hdr (rd_hdr); + + if (verify) { + puts(" Verifying Checksum ... "); + if (!image_check_dcrc (rd_hdr)) { + 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 (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_AVR32) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { + puts("Not a Linux/AVR32 RAMDISK image\n"); + show_boot_progress (-13); + do_reset(cmdtp, flag, argc, argv); + } + + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); + + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ + show_boot_progress (13); + image_multi_getimg (hdr, 1, &rd_data, &rd_len); + } else { + /* no initrd image */ + show_boot_progress (14); + rd_len = rd_data = 0; + } + + if (rd_data) { + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; + } else { + initrd_start = 0; + initrd_end = 0; + } + + show_boot_progress (15); + + params = params_start = (struct tag *)gd->bd->bi_boot_params; + params = setup_start_tag(params); + params = setup_memory_tags(params); + if (initrd_start) { + params = setup_ramdisk_tag(params, + PHYSADDR(initrd_start), + PHYSADDR(initrd_end)); + } + params = setup_commandline_tag(params, commandline); + params = setup_clock_tags(params); + params = setup_ethernet_tags(params); + setup_end_tag(params); + + printf("\nStarting kernel at %p (params at %p)...\n\n", + theKernel, params_start); + + prepare_to_boot(); + + theKernel(ATAG_MAGIC, params_start); +} diff --git a/lib_blackfin/Makefile b/lib_blackfin/Makefile index a7aaef7..ac3fb28 100644 --- a/lib_blackfin/Makefile +++ b/lib_blackfin/Makefile @@ -31,7 +31,7 @@ LIB = $(obj)lib$(ARCH).a SOBJS = memcpy.o memcmp.o memset.o memmove.o -COBJS = post.o tests.o board.o bf533_linux.o bf533_string.o cache.o muldi3.o +COBJS = post.o tests.o board.o bootm.o bf533_string.o cache.o muldi3.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/lib_blackfin/bf533_linux.c b/lib_blackfin/bf533_linux.c deleted file mode 100644 index 6299415..0000000 --- a/lib_blackfin/bf533_linux.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * U-boot - bf533_linux.c - * - * Copyright (c) 2005-2007 Analog Devices Inc. - * - * (C) Copyright 2000-2004 - * 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., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -/* Dummy functions, currently not in Use */ - -#include -#include -#include -#include -#include - -#define LINUX_MAX_ENVS 256 -#define LINUX_MAX_ARGS 256 - -#define CMD_LINE_ADDR 0xFF900000 /* L1 scratchpad */ - -#ifdef SHARED_RESOURCES -extern void swap_to(int device_id); -#endif - -extern void flush_instruction_cache(void); -extern void flush_data_cache(void); -static char *make_command_line(void); - -void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) -{ - int (*appl) (char *cmdline); - char *cmdline; - -#ifdef SHARED_RESOURCES - swap_to(FLASH); -#endif - - appl = (int (*)(char *))image_get_ep (hdr); - printf("Starting Kernel at = %x\n", appl); - cmdline = make_command_line(); - if (icache_status()) { - flush_instruction_cache(); - icache_disable(); - } - if (dcache_status()) { - flush_data_cache(); - dcache_disable(); - } - (*appl) (cmdline); -} - -char *make_command_line(void) -{ - char *dest = (char *)CMD_LINE_ADDR; - char *bootargs; - - if ((bootargs = getenv("bootargs")) == NULL) - return NULL; - - strncpy(dest, bootargs, 0x1000); - dest[0xfff] = 0; - return dest; -} diff --git a/lib_blackfin/bootm.c b/lib_blackfin/bootm.c new file mode 100644 index 0000000..6299415 --- /dev/null +++ b/lib_blackfin/bootm.c @@ -0,0 +1,84 @@ +/* + * U-boot - bf533_linux.c + * + * Copyright (c) 2005-2007 Analog Devices Inc. + * + * (C) Copyright 2000-2004 + * 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., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +/* Dummy functions, currently not in Use */ + +#include +#include +#include +#include +#include + +#define LINUX_MAX_ENVS 256 +#define LINUX_MAX_ARGS 256 + +#define CMD_LINE_ADDR 0xFF900000 /* L1 scratchpad */ + +#ifdef SHARED_RESOURCES +extern void swap_to(int device_id); +#endif + +extern void flush_instruction_cache(void); +extern void flush_data_cache(void); +static char *make_command_line(void); + +void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], + image_header_t *hdr, int verify) +{ + int (*appl) (char *cmdline); + char *cmdline; + +#ifdef SHARED_RESOURCES + swap_to(FLASH); +#endif + + appl = (int (*)(char *))image_get_ep (hdr); + printf("Starting Kernel at = %x\n", appl); + cmdline = make_command_line(); + if (icache_status()) { + flush_instruction_cache(); + icache_disable(); + } + if (dcache_status()) { + flush_data_cache(); + dcache_disable(); + } + (*appl) (cmdline); +} + +char *make_command_line(void) +{ + char *dest = (char *)CMD_LINE_ADDR; + char *bootargs; + + if ((bootargs = getenv("bootargs")) == NULL) + return NULL; + + strncpy(dest, bootargs, 0x1000); + dest[0xfff] = 0; + return dest; +} diff --git a/lib_i386/Makefile b/lib_i386/Makefile index e344da5..ef0ba54 100644 --- a/lib_i386/Makefile +++ b/lib_i386/Makefile @@ -27,7 +27,7 @@ LIB = $(obj)lib$(ARCH).a SOBJS = bios.o bios_pci.o realmode_switch.o -COBJS = board.o bios_setup.o i386_linux.o zimage.o realmode.o \ +COBJS = board.o bios_setup.o bootm.o zimage.o realmode.o \ pci_type1.o pci.o video_bios.o video.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c new file mode 100644 index 0000000..27a2b0d --- /dev/null +++ b/lib_i386/bootm.c @@ -0,0 +1,142 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) + * + * 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 +#include +#include +#include +#include +#include + +/*cmd_boot.c*/ +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + image_header_t *hdr, int verify) +{ + void *base_ptr; + + ulong os_data, os_len; + ulong rd_data, rd_len; + ulong initrd_start, initrd_end; + image_header_t *rd_hdr; + + /* + * Check if there is an initrd image + */ + if (argc >= 3) { + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr); + + if (!image_check_magic (rd_hdr)) { + printf ("Bad Magic Number\n"); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_hcrc (rd_hdr)) { + printf ("Bad Header Checksum\n"); + do_reset (cmdtp, flag, argc, argv); + } + + print_image_hdr (rd_hdr); + + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); + + if (verify) { + printf (" Verifying Checksum ... "); + if (!image_check_dcrc (rd_hdr)) { + printf ("Bad Data CRC\n"); + do_reset (cmdtp, flag, argc, argv); + } + printf ("OK\n"); + } + + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_I386) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { + printf ("No Linux i386 Ramdisk Image\n"); + do_reset (cmdtp, flag, argc, argv); + } + + /* + * Now check if we have a multifile image + */ + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ + image_multi_getimg (hdr, 1, &rd_data, &rd_len); + } else { + /* + * no initrd image + */ + rd_data = rd_len = 0; + } + +#ifdef DEBUG + if (!rd_data) { + printf ("No initrd\n"); + } +#endif + + if (rd_data) { + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; + printf (" Loading Ramdisk to %08lx, end %08lx ... ", + initrd_start, initrd_end); + memmove ((void *)initrd_start, (void *)rd_data, rd_len); + printf ("OK\n"); + } else { + initrd_start = 0; + initrd_end = 0; + } + + /* if multi-part image, we need to advance base ptr */ + if (image_check_type (hdr, IH_TYPE_MULTI)) { + image_multi_getimg (hdr, 0, &os_data, &os_len); + } else { + os_data = image_get_data (hdr); + os_len = image_get_data_size (hdr); + } + + base_ptr = load_zimage ((void*)os_data, os_len, + initrd_start, rd_len, 0); + + if (NULL == base_ptr) { + printf ("## Kernel loading failed ...\n"); + do_reset(cmdtp, flag, argc, argv); + + } + +#ifdef DEBUG + printf ("## Transferring control to Linux (at address %08x) ...\n", + (u32)base_ptr); +#endif + + /* we assume that the kernel is in place */ + printf("\nStarting kernel ...\n\n"); + + boot_zimage(base_ptr); + +} diff --git a/lib_i386/i386_linux.c b/lib_i386/i386_linux.c deleted file mode 100644 index 27a2b0d..0000000 --- a/lib_i386/i386_linux.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) - * - * 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 -#include -#include -#include -#include -#include - -/*cmd_boot.c*/ -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - -void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) -{ - void *base_ptr; - - ulong os_data, os_len; - ulong rd_data, rd_len; - ulong initrd_start, initrd_end; - image_header_t *rd_hdr; - - /* - * Check if there is an initrd image - */ - if (argc >= 3) { - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr); - - if (!image_check_magic (rd_hdr)) { - printf ("Bad Magic Number\n"); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - printf ("Bad Header Checksum\n"); - do_reset (cmdtp, flag, argc, argv); - } - - print_image_hdr (rd_hdr); - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - - if (verify) { - printf (" Verifying Checksum ... "); - if (!image_check_dcrc (rd_hdr)) { - printf ("Bad Data CRC\n"); - do_reset (cmdtp, flag, argc, argv); - } - printf ("OK\n"); - } - - if (!image_check_os (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_I386) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - printf ("No Linux i386 Ramdisk Image\n"); - do_reset (cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - } else { - /* - * no initrd image - */ - rd_data = rd_len = 0; - } - -#ifdef DEBUG - if (!rd_data) { - printf ("No initrd\n"); - } -#endif - - if (rd_data) { - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - printf (" Loading Ramdisk to %08lx, end %08lx ... ", - initrd_start, initrd_end); - memmove ((void *)initrd_start, (void *)rd_data, rd_len); - printf ("OK\n"); - } else { - initrd_start = 0; - initrd_end = 0; - } - - /* if multi-part image, we need to advance base ptr */ - if (image_check_type (hdr, IH_TYPE_MULTI)) { - image_multi_getimg (hdr, 0, &os_data, &os_len); - } else { - os_data = image_get_data (hdr); - os_len = image_get_data_size (hdr); - } - - base_ptr = load_zimage ((void*)os_data, os_len, - initrd_start, rd_len, 0); - - if (NULL == base_ptr) { - printf ("## Kernel loading failed ...\n"); - do_reset(cmdtp, flag, argc, argv); - - } - -#ifdef DEBUG - printf ("## Transferring control to Linux (at address %08x) ...\n", - (u32)base_ptr); -#endif - - /* we assume that the kernel is in place */ - printf("\nStarting kernel ...\n\n"); - - boot_zimage(base_ptr); - -} diff --git a/lib_m68k/Makefile b/lib_m68k/Makefile index 03784fd..d515223 100644 --- a/lib_m68k/Makefile +++ b/lib_m68k/Makefile @@ -27,7 +27,7 @@ LIB = $(obj)lib$(ARCH).a SOBJS = -COBJS = cache.o traps.o time.o interrupts.o board.o m68k_linux.o +COBJS = cache.o traps.o time.o interrupts.o board.o bootm.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c new file mode 100644 index 0000000..b135556 --- /dev/null +++ b/lib_m68k/bootm.c @@ -0,0 +1,279 @@ +/* + * (C) Copyright 2003 + * 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 +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define PHYSADDR(x) x + +#define LINUX_MAX_ENVS 256 +#define LINUX_MAX_ARGS 256 + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# include +# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) +#else +# define SHOW_BOOT_PROGRESS(arg) +#endif + +int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, + int argc, char *argv[], + image_header_t *hdr, int verify) +{ + ulong sp; + + ulong rd_data, rd_len; + ulong initrd_high; + ulong initrd_start, initrd_end; + image_header_t *rd_hdr; + int initrd_copy_to_ram = 1; + + ulong cmd_start, cmd_end; + char *cmdline; + char *s; + bd_t *kbd; + void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); + + 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("movel %%a7, %%d0\n" + "movel %%d0, %0\n": "=d"(sp): :"%d0"); + + 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; + } + + kernel = + (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); + + /* + * Check if there is an initrd image + */ + + if (argc >= 3) { + debug("Not skipping initrd\n"); + SHOW_BOOT_PROGRESS(9); + + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading RAMDisk Image at %08lx ...\n", rd_hdr); + + if (!image_check_magic (rd_hdr)) { + puts("Bad Magic Number\n"); + SHOW_BOOT_PROGRESS(-10); + do_reset(cmdtp, flag, argc, argv); + } + + if (!image_check_hcrc (rd_hdr)) { + puts("Bad Header Checksum\n"); + SHOW_BOOT_PROGRESS(-11); + do_reset(cmdtp, flag, argc, argv); + } + + SHOW_BOOT_PROGRESS(10); + + print_image_hdr (rd_hdr); + + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); + + if (verify) { + puts(" Verifying Checksum ... "); + if (!image_check_dcrc_wd (rd_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 (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_M68K) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { + puts("No Linux ColdFire Ramdisk Image\n"); + SHOW_BOOT_PROGRESS(-13); + do_reset(cmdtp, flag, argc, argv); + } + + /* + * Now check if we have a multifile image + */ + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ + SHOW_BOOT_PROGRESS (13); + image_multi_getimg (hdr, 1, &rd_data, &rd_len); + } else { + /* + * no initrd image + */ + SHOW_BOOT_PROGRESS(14); + + rd_len = rd_data = 0; + } + + if (!rd_data) { + debug("No initrd\n"); + } + + if (rd_data) { + if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; + } else { + initrd_start = (ulong) kbd - rd_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("movel %%a7, %%d0\n" + "movel %%d0, %0\n": "=d"(nsp): :"%d0"); + + nsp -= 2048; /* just to be sure */ + nsp &= ~0xF; + + if (nsp > initrd_high) /* limit as specified */ + nsp = initrd_high; + + nsp -= rd_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", + rd_data, rd_data + rd_len - 1, rd_len, rd_len); + + initrd_end = initrd_start + rd_len; + printf(" Loading Ramdisk to %08lx, end %08lx ... ", + initrd_start, initrd_end); + + memmove_wd((void *)initrd_start, + (void *)rd_data, rd_len, CHUNKSZ); + + puts("OK\n"); + } + } else { + initrd_start = 0; + initrd_end = 0; + } + + debug("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) kernel); + + SHOW_BOOT_PROGRESS(15); + + /* + * 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 */ +} diff --git a/lib_m68k/m68k_linux.c b/lib_m68k/m68k_linux.c deleted file mode 100644 index b135556..0000000 --- a/lib_m68k/m68k_linux.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * (C) Copyright 2003 - * 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 -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -#define PHYSADDR(x) x - -#define LINUX_MAX_ENVS 256 -#define LINUX_MAX_ARGS 256 - -#ifdef CONFIG_SHOW_BOOT_PROGRESS -# include -# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) -#else -# define SHOW_BOOT_PROGRESS(arg) -#endif - -int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - -void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, - int argc, char *argv[], - image_header_t *hdr, int verify) -{ - ulong sp; - - ulong rd_data, rd_len; - ulong initrd_high; - ulong initrd_start, initrd_end; - image_header_t *rd_hdr; - int initrd_copy_to_ram = 1; - - ulong cmd_start, cmd_end; - char *cmdline; - char *s; - bd_t *kbd; - void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); - - 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("movel %%a7, %%d0\n" - "movel %%d0, %0\n": "=d"(sp): :"%d0"); - - 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; - } - - kernel = - (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); - - /* - * Check if there is an initrd image - */ - - if (argc >= 3) { - debug("Not skipping initrd\n"); - SHOW_BOOT_PROGRESS(9); - - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading RAMDisk Image at %08lx ...\n", rd_hdr); - - if (!image_check_magic (rd_hdr)) { - puts("Bad Magic Number\n"); - SHOW_BOOT_PROGRESS(-10); - do_reset(cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - puts("Bad Header Checksum\n"); - SHOW_BOOT_PROGRESS(-11); - do_reset(cmdtp, flag, argc, argv); - } - - SHOW_BOOT_PROGRESS(10); - - print_image_hdr (rd_hdr); - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - - if (verify) { - puts(" Verifying Checksum ... "); - if (!image_check_dcrc_wd (rd_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 (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_M68K) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - puts("No Linux ColdFire Ramdisk Image\n"); - SHOW_BOOT_PROGRESS(-13); - do_reset(cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - SHOW_BOOT_PROGRESS (13); - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - } else { - /* - * no initrd image - */ - SHOW_BOOT_PROGRESS(14); - - rd_len = rd_data = 0; - } - - if (!rd_data) { - debug("No initrd\n"); - } - - if (rd_data) { - if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - } else { - initrd_start = (ulong) kbd - rd_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("movel %%a7, %%d0\n" - "movel %%d0, %0\n": "=d"(nsp): :"%d0"); - - nsp -= 2048; /* just to be sure */ - nsp &= ~0xF; - - if (nsp > initrd_high) /* limit as specified */ - nsp = initrd_high; - - nsp -= rd_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", - rd_data, rd_data + rd_len - 1, rd_len, rd_len); - - initrd_end = initrd_start + rd_len; - printf(" Loading Ramdisk to %08lx, end %08lx ... ", - initrd_start, initrd_end); - - memmove_wd((void *)initrd_start, - (void *)rd_data, rd_len, CHUNKSZ); - - puts("OK\n"); - } - } else { - initrd_start = 0; - initrd_end = 0; - } - - debug("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) kernel); - - SHOW_BOOT_PROGRESS(15); - - /* - * 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 */ -} diff --git a/lib_microblaze/Makefile b/lib_microblaze/Makefile index 82b7bea..9b317a2 100644 --- a/lib_microblaze/Makefile +++ b/lib_microblaze/Makefile @@ -27,7 +27,7 @@ LIB = $(obj)lib$(ARCH).a SOBJS = -COBJS = board.o microblaze_linux.o time.o cache.o +COBJS = board.o bootm.o time.o cache.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/lib_microblaze/bootm.c b/lib_microblaze/bootm.c new file mode 100644 index 0000000..a4fce5a --- /dev/null +++ b/lib_microblaze/bootm.c @@ -0,0 +1,138 @@ +/* + * (C) Copyright 2007 Michal Simek + * (C) Copyright 2004 Atmark Techno, Inc. + * + * Michal SIMEK + * Yasushi SHOJI + * + * 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 +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +extern int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); + +void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], + image_header_t *hdr, int verify) +{ + int i; + ulong checksum; + + ulong rd_data, rd_len; + ulong initrd_start, initrd_end; + image_header_t *rd_hdr; + + /* First parameter is mapped to $r5 for kernel boot args */ + void (*theKernel) (char *); + char *commandline = getenv ("bootargs"); + + theKernel = (void (*)(char *))image_get_ep (hdr); + + /* Check if there is an initrd image */ + if (argc >= 3) { + show_boot_progress (9); + + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr); + + if (!image_check_magic (rd_hdr)) { + printf ("Bad Magic Number\n"); + show_boot_progress (-10); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_magic (rd_hdr)) { + printf ("Bad Header Checksum\n"); + show_boot_progress (-11); + do_reset (cmdtp, flag, argc, argv); + } + + show_boot_progress (10); + print_image_hdr (rd_hdr); + + rd_data = image_get_data (rd_hdr); + rd_en = image_get_data_size (rd_hdr); + + if (verify) { + printf (" Verifying Checksum ... "); + if (!image_check_dcrc (rd_hdr)) { + printf ("Bad Data CRC\n"); + show_boot_progress (-12); + do_reset (cmdtp, flag, argc, argv); + } + printf ("OK\n"); + } + + show_boot_progress (11); + + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_MICROBLAZE) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { + printf ("No Linux Microblaze Ramdisk Image\n"); + show_boot_progress (-13); + do_reset (cmdtp, flag, argc, argv); + } + + /* + * Now check if we have a multifile image + */ + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ + show_boot_progress (13); + image_multi_getimg (hdr, 1, &rd_data, &rd_len); + } else { + /* + * no initrd image + */ + show_boot_progress (14); + + rd_data = rd_len = 0; + } + +#ifdef DEBUG + if (!rd_data) { + printf ("No initrd\n"); + } +#endif + + if (rd_data) { + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; + } else { + initrd_start = 0; + initrd_end = 0; + } + + show_boot_progress (15); + +#ifdef DEBUG + printf ("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) theKernel); +#endif + + theKernel (commandline); +} diff --git a/lib_microblaze/microblaze_linux.c b/lib_microblaze/microblaze_linux.c deleted file mode 100644 index a4fce5a..0000000 --- a/lib_microblaze/microblaze_linux.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * (C) Copyright 2007 Michal Simek - * (C) Copyright 2004 Atmark Techno, Inc. - * - * Michal SIMEK - * Yasushi SHOJI - * - * 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 -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -extern int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); - -void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) -{ - int i; - ulong checksum; - - ulong rd_data, rd_len; - ulong initrd_start, initrd_end; - image_header_t *rd_hdr; - - /* First parameter is mapped to $r5 for kernel boot args */ - void (*theKernel) (char *); - char *commandline = getenv ("bootargs"); - - theKernel = (void (*)(char *))image_get_ep (hdr); - - /* Check if there is an initrd image */ - if (argc >= 3) { - show_boot_progress (9); - - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr); - - if (!image_check_magic (rd_hdr)) { - printf ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_magic (rd_hdr)) { - printf ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - print_image_hdr (rd_hdr); - - rd_data = image_get_data (rd_hdr); - rd_en = image_get_data_size (rd_hdr); - - if (verify) { - printf (" Verifying Checksum ... "); - if (!image_check_dcrc (rd_hdr)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - printf ("OK\n"); - } - - show_boot_progress (11); - - if (!image_check_os (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_MICROBLAZE) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - printf ("No Linux Microblaze Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - show_boot_progress (13); - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - } else { - /* - * no initrd image - */ - show_boot_progress (14); - - rd_data = rd_len = 0; - } - -#ifdef DEBUG - if (!rd_data) { - printf ("No initrd\n"); - } -#endif - - if (rd_data) { - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - } else { - initrd_start = 0; - initrd_end = 0; - } - - show_boot_progress (15); - -#ifdef DEBUG - printf ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) theKernel); -#endif - - theKernel (commandline); -} diff --git a/lib_mips/Makefile b/lib_mips/Makefile index 3163f00..93cca7a 100644 --- a/lib_mips/Makefile +++ b/lib_mips/Makefile @@ -27,7 +27,7 @@ LIB = $(obj)lib$(ARCH).a SOBJS = -COBJS = board.o time.o mips_linux.o +COBJS = board.o time.o bootm.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c new file mode 100644 index 0000000..7ea7571 --- /dev/null +++ b/lib_mips/bootm.c @@ -0,0 +1,249 @@ +/* + * (C) Copyright 2003 + * 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 +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define LINUX_MAX_ENVS 256 +#define LINUX_MAX_ARGS 256 + +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +static int linux_argc; +static char ** linux_argv; + +static char ** linux_env; +static char * linux_env_p; +static int linux_env_idx; + +static void linux_params_init (ulong start, char * commandline); +static void linux_env_set (char * env_name, char * env_val); + + +void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], + image_header_t *hdr, int verify) +{ + ulong rd_data, rd_len; + ulong initrd_start, initrd_end; + image_header_t *rd_hdr; + + void (*theKernel) (int, char **, char **, int *); + char *commandline = getenv ("bootargs"); + char env_buf[12]; + + theKernel = + (void (*)(int, char **, char **, int *))image_get_ep (hdr); + + /* + * Check if there is an initrd image + */ + if (argc >= 3) { + show_boot_progress (9); + + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr); + + if (!image_check_magic (rd_hdr)) { + printf ("Bad Magic Number\n"); + show_boot_progress (-10); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_hcrc (rd_hdr)) { + printf ("Bad Header Checksum\n"); + show_boot_progress (-11); + do_reset (cmdtp, flag, argc, argv); + } + + show_boot_progress (10); + print_image_hdr (rd_hdr); + + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); + + if (verify) { + printf (" Verifying Checksum ... "); + if (!image_check_dcrc (rd_hdr)) { + printf ("Bad Data CRC\n"); + show_boot_progress (-12); + do_reset (cmdtp, flag, argc, argv); + } + printf ("OK\n"); + } + + show_boot_progress (11); + + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_MIPS) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { + printf ("No Linux MIPS Ramdisk Image\n"); + show_boot_progress (-13); + do_reset (cmdtp, flag, argc, argv); + } + + /* + * Now check if we have a multifile image + */ + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ + show_boot_progress (13); + image_multi_getimg (hdr, 1, &rd_data, &rd_len); + } else { + /* + * no initrd image + */ + show_boot_progress (14); + + rd_data = rd_len = 0; + } + +#ifdef DEBUG + if (!rd_data) { + printf ("No initrd\n"); + } +#endif + + if (rd_data) { + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; + } else { + initrd_start = 0; + initrd_end = 0; + } + + show_boot_progress (15); + +#ifdef DEBUG + printf ("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) theKernel); +#endif + + linux_params_init (UNCACHED_SDRAM (gd->bd->bi_boot_params), commandline); + +#ifdef CONFIG_MEMSIZE_IN_BYTES + sprintf (env_buf, "%lu", gd->ram_size); +#ifdef DEBUG + printf ("## Giving linux memsize in bytes, %lu\n", gd->ram_size); +#endif +#else + sprintf (env_buf, "%lu", gd->ram_size >> 20); +#ifdef DEBUG + printf ("## Giving linux memsize in MB, %lu\n", gd->ram_size >> 20); +#endif +#endif /* CONFIG_MEMSIZE_IN_BYTES */ + + linux_env_set ("memsize", env_buf); + + sprintf (env_buf, "0x%08X", (uint) UNCACHED_SDRAM (initrd_start)); + linux_env_set ("initrd_start", env_buf); + + sprintf (env_buf, "0x%X", (uint) (initrd_end - initrd_start)); + linux_env_set ("initrd_size", env_buf); + + sprintf (env_buf, "0x%08X", (uint) (gd->bd->bi_flashstart)); + linux_env_set ("flash_start", env_buf); + + sprintf (env_buf, "0x%X", (uint) (gd->bd->bi_flashsize)); + linux_env_set ("flash_size", env_buf); + + /* we assume that the kernel is in place */ + printf ("\nStarting kernel ...\n\n"); + + theKernel (linux_argc, linux_argv, linux_env, 0); +} + +static void linux_params_init (ulong start, char *line) +{ + char *next, *quote, *argp; + + linux_argc = 1; + linux_argv = (char **) start; + linux_argv[0] = 0; + argp = (char *) (linux_argv + LINUX_MAX_ARGS); + + next = line; + + while (line && *line && linux_argc < LINUX_MAX_ARGS) { + quote = strchr (line, '"'); + next = strchr (line, ' '); + + while (next != NULL && quote != NULL && quote < next) { + /* we found a left quote before the next blank + * now we have to find the matching right quote + */ + next = strchr (quote + 1, '"'); + if (next != NULL) { + quote = strchr (next + 1, '"'); + next = strchr (next + 1, ' '); + } + } + + if (next == NULL) { + next = line + strlen (line); + } + + linux_argv[linux_argc] = argp; + memcpy (argp, line, next - line); + argp[next - line] = 0; + + argp += next - line + 1; + linux_argc++; + + if (*next) + next++; + + line = next; + } + + linux_env = (char **) (((ulong) argp + 15) & ~15); + linux_env[0] = 0; + linux_env_p = (char *) (linux_env + LINUX_MAX_ENVS); + linux_env_idx = 0; +} + +static void linux_env_set (char *env_name, char *env_val) +{ + if (linux_env_idx < LINUX_MAX_ENVS - 1) { + linux_env[linux_env_idx] = linux_env_p; + + strcpy (linux_env_p, env_name); + linux_env_p += strlen (env_name); + + strcpy (linux_env_p, "="); + linux_env_p += 1; + + strcpy (linux_env_p, env_val); + linux_env_p += strlen (env_val); + + linux_env_p++; + linux_env[++linux_env_idx] = 0; + } +} diff --git a/lib_mips/mips_linux.c b/lib_mips/mips_linux.c deleted file mode 100644 index 7ea7571..0000000 --- a/lib_mips/mips_linux.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * (C) Copyright 2003 - * 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 -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -#define LINUX_MAX_ENVS 256 -#define LINUX_MAX_ARGS 256 - -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - -static int linux_argc; -static char ** linux_argv; - -static char ** linux_env; -static char * linux_env_p; -static int linux_env_idx; - -static void linux_params_init (ulong start, char * commandline); -static void linux_env_set (char * env_name, char * env_val); - - -void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) -{ - ulong rd_data, rd_len; - ulong initrd_start, initrd_end; - image_header_t *rd_hdr; - - void (*theKernel) (int, char **, char **, int *); - char *commandline = getenv ("bootargs"); - char env_buf[12]; - - theKernel = - (void (*)(int, char **, char **, int *))image_get_ep (hdr); - - /* - * Check if there is an initrd image - */ - if (argc >= 3) { - show_boot_progress (9); - - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr); - - if (!image_check_magic (rd_hdr)) { - printf ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - printf ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - print_image_hdr (rd_hdr); - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - - if (verify) { - printf (" Verifying Checksum ... "); - if (!image_check_dcrc (rd_hdr)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - printf ("OK\n"); - } - - show_boot_progress (11); - - if (!image_check_os (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_MIPS) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - printf ("No Linux MIPS Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - show_boot_progress (13); - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - } else { - /* - * no initrd image - */ - show_boot_progress (14); - - rd_data = rd_len = 0; - } - -#ifdef DEBUG - if (!rd_data) { - printf ("No initrd\n"); - } -#endif - - if (rd_data) { - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - } else { - initrd_start = 0; - initrd_end = 0; - } - - show_boot_progress (15); - -#ifdef DEBUG - printf ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) theKernel); -#endif - - linux_params_init (UNCACHED_SDRAM (gd->bd->bi_boot_params), commandline); - -#ifdef CONFIG_MEMSIZE_IN_BYTES - sprintf (env_buf, "%lu", gd->ram_size); -#ifdef DEBUG - printf ("## Giving linux memsize in bytes, %lu\n", gd->ram_size); -#endif -#else - sprintf (env_buf, "%lu", gd->ram_size >> 20); -#ifdef DEBUG - printf ("## Giving linux memsize in MB, %lu\n", gd->ram_size >> 20); -#endif -#endif /* CONFIG_MEMSIZE_IN_BYTES */ - - linux_env_set ("memsize", env_buf); - - sprintf (env_buf, "0x%08X", (uint) UNCACHED_SDRAM (initrd_start)); - linux_env_set ("initrd_start", env_buf); - - sprintf (env_buf, "0x%X", (uint) (initrd_end - initrd_start)); - linux_env_set ("initrd_size", env_buf); - - sprintf (env_buf, "0x%08X", (uint) (gd->bd->bi_flashstart)); - linux_env_set ("flash_start", env_buf); - - sprintf (env_buf, "0x%X", (uint) (gd->bd->bi_flashsize)); - linux_env_set ("flash_size", env_buf); - - /* we assume that the kernel is in place */ - printf ("\nStarting kernel ...\n\n"); - - theKernel (linux_argc, linux_argv, linux_env, 0); -} - -static void linux_params_init (ulong start, char *line) -{ - char *next, *quote, *argp; - - linux_argc = 1; - linux_argv = (char **) start; - linux_argv[0] = 0; - argp = (char *) (linux_argv + LINUX_MAX_ARGS); - - next = line; - - while (line && *line && linux_argc < LINUX_MAX_ARGS) { - quote = strchr (line, '"'); - next = strchr (line, ' '); - - while (next != NULL && quote != NULL && quote < next) { - /* we found a left quote before the next blank - * now we have to find the matching right quote - */ - next = strchr (quote + 1, '"'); - if (next != NULL) { - quote = strchr (next + 1, '"'); - next = strchr (next + 1, ' '); - } - } - - if (next == NULL) { - next = line + strlen (line); - } - - linux_argv[linux_argc] = argp; - memcpy (argp, line, next - line); - argp[next - line] = 0; - - argp += next - line + 1; - linux_argc++; - - if (*next) - next++; - - line = next; - } - - linux_env = (char **) (((ulong) argp + 15) & ~15); - linux_env[0] = 0; - linux_env_p = (char *) (linux_env + LINUX_MAX_ENVS); - linux_env_idx = 0; -} - -static void linux_env_set (char *env_name, char *env_val) -{ - if (linux_env_idx < LINUX_MAX_ENVS - 1) { - linux_env[linux_env_idx] = linux_env_p; - - strcpy (linux_env_p, env_name); - linux_env_p += strlen (env_name); - - strcpy (linux_env_p, "="); - linux_env_p += 1; - - strcpy (linux_env_p, env_val); - linux_env_p += strlen (env_val); - - linux_env_p++; - linux_env[++linux_env_idx] = 0; - } -} diff --git a/lib_nios/Makefile b/lib_nios/Makefile index 7c9d62c..d8ae7bd 100644 --- a/lib_nios/Makefile +++ b/lib_nios/Makefile @@ -27,7 +27,7 @@ LIB = $(obj)lib$(ARCH).a SOBJS = -COBJS = board.o cache.o divmod.o nios_linux.o mult.o time.o +COBJS = board.o cache.o divmod.o bootm.o mult.o time.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/lib_nios/bootm.c b/lib_nios/bootm.c new file mode 100644 index 0000000..55f7e3a --- /dev/null +++ b/lib_nios/bootm.c @@ -0,0 +1,34 @@ +/* + * (C) Copyright 2003, Psyent Corporation + * Scott McNutt + * + * 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 +#include + +/* FIXME: Once we find a stable version of uC-linux for nios + * we can get this working. ;-) + * + */ +void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + image__header_t *hdr, int verify) +{ +} diff --git a/lib_nios/nios_linux.c b/lib_nios/nios_linux.c deleted file mode 100644 index 55f7e3a..0000000 --- a/lib_nios/nios_linux.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * (C) Copyright 2003, Psyent Corporation - * Scott McNutt - * - * 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 -#include - -/* FIXME: Once we find a stable version of uC-linux for nios - * we can get this working. ;-) - * - */ -void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image__header_t *hdr, int verify) -{ -} diff --git a/lib_nios2/Makefile b/lib_nios2/Makefile index 1ff2f29..5f996d3 100644 --- a/lib_nios2/Makefile +++ b/lib_nios2/Makefile @@ -27,7 +27,7 @@ LIB = $(obj)lib$(ARCH).a SOBJS = cache.o -COBJS = board.o divmod.o nios_linux.o mult.o time.o +COBJS = board.o divmod.o bootm.o mult.o time.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/lib_nios2/bootm.c b/lib_nios2/bootm.c new file mode 100644 index 0000000..cb84324 --- /dev/null +++ b/lib_nios2/bootm.c @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2003, Psyent Corporation + * Scott McNutt + * + * 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 +#include +#include + +void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + image_header_t *hdr, int verify) +{ + void (*kernel)(void) = (void (*)(void))image_get_ep (hdr); + + /* For now we assume the Microtronix linux ... which only + * needs to be called ;-) + */ + kernel (); +} diff --git a/lib_nios2/nios_linux.c b/lib_nios2/nios_linux.c deleted file mode 100644 index cb84324..0000000 --- a/lib_nios2/nios_linux.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * (C) Copyright 2003, Psyent Corporation - * Scott McNutt - * - * 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 -#include -#include - -void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) -{ - void (*kernel)(void) = (void (*)(void))image_get_ep (hdr); - - /* For now we assume the Microtronix linux ... which only - * needs to be called ;-) - */ - kernel (); -} diff --git a/lib_ppc/Makefile b/lib_ppc/Makefile index 2aa0154..6845ed0 100644 --- a/lib_ppc/Makefile +++ b/lib_ppc/Makefile @@ -29,7 +29,7 @@ SOBJS = ppcstring.o ticks.o COBJS = board.o \ bat_rw.o cache.o extable.o kgdb.o time.o interrupts.o \ - ppc_linux.o + bootm.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c new file mode 100644 index 0000000..3911687 --- /dev/null +++ b/lib_ppc/bootm.c @@ -0,0 +1,554 @@ +/* + * (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 + */ + +#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_OF_LIBFDT) +#include +#include +#include +#elif defined(CONFIG_OF_FLAT_TREE) +#include +#endif + +#ifdef CONFIG_LOGBUFFER +#include +#endif + +#ifdef CFG_INIT_RAM_LOCK +#include +#endif + +DECLARE_GLOBAL_DATA_PTR; + +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +#if defined(CONFIG_CMD_BDI) +extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +#endif + +void __attribute__((noinline)) +do_bootm_linux(cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + image_header_t *hdr, + int verify) +{ + ulong initrd_high; + int initrd_copy_to_ram = 1; + ulong initrd_start, initrd_end; + ulong rd_data, rd_len; + image_header_t *rd_hdr; + + ulong cmd_start, cmd_end; + char *cmdline; + + ulong sp; + char *s; + bd_t *kbd; + void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); + +#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) + image_header_t *fdt_hdr; + 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); + +#if defined(CONFIG_CMD_BDI) + do_bdinfo (NULL, 0, 0, NULL); +#endif +#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"); + rd_len = rd_data = 0; + } + else +#endif + if (argc >= 3) { + debug ("Not skipping initrd\n"); + show_boot_progress (9); + + rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); + printf ("## Loading RAMDisk Image at %08lx ...\n", (ulong)rd_hdr); + + if (!image_check_magic (rd_hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-10); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_hcrc (rd_hdr)) { + puts ("Bad Header Checksum\n"); + show_boot_progress (-11); + do_reset (cmdtp, flag, argc, argv); + } + show_boot_progress (10); + + print_image_hdr (rd_hdr); + + if (verify) { + puts (" Verifying Checksum ... "); + + if (!image_check_dcrc_wd (rd_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 (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, IH_ARCH_PPC) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { + puts ("No Linux PPC Ramdisk Image\n"); + show_boot_progress (-13); + do_reset (cmdtp, flag, argc, argv); + } + + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); + + /* + * Now check if we have a multifile image + */ + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Get second entry data start address and len + */ + image_multi_getimg (hdr, 1, &rd_data, &rd_len); + show_boot_progress (13); + } else { + /* + * No initrd image + */ + show_boot_progress (14); + + rd_len = rd_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); + fdt_hdr = (image_header_t *)of_flat_tree; +#if defined(CONFIG_OF_FLAT_TREE) + if (*((ulong *)(of_flat_tree)) == OF_DT_HEADER) { +#elif defined(CONFIG_OF_LIBFDT) + if (fdt_check_header (of_flat_tree) == 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 (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); + + 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); + } + + puts (" Verifying Checksum ... "); + if (!image_check_hcrc (fdt_hdr)) { + puts ("ERROR: fdt header checksum invalid - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_dcrc (fdt_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 (fdt_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 (fdt_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) { +#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 - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + + memmove ((void *)image_get_load (fdt_hdr), + (void *)(of_flat_tree + image_get_header_size ()), + image_get_data_size (fdt_hdr)); + + of_flat_tree = (char *)image_get_load (fdt_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)) { + ulong fdt_data, fdt_len; + + image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); + if (fdt_len) { + + of_flat_tree = (char *)fdt_data; + +#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) { +#elif defined(CONFIG_OF_LIBFDT) + 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 != fdt_len) { +#elif defined(CONFIG_OF_LIBFDT) + if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) { +#endif + puts ("ERROR: fdt size != image size - " + "must RESET the board to recover.\n"); + do_reset (cmdtp, flag, argc, argv); + } + } + } +#endif + if (!rd_data) { + debug ("No initrd\n"); + } + + if (rd_data) { + if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ + initrd_start = rd_data; + initrd_end = initrd_start + rd_len; + } else { + initrd_start = (ulong)kbd - rd_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 -= rd_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", + rd_data, rd_data + rd_len - 1, rd_len, rd_len); + + initrd_end = initrd_start + rd_len; + printf (" Loading Ramdisk to %08lx, end %08lx ... ", + initrd_start, initrd_end); + + memmove_wd((void *)initrd_start, + (void *)rd_data, rd_len, CHUNKSZ); + + 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 + } + +#elif 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 /* #if defined(CONFIG_OF_LIBFDT) #elif defined(CONFIG_OF_FLAT_TREE) */ + + 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 */ +} diff --git a/lib_ppc/ppc_linux.c b/lib_ppc/ppc_linux.c deleted file mode 100644 index 3911687..0000000 --- a/lib_ppc/ppc_linux.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * (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 - */ - -#define DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_OF_LIBFDT) -#include -#include -#include -#elif defined(CONFIG_OF_FLAT_TREE) -#include -#endif - -#ifdef CONFIG_LOGBUFFER -#include -#endif - -#ifdef CFG_INIT_RAM_LOCK -#include -#endif - -DECLARE_GLOBAL_DATA_PTR; - -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - -#if defined(CONFIG_CMD_BDI) -extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); -#endif - -void __attribute__((noinline)) -do_bootm_linux(cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - image_header_t *hdr, - int verify) -{ - ulong initrd_high; - int initrd_copy_to_ram = 1; - ulong initrd_start, initrd_end; - ulong rd_data, rd_len; - image_header_t *rd_hdr; - - ulong cmd_start, cmd_end; - char *cmdline; - - ulong sp; - char *s; - bd_t *kbd; - void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); - -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - image_header_t *fdt_hdr; - 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); - -#if defined(CONFIG_CMD_BDI) - do_bdinfo (NULL, 0, 0, NULL); -#endif -#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"); - rd_len = rd_data = 0; - } - else -#endif - if (argc >= 3) { - debug ("Not skipping initrd\n"); - show_boot_progress (9); - - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading RAMDisk Image at %08lx ...\n", (ulong)rd_hdr); - - if (!image_check_magic (rd_hdr)) { - puts ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - show_boot_progress (10); - - print_image_hdr (rd_hdr); - - if (verify) { - puts (" Verifying Checksum ... "); - - if (!image_check_dcrc_wd (rd_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 (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_PPC) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - puts ("No Linux PPC Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - show_boot_progress (13); - } else { - /* - * No initrd image - */ - show_boot_progress (14); - - rd_len = rd_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); - fdt_hdr = (image_header_t *)of_flat_tree; -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree)) == OF_DT_HEADER) { -#elif defined(CONFIG_OF_LIBFDT) - if (fdt_check_header (of_flat_tree) == 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 (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); - - 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); - } - - puts (" Verifying Checksum ... "); - if (!image_check_hcrc (fdt_hdr)) { - puts ("ERROR: fdt header checksum invalid - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_dcrc (fdt_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 (fdt_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 (fdt_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) { -#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 - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - - memmove ((void *)image_get_load (fdt_hdr), - (void *)(of_flat_tree + image_get_header_size ()), - image_get_data_size (fdt_hdr)); - - of_flat_tree = (char *)image_get_load (fdt_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)) { - ulong fdt_data, fdt_len; - - image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); - if (fdt_len) { - - of_flat_tree = (char *)fdt_data; - -#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) { -#elif defined(CONFIG_OF_LIBFDT) - 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 != fdt_len) { -#elif defined(CONFIG_OF_LIBFDT) - if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) { -#endif - puts ("ERROR: fdt size != image size - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - } - } -#endif - if (!rd_data) { - debug ("No initrd\n"); - } - - if (rd_data) { - if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - } else { - initrd_start = (ulong)kbd - rd_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 -= rd_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", - rd_data, rd_data + rd_len - 1, rd_len, rd_len); - - initrd_end = initrd_start + rd_len; - printf (" Loading Ramdisk to %08lx, end %08lx ... ", - initrd_start, initrd_end); - - memmove_wd((void *)initrd_start, - (void *)rd_data, rd_len, CHUNKSZ); - - 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 - } - -#elif 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 /* #if defined(CONFIG_OF_LIBFDT) #elif defined(CONFIG_OF_FLAT_TREE) */ - - 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 */ -} diff --git a/lib_sh/Makefile b/lib_sh/Makefile index cf127a8..edb03d0 100644 --- a/lib_sh/Makefile +++ b/lib_sh/Makefile @@ -24,7 +24,7 @@ LIB = $(obj)lib$(ARCH).a SOBJS = -COBJS = board.o sh_linux.o # time.o +COBJS = board.o bootm.o # time.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/lib_sh/bootm.c b/lib_sh/bootm.c new file mode 100644 index 0000000..14b6815 --- /dev/null +++ b/lib_sh/bootm.c @@ -0,0 +1,74 @@ +/* + * (C) Copyright 2003 + * 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 +#include +#include + +extern image_header_t header; /* common/cmd_bootm.c */ + +/* The SH kernel reads arguments from the empty zero page at location + * 0 at the start of SDRAM. The following are copied from + * arch/sh/kernel/setup.c and may require tweaking if the kernel sources + * change. + */ +#define PARAM ((unsigned char *)CFG_SDRAM_BASE + 0x1000) + +#define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000)) +#define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004)) +#define ORIG_ROOT_DEV (*(unsigned long *) (PARAM+0x008)) +#define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c)) +#define INITRD_START (*(unsigned long *) (PARAM+0x010)) +#define INITRD_SIZE (*(unsigned long *) (PARAM+0x014)) +/* ... */ +#define COMMAND_LINE ((char *) (PARAM+0x100)) + +#define RAMDISK_IMAGE_START_MASK 0x07FF + +#ifdef CFG_DEBUG +static void hexdump (unsigned char *buf, int len) +{ + int i; + + for (i = 0; i < len; i++) { + if ((i % 16) == 0) + printf ("%s%08x: ", i ? "\n" : "", (unsigned int) &buf[i]); + printf ("%02x ", buf[i]); + } + printf ("\n"); +} +#endif + +void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + ulong addr, ulong *len_ptr, int verify) +{ + image_header_t *hdr = &header; + char *bootargs = getenv("bootargs"); + void (*kernel) (void) = (void (*)(void)) ntohl (hdr->ih_ep); + + /* Setup parameters */ + memset(PARAM, 0, 0x1000); /* Clear zero page */ + strcpy(COMMAND_LINE, bootargs); + + kernel(); +} diff --git a/lib_sh/sh_linux.c b/lib_sh/sh_linux.c deleted file mode 100644 index 14b6815..0000000 --- a/lib_sh/sh_linux.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * (C) Copyright 2003 - * 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 -#include -#include - -extern image_header_t header; /* common/cmd_bootm.c */ - -/* The SH kernel reads arguments from the empty zero page at location - * 0 at the start of SDRAM. The following are copied from - * arch/sh/kernel/setup.c and may require tweaking if the kernel sources - * change. - */ -#define PARAM ((unsigned char *)CFG_SDRAM_BASE + 0x1000) - -#define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000)) -#define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004)) -#define ORIG_ROOT_DEV (*(unsigned long *) (PARAM+0x008)) -#define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c)) -#define INITRD_START (*(unsigned long *) (PARAM+0x010)) -#define INITRD_SIZE (*(unsigned long *) (PARAM+0x014)) -/* ... */ -#define COMMAND_LINE ((char *) (PARAM+0x100)) - -#define RAMDISK_IMAGE_START_MASK 0x07FF - -#ifdef CFG_DEBUG -static void hexdump (unsigned char *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) { - if ((i % 16) == 0) - printf ("%s%08x: ", i ? "\n" : "", (unsigned int) &buf[i]); - printf ("%02x ", buf[i]); - } - printf ("\n"); -} -#endif - -void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) -{ - image_header_t *hdr = &header; - char *bootargs = getenv("bootargs"); - void (*kernel) (void) = (void (*)(void)) ntohl (hdr->ih_ep); - - /* Setup parameters */ - memset(PARAM, 0, 0x1000); /* Clear zero page */ - strcpy(COMMAND_LINE, bootargs); - - kernel(); -} -- cgit v0.10.2 From 82850f3d32a2661868ec6876bed7a22c55cef718 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:20:06 +0100 Subject: [new uImage] Use image API in SH do_bootm_linux() routine Introduce image handling API for lately added Hitachi SH architecture. Signed-off-by: Marian Balakowicz diff --git a/lib_sh/bootm.c b/lib_sh/bootm.c index 14b6815..4e5fe77 100644 --- a/lib_sh/bootm.c +++ b/lib_sh/bootm.c @@ -25,8 +25,6 @@ #include #include -extern image_header_t header; /* common/cmd_bootm.c */ - /* The SH kernel reads arguments from the empty zero page at location * 0 at the start of SDRAM. The following are copied from * arch/sh/kernel/setup.c and may require tweaking if the kernel sources @@ -60,11 +58,10 @@ static void hexdump (unsigned char *buf, int len) #endif void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) + image_header_t *hdr, int verify) { - image_header_t *hdr = &header; char *bootargs = getenv("bootargs"); - void (*kernel) (void) = (void (*)(void)) ntohl (hdr->ih_ep); + void (*kernel) (void) = (void (*)(void))image_get_ep (hdr); /* Setup parameters */ memset(PARAM, 0, 0x1000); /* Clear zero page */ -- cgit v0.10.2 From 4a2ad5ff6400698433dd7203d34939c3c9cc9bff Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:20:07 +0100 Subject: [new uImage] Remove OF_FLAT_TREE support from PPC bootm code Support for OF_FLAT_TREE is to be obsoleted in the near future, remove related code from the bootm routines. Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index f441e0e..3390be7 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -36,14 +36,6 @@ #include #include -#if defined(CONFIG_OF_LIBFDT) -#include -#include -#include -#elif defined(CONFIG_OF_FLAT_TREE) -#include -#endif - #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) #include #endif @@ -390,7 +382,7 @@ U_BOOT_CMD( "[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) +#if 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" "\tdevice-tree blob. To boot that kernel without an initrd image,\n" diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 3911687..16b2f38 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -39,8 +39,6 @@ #include #include #include -#elif defined(CONFIG_OF_FLAT_TREE) -#include #endif #ifdef CONFIG_LOGBUFFER @@ -79,7 +77,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, bd_t *kbd; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) +#if defined(CONFIG_OF_LIBFDT) image_header_t *fdt_hdr; char *of_flat_tree = NULL; ulong of_data = 0; @@ -175,7 +173,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, * Check if there is an initrd image */ -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) +#if 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"); @@ -247,15 +245,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, rd_len = rd_data = 0; } -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) +#if defined(CONFIG_OF_LIBFDT) if(argc > 3) { of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); fdt_hdr = (image_header_t *)of_flat_tree; -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree)) == OF_DT_HEADER) { -#elif defined(CONFIG_OF_LIBFDT) + if (fdt_check_header (of_flat_tree) == 0) { -#endif #ifndef CFG_NO_FLASH if (addr2info((ulong)of_flat_tree) != NULL) of_data = (ulong)of_flat_tree; @@ -303,11 +298,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, "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) { -#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 - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); @@ -339,21 +330,13 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, of_data = (ulong)of_flat_tree; #endif -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { -#elif defined(CONFIG_OF_LIBFDT) 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 != fdt_len) { -#elif defined(CONFIG_OF_LIBFDT) if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) { -#endif puts ("ERROR: fdt size != image size - " "must RESET the board to recover.\n"); do_reset (cmdtp, flag, argc, argv); @@ -480,43 +463,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, ft_board_setup(of_flat_tree, gd->bd); #endif } - -#elif 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 /* #if defined(CONFIG_OF_LIBFDT) #elif defined(CONFIG_OF_FLAT_TREE) */ +#endif /* CONFIG_OF_LIBFDT */ debug ("## Transferring control to Linux (at address %08lx) ...\n", (ulong)kernel); @@ -527,7 +474,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, unlock_ram_in_cache(); #endif -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) +#if defined(CONFIG_OF_LIBFDT) if (of_flat_tree) { /* device tree; boot new style */ /* * Linux Kernel Parameters (passing device tree): -- cgit v0.10.2 From e99c26694a384221d336f6448c06a57479c0baa4 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:20:07 +0100 Subject: [new uImage] Remove standalone applications handling from boootm Standalone applications are supposed to be run using the "go" command. This patch removes standalone images handling from the do_bootm(). Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 3390be7..2705a5d 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -116,8 +116,7 @@ ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong iflag; - char *name, *s; - int (*appl)(int, char *[]); + char *name; uint unc_len = CFG_BOOTM_LEN; int verify = getenv_verify(); @@ -189,13 +188,6 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) 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) { - image_set_load (hdr, simple_strtoul (argv[2], NULL, 16)); - } - break; case IH_TYPE_KERNEL: name = "Kernel Image"; os_data = image_get_data (hdr); @@ -298,34 +290,6 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) do_reset (cmdtp, flag, argc, argv); } - switch (image_get_type (hdr)) { - case IH_TYPE_STANDALONE: - if (iflag) - enable_interrupts(); - - /* load (and uncompress), but don't start if "autostart" - * is set to "no" - */ - if (((s = getenv("autostart")) != NULL) && (strcmp(s,"no") == 0)) { - char buf[32]; - sprintf(buf, "%lX", image_get_data_size(hdr)); - setenv("filesize", buf); - return 0; - } - appl = (int (*)(int, char *[]))image_get_ep (hdr); - (*appl)(argc-1, &argv[1]); - return 0; - case IH_TYPE_KERNEL: - case IH_TYPE_MULTI: - /* handled below */ - break; - default: - if (iflag) - enable_interrupts(); - printf ("Can't boot image type %d\n", image_get_type (hdr)); - show_boot_progress (-8); - return 1; - } show_boot_progress (8); switch (image_get_os (hdr)) { -- cgit v0.10.2 From 42b73e8ee00d48004791dea64b8093fb974c57e1 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:20:07 +0100 Subject: [new uImage] Factor out common routines for getting os/arch/type/comp names Move numeric-id to name translation for image os/arch/type/comp header fields to a helper routines: image_get_os_name(), image_get_arch_name(), image_get_type_name(), image_get_comp_name(). Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 2705a5d..8b6616b 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -116,7 +116,7 @@ ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong iflag; - char *name; + const char *type_name; uint unc_len = CFG_BOOTM_LEN; int verify = getenv_verify(); @@ -189,12 +189,10 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) switch (image_get_type (hdr)) { case IH_TYPE_KERNEL: - name = "Kernel Image"; os_data = image_get_data (hdr); os_len = image_get_data_size (hdr); break; case IH_TYPE_MULTI: - name = "Multi-File Image"; image_multi_getimg (hdr, 0, &os_data, &os_len); break; default: @@ -222,6 +220,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) dcache_disable(); #endif + type_name = image_get_type_name (image_get_type (hdr)); + image_start = (ulong)hdr; image_end = image_get_image_end (hdr); load_start = image_get_load (hdr); @@ -230,9 +230,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) == img_addr) { - printf (" XIP %s ... ", name); + printf (" XIP %s ... ", type_name); } else { - printf (" Loading %s ... ", name); + printf (" Loading %s ... ", type_name); memmove_wd ((void *)image_get_load (hdr), (void *)os_data, os_len, CHUNKSZ); @@ -242,7 +242,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } break; case IH_COMP_GZIP: - printf (" Uncompressing %s ... ", name); + printf (" Uncompressing %s ... ", type_name); if (gunzip ((void *)image_get_load (hdr), unc_len, (uchar *)os_data, &os_len) != 0) { puts ("GUNZIP ERROR - must RESET board to recover\n"); @@ -254,7 +254,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; #ifdef CONFIG_BZIP2 case IH_COMP_BZIP2: - printf (" Uncompressing %s ... ", name); + printf (" Uncompressing %s ... ", type_name); /* * If we've got less than 4 MB of malloc() space, * use slower decompression algorithm which requires @@ -544,65 +544,12 @@ void print_image_hdr (image_header_t *hdr) static void print_type (image_header_t *hdr) { - char *os, *arch, *type, *comp; - - switch (image_get_os (hdr)) { - case IH_OS_INVALID: os = "Invalid OS"; break; - case IH_OS_NETBSD: os = "NetBSD"; break; - case IH_OS_LINUX: os = "Linux"; break; - case IH_OS_VXWORKS: os = "VxWorks"; break; - case IH_OS_QNX: os = "QNX"; break; - case IH_OS_U_BOOT: os = "U-Boot"; break; - case IH_OS_RTEMS: os = "RTEMS"; break; -#ifdef CONFIG_ARTOS - case IH_OS_ARTOS: os = "ARTOS"; break; -#endif -#ifdef CONFIG_LYNXKDI - case IH_OS_LYNXOS: os = "LynxOS"; break; -#endif - default: os = "Unknown OS"; break; - } + const char *os, *arch, *type, *comp; - switch (image_get_arch (hdr)) { - case IH_ARCH_INVALID: arch = "Invalid CPU"; break; - case IH_ARCH_ALPHA: arch = "Alpha"; break; - case IH_ARCH_ARM: arch = "ARM"; break; - case IH_ARCH_AVR32: arch = "AVR32"; break; - case IH_ARCH_BLACKFIN: arch = "Blackfin"; break; - case IH_ARCH_I386: arch = "Intel x86"; break; - case IH_ARCH_IA64: arch = "IA64"; break; - case IH_ARCH_M68K: arch = "M68K"; break; - case IH_ARCH_MICROBLAZE:arch = "Microblaze"; break; - case IH_ARCH_MIPS64: arch = "MIPS 64 Bit"; break; - case IH_ARCH_MIPS: arch = "MIPS"; break; - case IH_ARCH_NIOS2: arch = "Nios-II"; break; - case IH_ARCH_NIOS: arch = "Nios"; break; - case IH_ARCH_PPC: arch = "PowerPC"; break; - case IH_ARCH_S390: arch = "IBM S390"; break; - case IH_ARCH_SH: arch = "SuperH"; break; - case IH_ARCH_SPARC64: arch = "SPARC 64 Bit"; break; - case IH_ARCH_SPARC: arch = "SPARC"; break; - default: arch = "Unknown Architecture"; break; - } - - switch (image_get_type (hdr)) { - case IH_TYPE_INVALID: type = "Invalid Image"; break; - case IH_TYPE_STANDALONE:type = "Standalone Program"; break; - case IH_TYPE_KERNEL: type = "Kernel Image"; break; - case IH_TYPE_RAMDISK: type = "RAMDisk Image"; break; - case IH_TYPE_MULTI: type = "Multi-File Image"; break; - case IH_TYPE_FIRMWARE: type = "Firmware"; break; - case IH_TYPE_SCRIPT: type = "Script"; break; - case IH_TYPE_FLATDT: type = "Flat Device Tree"; break; - default: type = "Unknown Image"; break; - } - - switch (image_get_comp (hdr)) { - case IH_COMP_NONE: comp = "uncompressed"; break; - case IH_COMP_GZIP: comp = "gzip compressed"; break; - case IH_COMP_BZIP2: comp = "bzip2 compressed"; break; - default: comp = "unknown compression"; break; - } + os = image_get_os_name (image_get_os (hdr)); + arch = image_get_arch_name (image_get_arch (hdr)); + type = image_get_type_name (image_get_type (hdr)); + comp = image_get_comp_name (image_get_comp (hdr)); printf ("%s %s %s (%s)", arch, os, type, comp); } diff --git a/common/image.c b/common/image.c index 6eee83d..6726f03 100644 --- a/common/image.c +++ b/common/image.c @@ -193,3 +193,91 @@ void image_multi_getimg (image_header_t *hdr, ulong idx, *data = 0; } } + +#ifndef USE_HOSTCC +const char* image_get_os_name (uint8_t os) +{ + const char *name; + + switch (os) { + case IH_OS_INVALID: name = "Invalid OS"; break; + case IH_OS_NETBSD: name = "NetBSD"; break; + case IH_OS_LINUX: name = "Linux"; break; + case IH_OS_VXWORKS: name = "VxWorks"; break; + case IH_OS_QNX: name = "QNX"; break; + case IH_OS_U_BOOT: name = "U-Boot"; break; + case IH_OS_RTEMS: name = "RTEMS"; break; +#ifdef CONFIG_ARTOS + case IH_OS_ARTOS: name = "ARTOS"; break; +#endif +#ifdef CONFIG_LYNXKDI + case IH_OS_LYNXOS: name = "LynxOS"; break; +#endif + default: name = "Unknown OS"; break; + } + + return name; +} + +const char* image_get_arch_name (uint8_t arch) +{ + const char *name; + + switch (arch) { + case IH_ARCH_INVALID: name = "Invalid Architecture"; break; + case IH_ARCH_ALPHA: name = "Alpha"; break; + case IH_ARCH_ARM: name = "ARM"; break; + case IH_ARCH_AVR32: name = "AVR32"; break; + case IH_ARCH_BLACKFIN: name = "Blackfin"; break; + case IH_ARCH_I386: name = "Intel x86"; break; + case IH_ARCH_IA64: name = "IA64"; break; + case IH_ARCH_M68K: name = "M68K"; break; + case IH_ARCH_MICROBLAZE:name = "Microblaze"; break; + case IH_ARCH_MIPS64: name = "MIPS 64 Bit"; break; + case IH_ARCH_MIPS: name = "MIPS"; break; + case IH_ARCH_NIOS2: name = "Nios-II"; break; + case IH_ARCH_NIOS: name = "Nios"; break; + case IH_ARCH_PPC: name = "PowerPC"; break; + case IH_ARCH_S390: name = "IBM S390"; break; + case IH_ARCH_SH: name = "SuperH"; break; + case IH_ARCH_SPARC64: name = "SPARC 64 Bit"; break; + case IH_ARCH_SPARC: name = "SPARC"; break; + default: name = "Unknown Architecture"; break; + } + + return name; +} + +const char* image_get_type_name (uint8_t type) +{ + const char *name; + + switch (type) { + case IH_TYPE_INVALID: name = "Invalid Image"; break; + case IH_TYPE_STANDALONE:name = "Standalone Program"; break; + case IH_TYPE_KERNEL: name = "Kernel Image"; break; + case IH_TYPE_RAMDISK: name = "RAMDisk Image"; break; + case IH_TYPE_MULTI: name = "Multi-File Image"; break; + case IH_TYPE_FIRMWARE: name = "Firmware"; break; + case IH_TYPE_SCRIPT: name = "Script"; break; + case IH_TYPE_FLATDT: name = "Flat Device Tree"; break; + default: name = "Unknown Image"; break; + } + + return name; +} + +const char* image_get_comp_name (uint8_t comp) +{ + const char *name; + + switch (comp) { + case IH_COMP_NONE: name = "uncompressed"; break; + case IH_COMP_GZIP: name = "gzip compressed"; break; + case IH_COMP_BZIP2: name = "bzip2 compressed"; break; + default: name = "unknown compression"; break; + } + + return name; +} +#endif diff --git a/include/image.h b/include/image.h index c605d66..9ac25c9 100644 --- a/include/image.h +++ b/include/image.h @@ -290,6 +290,10 @@ static inline int image_check_os (image_header_t *hdr, uint8_t os) return (image_get_os (hdr) == os); } +ulong image_multi_count (image_header_t *hdr); +void image_multi_getimg (image_header_t *hdr, ulong idx, + ulong *data, ulong *len); + #ifndef USE_HOSTCC static inline int image_check_target_arch (image_header_t *hdr) { @@ -322,10 +326,11 @@ static inline int image_check_target_arch (image_header_t *hdr) return 1; } -#endif -ulong image_multi_count (image_header_t *hdr); -void image_multi_getimg (image_header_t *hdr, ulong idx, - ulong *data, ulong *len); +const char* image_get_os_name (uint8_t os); +const char* image_get_arch_name (uint8_t arch); +const char* image_get_type_name (uint8_t type); +const char* image_get_comp_name (uint8_t comp); +#endif /* USE_HOSTCCa */ #endif /* __IMAGE_H__ */ -- cgit v0.10.2 From d3c5eb6dd1f4ed3c3388386cf1d1bf82aa51d56b Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:20:08 +0100 Subject: [new uImage] Move FDT error printing to common fdt_error() routine FDT error handling in PPC do_bootm_linux() shares the same message format. This patch moves error message printing to a helper fdt_error() routine. Signed-off-by: Marian Balakowicz Acked-by: Gerald Van Baren diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 16b2f38..36e6776 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -39,6 +39,8 @@ #include #include #include + +static void fdt_error (const char *msg); #endif #ifdef CONFIG_LOGBUFFER @@ -269,38 +271,32 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, 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"); + fdt_error ("fdt overwritten"); do_reset (cmdtp, flag, argc, argv); } puts (" Verifying Checksum ... "); if (!image_check_hcrc (fdt_hdr)) { - puts ("ERROR: fdt header checksum invalid - " - "must RESET the board to recover.\n"); + fdt_error ("fdt header checksum invalid"); do_reset (cmdtp, flag, argc, argv); } if (!image_check_dcrc (fdt_hdr)) { - puts ("ERROR: fdt checksum invalid - " - "must RESET the board to recover.\n"); + fdt_error ("fdt checksum invalid"); do_reset (cmdtp, flag, argc, argv); } puts ("OK\n"); if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { - puts ("ERROR: uImage is not a fdt - " - "must RESET the board to recover.\n"); + fdt_error ("uImage is not a fdt"); do_reset (cmdtp, flag, argc, argv); } if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { - puts ("ERROR: uImage is compressed - " - "must RESET the board to recover.\n"); + fdt_error ("uImage is compressed"); do_reset (cmdtp, flag, argc, argv); } if (fdt_check_header (of_flat_tree + image_get_header_size ()) != 0) { - puts ("ERROR: uImage data is not a fdt - " - "must RESET the board to recover.\n"); + fdt_error ("uImage data is not a fdt"); do_reset (cmdtp, flag, argc, argv); } @@ -310,8 +306,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, of_flat_tree = (char *)image_get_load (fdt_hdr); } else { - puts ("Did not find a flat Flat Device Tree.\n" - "Must RESET the board to recover.\n"); + fdt_error ("Did not find a Flattened Device Tree"); do_reset (cmdtp, flag, argc, argv); } printf (" Booting using the fdt at 0x%x\n", @@ -331,14 +326,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, #endif if (fdt_check_header (of_flat_tree) != 0) { - puts ("ERROR: image is not a fdt - " - "must RESET the board to recover.\n"); + fdt_error ("image is not a fdt"); do_reset (cmdtp, flag, argc, argv); } if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) { - puts ("ERROR: fdt size != image size - " - "must RESET the board to recover.\n"); + fdt_error ("fdt size != image size"); do_reset (cmdtp, flag, argc, argv); } } @@ -428,8 +421,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, 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"); + fdt_error ("fdt move failed"); do_reset (cmdtp, flag, argc, argv); } puts ("OK\n"); @@ -440,21 +432,18 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, */ 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"); + fdt_error ("/chosen node create failed"); 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"); + fdt_error ("/u-boot-env node create failed"); 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"); + fdt_error ("/bd_t node create failed"); do_reset (cmdtp, flag, argc, argv); } #endif @@ -499,3 +488,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); /* does not return */ } + +#if defined(CONFIG_OF_LIBFDT) +static void fdt_error (const char *msg) +{ + puts ("ERROR: "); + puts (msg); + puts (" - must RESET the board to recover.\n"); +} +#endif -- cgit v0.10.2 From 5ad03eb3854c162684222a718b44c0716ea0db03 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:55:39 +0100 Subject: [new uImage] Factor out common image_get_ramdisk() routine Architecture specific do_bootm_linux() routines share common ramdisk image processing code. Move this code to a common helper routine. Signed-off-by: Marian Balakowicz diff --git a/common/image.c b/common/image.c index 6726f03..e4be4ca 100644 --- a/common/image.c +++ b/common/image.c @@ -23,10 +23,20 @@ * MA 02111-1307 USA */ #ifndef USE_HOSTCC -# include -# include +#include +#include + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +#include +#endif + +#ifdef CONFIG_HAS_DATAFLASH +#include +#endif + +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #else -# include "mkimage.h" +#include "mkimage.h" #endif #include @@ -280,4 +290,191 @@ const char* image_get_comp_name (uint8_t comp) return name; } + +/** + * image_get_ramdisk - get and verify ramdisk image + * @cmdtp: command table pointer + * @flag: command flag + * @argc: command argument count + * @argv: command argument list + * @rd_addr: ramdisk image start address + * @arch: expected ramdisk architecture + * @verify: checksum verification flag + * + * image_get_ramdisk() returns a pointer to the verified ramdisk image + * header. Routine receives image start address and expected architecture + * flag. Verification done covers data and header integrity and os/type/arch + * fields checking. + * + * If dataflash support is enabled routine checks for dataflash addresses + * and handles required dataflash reads. + * + * returns: + * pointer to a ramdisk image header, if image was found and valid + * otherwise, board is reset + */ +image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong rd_addr, uint8_t arch, int verify) +{ + image_header_t *rd_hdr; + + show_boot_progress (9); + +#ifdef CONFIG_HAS_DATAFLASH + if (addr_dataflash (rd_addr)) { + rd_hdr = (image_header_t *)CFG_LOAD_ADDR; + debug (" Reading Ramdisk image header from dataflash address " + "%08lx to %08lx\n", rd_addr, (ulong)rd_hdr); + read_dataflash (rd_addr, image_get_header_size (), + (char *)rd_hdr); + } else +#endif + rd_hdr = (image_header_t *)rd_addr; + + if (!image_check_magic (rd_hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-10); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_hcrc (rd_hdr)) { + puts ("Bad Header Checksum\n"); + show_boot_progress (-11); + do_reset (cmdtp, flag, argc, argv); + } + + show_boot_progress (10); + print_image_hdr (rd_hdr); + +#ifdef CONFIG_HAS_DATAFLASH + if (addr_dataflash (rd_addr)) { + debug (" Reading Ramdisk image data from dataflash address " + "%08lx to %08lx\n", rd_addr + image_get_header_size, + (ulong)image_get_data (rd_hdr)); + + read_dataflash (rd_addr + image_get_header_size (), + image_get_data_size (rd_hdr), + (char *)image_get_data (rd_hdr)); + } #endif + + if (verify) { + puts(" Verifying Checksum ... "); + if (!image_check_dcrc_wd (rd_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 (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, arch) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { + printf ("No Linux %s Ramdisk Image\n", + image_get_arch_name(arch)); + show_boot_progress (-13); + do_reset (cmdtp, flag, argc, argv); + } + + return rd_hdr; +} + +/** + * get_ramdisk - main ramdisk handling routine + * @cmdtp: command table pointer + * @flag: command flag + * @argc: command argument count + * @argv: command argument list + * @hdr: pointer to the posiibly multi componet kernel image + * @verify: checksum verification flag + * @arch: expected ramdisk architecture + * @rd_start: pointer to a ulong variable, will hold ramdisk start address + * @rd_end: pointer to a ulong variable, will hold ramdisk end + * + * get_ramdisk() is responsible for finding a valid ramdisk image. + * Curently supported are the following ramdisk sources: + * - multicomponent kernel/ramdisk image, + * - commandline provided address of decicated ramdisk image. + * + * returns: + * rd_start and rd_end are set to ramdisk start/end addresses if + * ramdisk image is found and valid + * rd_start and rd_end are set to 0 if no ramdisk exists + * board is reset if ramdisk image is found but corrupted + */ +void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + image_header_t *hdr, int verify, uint8_t arch, + ulong *rd_start, ulong *rd_end) +{ + ulong rd_addr; + ulong rd_data, rd_len; + image_header_t *rd_hdr; + + if (argc >= 3) { + /* + * Look for a '-' which indicates to ignore the + * ramdisk argument + */ + if (strcmp(argv[2], "-") == 0) { + debug ("## Skipping init Ramdisk\n"); + rd_len = rd_data = 0; + } else { + /* + * Check if there is an initrd image at the + * address provided in the second bootm argument + */ + rd_addr = simple_strtoul (argv[2], NULL, 16); + printf ("## Loading init Ramdisk Image at %08lx ...\n", + rd_addr); + + rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv, + rd_addr, arch, verify); + + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); + +#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO) + /* + *we need to copy the ramdisk to SRAM to let Linux boot + */ + memmove ((void *)image_get_load (rd_hdr), + (uchar *)rd_data, rd_len); + + rd_data = image_get_load (rd_hdr); +#endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */ + } + + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* + * Now check if we have a multifile image + * Get second entry data start address and len + */ + show_boot_progress (13); + printf ("## Loading init Ramdisk from multi component " + "Image at %08lx ...\n", (ulong)hdr); + image_multi_getimg (hdr, 1, &rd_data, &rd_len); + } else { + /* + * no initrd image + */ + show_boot_progress (14); + rd_len = rd_data = 0; + } + + if (!rd_data) { + debug ("## No init Ramdisk\n"); + *rd_start = 0; + *rd_end = 0; + } else { + *rd_start = rd_data; + *rd_end = rd_data + rd_len; + } + debug (" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n", + *rd_start, *rd_end); +} +#endif /* USE_HOSTCC */ + diff --git a/include/image.h b/include/image.h index 9ac25c9..b438564 100644 --- a/include/image.h +++ b/include/image.h @@ -34,6 +34,7 @@ #define __IMAGE_H__ #include +#include #ifndef USE_HOSTCC #include #endif @@ -331,6 +332,15 @@ const char* image_get_os_name (uint8_t os); const char* image_get_arch_name (uint8_t arch); const char* image_get_type_name (uint8_t type); const char* image_get_comp_name (uint8_t comp); + +image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong rd_addr, uint8_t arch, int verify); + +void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + image_header_t *hdr, int verify, uint8_t arch, + ulong *rd_start, ulong *rd_end); #endif /* USE_HOSTCCa */ + #endif /* __IMAGE_H__ */ diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index 4f9aae6..529b097 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -26,15 +26,9 @@ #include #include #include -#ifdef CONFIG_HAS_DATAFLASH -#include -#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_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ defined (CONFIG_INITRD_TAG) || \ @@ -69,10 +63,7 @@ static struct tag *params; void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], image_header_t *hdr, int verify) { - ulong rd_addr; - ulong rd_data, rd_len = 0; ulong initrd_start, initrd_end; - image_header_t *rd_hdr; void (*theKernel)(int zero, int arch, uint params); bd_t *bd = gd->bd; @@ -82,109 +73,8 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], theKernel = (void (*)(int, int, uint))image_get_ep (hdr); - /* - * Check if there is an initrd image - */ - if (argc >= 3) { - show_boot_progress (9); - - rd_addr = simple_strtoul (argv[2], NULL, 16); - printf ("## Loading Ramdisk Image at %08lx ...\n", rd_addr); - - /* Copy header so we can blank CRC field for re-calculation */ -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (rd_addr)) { - rd_hdr = (image_header_t *)CFG_LOAD_ADDR; - read_dataflash (rd_addr, image_get_header_size (), - (char *)rd_hdr); - } else -#endif - rd_hdr = (image_header_t *)rd_addr; - - if (!image_check_magic (rd_hdr)) { - printf ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - printf ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - - print_image_hdr (rd_hdr); - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (rd_addr)) - read_dataflash (rd_addr + image_get_header_size (), - rd_len, (char *)rd_data); -#endif - - if (verify) { - printf (" Verifying Checksum ... "); - if (!image_get_dcrc (rd_hdr)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - printf ("OK\n"); - } - - show_boot_progress (11); - - if (!image_check_os (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_ARM) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - printf ("No Linux ARM Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - -#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO) - /* - *we need to copy the ramdisk to SRAM to let Linux boot - */ - memmove ((void *)image_get_load (rd_hdr), (uchar *)rd_data, rd_len); - rd_data = image_get_load (rd_hdr); -#endif /* CONFIG_B2 || CONFIG_EVB4510 */ - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - show_boot_progress (13); - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - } else { - /* - * no initrd image - */ - show_boot_progress (14); - - rd_len = rd_data = 0; - } - -#ifdef DEBUG - if (!rd_data) { - printf ("No initrd\n"); - } -#endif - - if (rd_data) { - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - } else { - initrd_start = 0; - initrd_end = 0; - } + get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + IH_ARCH_ARM, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index 455590e..a934cae 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -31,8 +31,6 @@ DECLARE_GLOBAL_DATA_PTR; -extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - /* CPU-specific hook to allow flushing of caches, etc. */ extern void prepare_to_boot(void); @@ -176,9 +174,7 @@ static void setup_end_tag(struct tag *params) void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], image_header_t *hdr, int verify) { - ulong rd_data, rd_len = 0; ulong initrd_start, initrd_end; - image_header_t *rd_hdr; void (*theKernel)(int magic, void *tagtable); struct tag *params, *params_start; @@ -186,72 +182,8 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], theKernel = (void *)image_get_ep (hdr); - /* - * Check if there is an initrd image - */ - if (argc >= 3) { - show_boot_progress (9); - - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading RAMDISK image at %08lx ...\n", rd_hdr); - - if (!image_check_magic (rd_hdr)) { - puts("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset(cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - puts("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset(cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - print_image_hdr (rd_hdr); - - if (verify) { - puts(" Verifying Checksum ... "); - if (!image_check_dcrc (rd_hdr)) { - 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 (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_AVR32) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - puts("Not a Linux/AVR32 RAMDISK image\n"); - show_boot_progress (-13); - do_reset(cmdtp, flag, argc, argv); - } - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - show_boot_progress (13); - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - } else { - /* no initrd image */ - show_boot_progress (14); - rd_len = rd_data = 0; - } - - if (rd_data) { - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - } else { - initrd_start = 0; - initrd_end = 0; - } + get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + IH_ARCH_AVR32, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c index 27a2b0d..ab6c2a9 100644 --- a/lib_i386/bootm.c +++ b/lib_i386/bootm.c @@ -37,80 +37,10 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], void *base_ptr; ulong os_data, os_len; - ulong rd_data, rd_len; ulong initrd_start, initrd_end; - image_header_t *rd_hdr; - /* - * Check if there is an initrd image - */ - if (argc >= 3) { - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr); - - if (!image_check_magic (rd_hdr)) { - printf ("Bad Magic Number\n"); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - printf ("Bad Header Checksum\n"); - do_reset (cmdtp, flag, argc, argv); - } - - print_image_hdr (rd_hdr); - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - - if (verify) { - printf (" Verifying Checksum ... "); - if (!image_check_dcrc (rd_hdr)) { - printf ("Bad Data CRC\n"); - do_reset (cmdtp, flag, argc, argv); - } - printf ("OK\n"); - } - - if (!image_check_os (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_I386) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - printf ("No Linux i386 Ramdisk Image\n"); - do_reset (cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - } else { - /* - * no initrd image - */ - rd_data = rd_len = 0; - } - -#ifdef DEBUG - if (!rd_data) { - printf ("No initrd\n"); - } -#endif - - if (rd_data) { - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - printf (" Loading Ramdisk to %08lx, end %08lx ... ", - initrd_start, initrd_end); - memmove ((void *)initrd_start, (void *)rd_data, rd_len); - printf ("OK\n"); - } else { - initrd_start = 0; - initrd_end = 0; - } + get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + IH_ARCH_I386, &initrd_start, &initrd_end); /* if multi-part image, we need to advance base ptr */ if (image_check_type (hdr, IH_TYPE_MULTI)) { @@ -121,7 +51,7 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } base_ptr = load_zimage ((void*)os_data, os_len, - initrd_start, rd_len, 0); + initrd_start, initrd_end - initrd_start, 0); if (NULL == base_ptr) { printf ("## Kernel loading failed ...\n"); diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index b135556..dac5276 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -44,18 +44,15 @@ DECLARE_GLOBAL_DATA_PTR; # define SHOW_BOOT_PROGRESS(arg) #endif -int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], image_header_t *hdr, int verify) { ulong sp; - ulong rd_data, rd_len; + ulong rd_data_start, rd_data_end, rd_len; ulong initrd_high; ulong initrd_start, initrd_end; - image_header_t *rd_hdr; int initrd_copy_to_ram = 1; ulong cmd_start, cmd_end; @@ -132,82 +129,14 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); - /* - * Check if there is an initrd image - */ - - if (argc >= 3) { - debug("Not skipping initrd\n"); - SHOW_BOOT_PROGRESS(9); + get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + IH_ARCH_M68K, &rd_data_start, &rd_data_end); + rd_len = rd_data_end - rd_data_start; - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading RAMDisk Image at %08lx ...\n", rd_hdr); - - if (!image_check_magic (rd_hdr)) { - puts("Bad Magic Number\n"); - SHOW_BOOT_PROGRESS(-10); - do_reset(cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - puts("Bad Header Checksum\n"); - SHOW_BOOT_PROGRESS(-11); - do_reset(cmdtp, flag, argc, argv); - } - - SHOW_BOOT_PROGRESS(10); - - print_image_hdr (rd_hdr); - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - - if (verify) { - puts(" Verifying Checksum ... "); - if (!image_check_dcrc_wd (rd_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 (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_M68K) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - puts("No Linux ColdFire Ramdisk Image\n"); - SHOW_BOOT_PROGRESS(-13); - do_reset(cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - SHOW_BOOT_PROGRESS (13); - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - } else { - /* - * no initrd image - */ - SHOW_BOOT_PROGRESS(14); - - rd_len = rd_data = 0; - } - - if (!rd_data) { - debug("No initrd\n"); - } - - if (rd_data) { + if (rd_data_start) { if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; + initrd_start = rd_data_start; + initrd_end = rd_data_end; } else { initrd_start = (ulong) kbd - rd_len; initrd_start &= ~(4096 - 1); /* align on page */ @@ -245,14 +174,14 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - rd_data, rd_data + rd_len - 1, rd_len, rd_len); + rd_data_start, rd_data_end - 1, rd_len, rd_len); initrd_end = initrd_start + rd_len; printf(" Loading Ramdisk to %08lx, end %08lx ... ", initrd_start, initrd_end); memmove_wd((void *)initrd_start, - (void *)rd_data, rd_len, CHUNKSZ); + (void *)rd_data_start, rd_len, CHUNKSZ); puts("OK\n"); } diff --git a/lib_microblaze/bootm.c b/lib_microblaze/bootm.c index a4fce5a..1f3e777 100644 --- a/lib_microblaze/bootm.c +++ b/lib_microblaze/bootm.c @@ -32,17 +32,10 @@ DECLARE_GLOBAL_DATA_PTR; -extern int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); - void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], image_header_t *hdr, int verify) { - int i; - ulong checksum; - - ulong rd_data, rd_len; ulong initrd_start, initrd_end; - image_header_t *rd_hdr; /* First parameter is mapped to $r5 for kernel boot args */ void (*theKernel) (char *); @@ -50,82 +43,8 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], theKernel = (void (*)(char *))image_get_ep (hdr); - /* Check if there is an initrd image */ - if (argc >= 3) { - show_boot_progress (9); - - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr); - - if (!image_check_magic (rd_hdr)) { - printf ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_magic (rd_hdr)) { - printf ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - print_image_hdr (rd_hdr); - - rd_data = image_get_data (rd_hdr); - rd_en = image_get_data_size (rd_hdr); - - if (verify) { - printf (" Verifying Checksum ... "); - if (!image_check_dcrc (rd_hdr)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - printf ("OK\n"); - } - - show_boot_progress (11); - - if (!image_check_os (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_MICROBLAZE) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - printf ("No Linux Microblaze Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - show_boot_progress (13); - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - } else { - /* - * no initrd image - */ - show_boot_progress (14); - - rd_data = rd_len = 0; - } - -#ifdef DEBUG - if (!rd_data) { - printf ("No initrd\n"); - } -#endif - - if (rd_data) { - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - } else { - initrd_start = 0; - initrd_end = 0; - } + get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + IH_ARCH_MICROBLAZE, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c index 7ea7571..fb91c76 100644 --- a/lib_mips/bootm.c +++ b/lib_mips/bootm.c @@ -33,8 +33,6 @@ DECLARE_GLOBAL_DATA_PTR; #define LINUX_MAX_ENVS 256 #define LINUX_MAX_ARGS 256 -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - static int linux_argc; static char ** linux_argv; @@ -49,9 +47,7 @@ static void linux_env_set (char * env_name, char * env_val); void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], image_header_t *hdr, int verify) { - ulong rd_data, rd_len; ulong initrd_start, initrd_end; - image_header_t *rd_hdr; void (*theKernel) (int, char **, char **, int *); char *commandline = getenv ("bootargs"); @@ -60,84 +56,8 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], theKernel = (void (*)(int, char **, char **, int *))image_get_ep (hdr); - /* - * Check if there is an initrd image - */ - if (argc >= 3) { - show_boot_progress (9); - - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading Ramdisk Image at %08lx ...\n", rd_hdr); - - if (!image_check_magic (rd_hdr)) { - printf ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - printf ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - print_image_hdr (rd_hdr); - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - - if (verify) { - printf (" Verifying Checksum ... "); - if (!image_check_dcrc (rd_hdr)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - printf ("OK\n"); - } - - show_boot_progress (11); - - if (!image_check_os (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_MIPS) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - printf ("No Linux MIPS Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - show_boot_progress (13); - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - } else { - /* - * no initrd image - */ - show_boot_progress (14); - - rd_data = rd_len = 0; - } - -#ifdef DEBUG - if (!rd_data) { - printf ("No initrd\n"); - } -#endif - - if (rd_data) { - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; - } else { - initrd_start = 0; - initrd_end = 0; - } + get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + IH_ARCH_MIPS, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 36e6776..65edcdb 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -68,8 +68,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, ulong initrd_high; int initrd_copy_to_ram = 1; ulong initrd_start, initrd_end; - ulong rd_data, rd_len; - image_header_t *rd_hdr; + ulong rd_data_start, rd_data_end, rd_len; ulong cmd_start, cmd_end; char *cmdline; @@ -171,81 +170,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); - /* - * Check if there is an initrd image - */ - -#if 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"); - rd_len = rd_data = 0; - } - else -#endif - if (argc >= 3) { - debug ("Not skipping initrd\n"); - show_boot_progress (9); - - rd_hdr = (image_header_t *)simple_strtoul (argv[2], NULL, 16); - printf ("## Loading RAMDisk Image at %08lx ...\n", (ulong)rd_hdr); - - if (!image_check_magic (rd_hdr)) { - puts ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_hcrc (rd_hdr)) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - show_boot_progress (10); - - print_image_hdr (rd_hdr); - - if (verify) { - puts (" Verifying Checksum ... "); - - if (!image_check_dcrc_wd (rd_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 (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, IH_ARCH_PPC) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - puts ("No Linux PPC Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - - rd_data = image_get_data (rd_hdr); - rd_len = image_get_data_size (rd_hdr); - - /* - * Now check if we have a multifile image - */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { - /* - * Get second entry data start address and len - */ - image_multi_getimg (hdr, 1, &rd_data, &rd_len); - show_boot_progress (13); - } else { - /* - * No initrd image - */ - show_boot_progress (14); - - rd_len = rd_data = 0; - } + get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + IH_ARCH_PPC, &rd_data_start, &rd_data_end); + rd_len = rd_data_end - rd_data_start; #if defined(CONFIG_OF_LIBFDT) if(argc > 3) { @@ -337,14 +264,11 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, } } #endif - if (!rd_data) { - debug ("No initrd\n"); - } - if (rd_data) { + if (rd_data_start) { if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = rd_data; - initrd_end = initrd_start + rd_len; + initrd_start = rd_data_start; + initrd_end = rd_data_end; } else { initrd_start = (ulong)kbd - rd_len; initrd_start &= ~(4096 - 1); /* align on page */ @@ -376,14 +300,14 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, show_boot_progress (12); debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - rd_data, rd_data + rd_len - 1, rd_len, rd_len); + rd_data_start, rd_data_end - 1, rd_len, rd_len); initrd_end = initrd_start + rd_len; printf (" Loading Ramdisk to %08lx, end %08lx ... ", initrd_start, initrd_end); memmove_wd((void *)initrd_start, - (void *)rd_data, rd_len, CHUNKSZ); + (void *)rd_data_start, rd_len, CHUNKSZ); puts ("OK\n"); } -- cgit v0.10.2 From 68d4f05e6b2383a442fb71f80f2a9fbb3d8def68 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:55:53 +0100 Subject: [new uImage] Removed dead ramdisk code on microblaze architectures Microblaze do_bootm_linux() includes ramdisk processing code but the ramdisk does not get used anywhere later on. Signed-off-by: Marian Balakowicz diff --git a/lib_microblaze/bootm.c b/lib_microblaze/bootm.c index 1f3e777..bccfbe1 100644 --- a/lib_microblaze/bootm.c +++ b/lib_microblaze/bootm.c @@ -35,17 +35,12 @@ DECLARE_GLOBAL_DATA_PTR; void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], image_header_t *hdr, int verify) { - ulong initrd_start, initrd_end; - /* First parameter is mapped to $r5 for kernel boot args */ void (*theKernel) (char *); char *commandline = getenv ("bootargs"); theKernel = (void (*)(char *))image_get_ep (hdr); - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, - IH_ARCH_MICROBLAZE, &initrd_start, &initrd_end); - show_boot_progress (15); #ifdef DEBUG -- cgit v0.10.2 From ceaed2b1e54ebf14d600e02fef016c8df5cc4d40 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:57:17 +0100 Subject: [new uImage] Move ramdisk loading to a common routine Ramdisk loading code, including initrd_high variable handling, was duplicated for PPC and M68K platforms. This patch creates common helper routine that is being called from both platform do_bootm_linux() routines. Signed-off-by: Marian Balakowicz diff --git a/common/image.c b/common/image.c index e4be4ca..56d6b52 100644 --- a/common/image.c +++ b/common/image.c @@ -22,6 +22,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ + +#define DEBUG + #ifndef USE_HOSTCC #include #include @@ -34,6 +37,10 @@ #include #endif +#ifdef CONFIG_LOGBUFFER +#include +#endif + extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #else #include "mkimage.h" @@ -476,5 +483,111 @@ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], debug (" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n", *rd_start, *rd_end); } + +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +/** + * ramdisk_high - relocate init ramdisk + * @rd_data: ramdisk data start address + * @rd_len: ramdisk data length + * @kbd: kernel board info copy (within BOOTMAPSZ boundary) + * @sp_limit: stack pointer limit (including BOOTMAPSZ) + * @sp: current stack pointer + * @initrd_start: pointer to a ulong variable, will hold final init ramdisk + * start address (after possible relocation) + * @initrd_end: pointer to a ulong variable, will hold final init ramdisk + * end address (after possible relocation) + * + * ramdisk_high() takes a relocation hint from "initrd_high" environement + * variable and if requested ramdisk data is moved to a specified location. + * + * returns: + * initrd_start and initrd_end are set to final (after relocation) ramdisk + * start/end addresses if ramdisk image start and len were provided + * otherwise set initrd_start and initrd_end to zeros + * + */ +void ramdisk_high (ulong rd_data, ulong rd_len, bd_t *kbd, ulong sp_limit, + ulong sp, ulong *initrd_start, ulong *initrd_end) +{ + char *s; + ulong initrd_high; + int initrd_copy_to_ram = 1; + + 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 + /* 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 + debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n", + initrd_high, initrd_copy_to_ram); + + if (rd_data) { + if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ + debug (" in-place initrd\n"); + *initrd_start = rd_data; + *initrd_end = rd_data + rd_len; + } else { + *initrd_start = (ulong)kbd - rd_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 + * for command line args and board info. + */ + nsp = sp; + nsp -= 2048; /* just to be sure */ + nsp &= ~0xF; + + if (nsp > initrd_high) /* limit as specified */ + nsp = initrd_high; + + nsp -= rd_len; + nsp &= ~(4096 - 1); /* align on page */ + + if (nsp >= sp_limit) + *initrd_start = nsp; + } + + show_boot_progress (12); + + *initrd_end = *initrd_start + rd_len; + printf (" Loading Ramdisk to %08lx, end %08lx ... ", + *initrd_start, *initrd_end); + + memmove_wd((void *)*initrd_start, + (void *)rd_data, rd_len, CHUNKSZ); + + puts ("OK\n"); + } + } else { + *initrd_start = 0; + *initrd_end = 0; + } + debug (" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", + *initrd_start, *initrd_end); +} +#endif /* CONFIG_PPC || CONFIG_M68K */ #endif /* USE_HOSTCC */ diff --git a/include/image.h b/include/image.h index b438564..a8cb1da 100644 --- a/include/image.h +++ b/include/image.h @@ -37,6 +37,7 @@ #include #ifndef USE_HOSTCC #include +#include #endif /* @@ -340,7 +341,11 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], image_header_t *hdr, int verify, uint8_t arch, ulong *rd_start, ulong *rd_end); -#endif /* USE_HOSTCCa */ +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +void ramdisk_high (ulong rd_data_start, ulong rd_len, bd_t *kbd, ulong sp_limit, + ulong sp, ulong *initrd_start, ulong *initrd_end); +#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* USE_HOSTCC */ #endif /* __IMAGE_H__ */ diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index dac5276..3fd38e9 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -44,16 +44,16 @@ DECLARE_GLOBAL_DATA_PTR; # define SHOW_BOOT_PROGRESS(arg) #endif +static ulong get_sp (void); + void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], image_header_t *hdr, int verify) { - ulong sp; + ulong sp_limit; ulong rd_data_start, rd_data_end, rd_len; - ulong initrd_high; ulong initrd_start, initrd_end; - int initrd_copy_to_ram = 1; ulong cmd_start, cmd_end; char *cmdline; @@ -61,25 +61,6 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, bd_t *kbd; void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); - 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 * @@ -89,19 +70,18 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, * memory, which means far enough below the current stack * pointer. */ - asm("movel %%a7, %%d0\n" - "movel %%d0, %0\n": "=d"(sp): :"%d0"); + sp_limit = get_sp(); - debug("## Current stack ends at 0x%08lX ", sp); + debug("## Current stack ends at 0x%08lX ", sp_limit); - sp -= 2048; /* just to be sure */ - if (sp > CFG_BOOTMAPSZ) - sp = CFG_BOOTMAPSZ; - sp &= ~0xF; + sp_limit -= 2048; /* just to be sure */ + if (sp_limit > CFG_BOOTMAPSZ) + sp_limit = CFG_BOOTMAPSZ; + sp_limit &= ~0xF; - debug("=> set upper limit to 0x%08lX\n", sp); + debug("=> set upper limit to 0x%08lX\n", sp_limit); - cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF); + cmdline = (char *)((sp_limit - CFG_BARGSIZE) & ~0xF); kbd = (bd_t *) (((ulong) cmdline - sizeof(bd_t)) & ~0xF); if ((s = getenv("bootargs")) == NULL) @@ -126,69 +106,17 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, kbd->bi_busfreq /= 1000000L; } + /* find kernel */ kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); + /* find ramdisk */ get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, IH_ARCH_M68K, &rd_data_start, &rd_data_end); - rd_len = rd_data_end - rd_data_start; - if (rd_data_start) { - if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = rd_data_start; - initrd_end = rd_data_end; - } else { - initrd_start = (ulong) kbd - rd_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("movel %%a7, %%d0\n" - "movel %%d0, %0\n": "=d"(nsp): :"%d0"); - - nsp -= 2048; /* just to be sure */ - nsp &= ~0xF; - - if (nsp > initrd_high) /* limit as specified */ - nsp = initrd_high; - - nsp -= rd_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", - rd_data_start, rd_data_end - 1, rd_len, rd_len); - - initrd_end = initrd_start + rd_len; - printf(" Loading Ramdisk to %08lx, end %08lx ... ", - initrd_start, initrd_end); - - memmove_wd((void *)initrd_start, - (void *)rd_data_start, rd_len, CHUNKSZ); - - puts("OK\n"); - } - } else { - initrd_start = 0; - initrd_end = 0; - } + rd_len = rd_data_end - rd_data_start; + ramdisk_high (rd_data_start, rd_len, kdb, sp_limit, get_sp (), + &initrd_start, &initrd_end); debug("## Transferring control to Linux (at address %08lx) ...\n", (ulong) kernel); @@ -206,3 +134,13 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); /* does not return */ } + +static ulong get_sp (void) +{ + ulong sp; + + asm("movel %%a7, %%d0\n" + "movel %%d0, %0\n": "=d"(sp): :"%d0"); + + return sp; +} diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 65edcdb..d73d2fd 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -43,10 +43,6 @@ static void fdt_error (const char *msg); #endif -#ifdef CONFIG_LOGBUFFER -#include -#endif - #ifdef CFG_INIT_RAM_LOCK #include #endif @@ -54,9 +50,10 @@ static void fdt_error (const char *msg); DECLARE_GLOBAL_DATA_PTR; extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +static ulong get_sp (void); #if defined(CONFIG_CMD_BDI) -extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern int do_bdinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #endif void __attribute__((noinline)) @@ -65,15 +62,13 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, image_header_t *hdr, int verify) { - ulong initrd_high; - int initrd_copy_to_ram = 1; ulong initrd_start, initrd_end; ulong rd_data_start, rd_data_end, rd_len; ulong cmd_start, cmd_end; char *cmdline; - ulong sp; + ulong sp_limit; char *s; bd_t *kbd; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); @@ -84,25 +79,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, 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 * @@ -113,18 +89,17 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, * pointer. */ - asm( "mr %0,1": "=r"(sp) : ); - - debug ("## Current stack ends at 0x%08lX ", sp); + sp_limit = get_sp(); + debug ("## Current stack ends at 0x%08lX ", sp_limit); - sp -= 2048; /* just to be sure */ - if (sp > CFG_BOOTMAPSZ) - sp = CFG_BOOTMAPSZ; - sp &= ~0xF; + sp_limit -= 2048; /* just to be sure */ + if (sp_limit > CFG_BOOTMAPSZ) + sp_limit = CFG_BOOTMAPSZ; + sp_limit &= ~0xF; - debug ("=> set upper limit to 0x%08lX\n", sp); + debug ("=> set upper limit to 0x%08lX\n", sp_limit); - cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF); + cmdline = (char *)((sp_limit - CFG_BARGSIZE) & ~0xF); kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); if ((s = getenv("bootargs")) == NULL) @@ -168,13 +143,20 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, #endif /* CONFIG_MPC5xxx */ } + /* find kernel */ kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); + /* find ramdisk */ get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, IH_ARCH_PPC, &rd_data_start, &rd_data_end); + rd_len = rd_data_end - rd_data_start; + ramdisk_high (rd_data_start, rd_len, kbd, sp_limit, get_sp (), + &initrd_start, &initrd_end); + #if defined(CONFIG_OF_LIBFDT) + /* find flattened device tree */ if(argc > 3) { of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); fdt_hdr = (image_header_t *)of_flat_tree; @@ -265,56 +247,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, } #endif - if (rd_data_start) { - if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = rd_data_start; - initrd_end = rd_data_end; - } else { - initrd_start = (ulong)kbd - rd_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 -= rd_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", - rd_data_start, rd_data_end - 1, rd_len, rd_len); - - initrd_end = initrd_start + rd_len; - printf (" Loading Ramdisk to %08lx, end %08lx ... ", - initrd_start, initrd_end); - - memmove_wd((void *)initrd_start, - (void *)rd_data_start, rd_len, CHUNKSZ); - - puts ("OK\n"); - } - } else { - initrd_start = 0; - initrd_end = 0; - } #if defined(CONFIG_OF_LIBFDT) @@ -413,6 +345,14 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, /* does not return */ } +static ulong get_sp (void) +{ + ulong sp; + + asm( "mr %0,1": "=r"(sp) : ); + return sp; +} + #if defined(CONFIG_OF_LIBFDT) static void fdt_error (const char *msg) { -- cgit v0.10.2 From b6b0fe6460b7063ac60b9a3531ef210aedb31451 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:58:13 +0100 Subject: [new uImage] Cleanup do_botm_linux() boot allocations This patch moves common pre-boot allocation steps shared between PPC and M68K to a helper routines: common: - get_boot_sp_limit() - get_boot_cmline() - get_boot_kbd() platform: - set_clocks_in_mhz() Signed-off-by: Marian Balakowicz diff --git a/common/image.c b/common/image.c index 56d6b52..39e5f23 100644 --- a/common/image.c +++ b/common/image.c @@ -42,9 +42,15 @@ #endif extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +#ifdef CONFIG_CMD_BDI +extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +#endif + +DECLARE_GLOBAL_DATA_PTR; #else #include "mkimage.h" -#endif +#endif /* USE_HOSTCC*/ #include @@ -501,17 +507,19 @@ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * variable and if requested ramdisk data is moved to a specified location. * * returns: - * initrd_start and initrd_end are set to final (after relocation) ramdisk + * - initrd_start and initrd_end are set to final (after relocation) ramdisk * start/end addresses if ramdisk image start and len were provided - * otherwise set initrd_start and initrd_end to zeros - * + * otherwise set initrd_start and initrd_end set to zeros + * - returns new allc_current, next free address below BOOTMAPSZ */ -void ramdisk_high (ulong rd_data, ulong rd_len, bd_t *kbd, ulong sp_limit, - ulong sp, ulong *initrd_start, ulong *initrd_end) +ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, + bd_t *kbd, ulong sp_limit, ulong sp, + ulong *initrd_start, ulong *initrd_end) { char *s; ulong initrd_high; int initrd_copy_to_ram = 1; + ulong new_alloc_current = alloc_current; if ((s = getenv ("initrd_high")) != NULL) { /* a value of "no" or a similar string will act like 0, @@ -540,7 +548,8 @@ void ramdisk_high (ulong rd_data, ulong rd_len, bd_t *kbd, ulong sp_limit, *initrd_start = rd_data; *initrd_end = rd_data + rd_len; } else { - *initrd_start = (ulong)kbd - rd_len; + new_alloc_current = alloc_current - rd_len; + *initrd_start = new_alloc_current; *initrd_start &= ~(4096 - 1); /* align on page */ if (initrd_high) { @@ -566,8 +575,10 @@ void ramdisk_high (ulong rd_data, ulong rd_len, bd_t *kbd, ulong sp_limit, nsp -= rd_len; nsp &= ~(4096 - 1); /* align on page */ - if (nsp >= sp_limit) + if (nsp >= sp_limit) { *initrd_start = nsp; + new_alloc_current = alloc_current; + } } show_boot_progress (12); @@ -587,7 +598,96 @@ void ramdisk_high (ulong rd_data, ulong rd_len, bd_t *kbd, ulong sp_limit, } debug (" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", *initrd_start, *initrd_end); + + return new_alloc_current; +} + +/** + * get_boot_sp_limit - calculate stack pointer limit + * @sp: current stack pointer + * + * get_boot_sp_limit() takes current stack pointer adrress and calculates + * stack pointer limit, below which kernel boot data (cmdline, board info, + * etc.) will be allocated. + * + * returns: + * stack pointer limit + */ +ulong get_boot_sp_limit(ulong sp) +{ + ulong sp_limit = sp; + + sp_limit -= 2048; /* just to be sure */ + + /* make sure sp_limit is within kernel mapped space */ + if (sp_limit > CFG_BOOTMAPSZ) + sp_limit = CFG_BOOTMAPSZ; + sp_limit &= ~0xF; + + return sp_limit; +} + +/** + * get_boot_cmdline - allocate and initialize kernel cmdline + * @alloc_current: current boot allocation address (counting down + * from sp_limit) + * @cmd_start: pointer to a ulong variable, will hold cmdline start + * @cmd_end: pointer to a ulong variable, will hold cmdline end + * + * get_boot_cmdline() allocates space for kernel command line below + * provided alloc_current address. If "bootargs" U-boot environemnt + * variable is present its contents is copied to allocated kernel + * command line. + * + * returns: + * alloc_current after cmdline allocation + */ +ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end) +{ + char *cmdline; + char *s; + + cmdline = (char *)((alloc_current - CFG_BARGSIZE) & ~0xF); + + if ((s = getenv("bootargs")) == NULL) + s = ""; + + strcpy(cmdline, s); + + *cmd_start = (ulong) & cmdline[0]; + *cmd_end = *cmd_start + strlen(cmdline); + + debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end); + + return (ulong)cmdline; +} + +/** + * get_boot_kbd - allocate and initialize kernel copy of board info + * @alloc_current: current boot allocation address (counting down + * from sp_limit) + * @kbd: double pointer to board info data + * + * get_boot_kbd() - allocates space for kernel copy of board info data. + * Space is allocated below provided alloc_current address and kernel + * board info is initialized with the current u-boot board info data. + * + * returns: + * alloc_current after kbd allocation + */ +ulong get_boot_kbd (ulong alloc_current, bd_t **kbd) +{ + *kbd = (bd_t *) (((ulong)alloc_current - sizeof(bd_t)) & ~0xF); + **kbd = *(gd->bd); + + debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd); + +#if defined(DEBUG) && defined(CONFIG_CMD_BDI) + do_bdinfo(NULL, 0, 0, NULL); +#endif + + return (ulong)*kbd; } #endif /* CONFIG_PPC || CONFIG_M68K */ -#endif /* USE_HOSTCC */ +#endif /* USE_HOSTCC */ diff --git a/include/image.h b/include/image.h index a8cb1da..dbbbee9 100644 --- a/include/image.h +++ b/include/image.h @@ -343,9 +343,15 @@ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong *rd_start, ulong *rd_end); #if defined(CONFIG_PPC) || defined(CONFIG_M68K) -void ramdisk_high (ulong rd_data_start, ulong rd_len, bd_t *kbd, ulong sp_limit, - ulong sp, ulong *initrd_start, ulong *initrd_end); +ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, + bd_t *kbd, ulong sp_limit, ulong sp, + ulong *initrd_start, ulong *initrd_end); + +ulong get_boot_sp_limit (ulong sp); +ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end); +ulong get_boot_kbd (ulong alloc_current, bd_t **kbd); #endif /* CONFIG_PPC || CONFIG_M68K */ + #endif /* USE_HOSTCC */ #endif /* __IMAGE_H__ */ diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index 3fd38e9..ac04da0 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -29,6 +29,9 @@ #include #include #include +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -37,27 +40,19 @@ DECLARE_GLOBAL_DATA_PTR; #define LINUX_MAX_ENVS 256 #define LINUX_MAX_ARGS 256 -#ifdef CONFIG_SHOW_BOOT_PROGRESS -# include -# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) -#else -# define SHOW_BOOT_PROGRESS(arg) -#endif - static ulong get_sp (void); +static void set_clocks_in_mhz (bd_t *kbd); void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], image_header_t *hdr, int verify) { - ulong sp_limit; + ulong sp, sp_limit, alloc_current; ulong rd_data_start, rd_data_end, rd_len; ulong initrd_start, initrd_end; ulong cmd_start, cmd_end; - char *cmdline; - char *s; bd_t *kbd; void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); @@ -70,41 +65,18 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, * memory, which means far enough below the current stack * pointer. */ - sp_limit = get_sp(); - - debug("## Current stack ends at 0x%08lX ", sp_limit); - - sp_limit -= 2048; /* just to be sure */ - if (sp_limit > CFG_BOOTMAPSZ) - sp_limit = CFG_BOOTMAPSZ; - sp_limit &= ~0xF; - - debug("=> set upper limit to 0x%08lX\n", sp_limit); - - cmdline = (char *)((sp_limit - 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); + sp = get_sp(); + debug ("## Current stack ends at 0x%08lx ", sp); -#ifdef DEBUG - printf("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); + alloc_current = sp_limit = get_boot_sp_limit(sp); + debug ("=> set upper limit to 0x%08lx\n", sp_limit); - do_bdinfo(NULL, 0, 0, NULL); -#endif + /* allocate space and init command line */ + alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end); - if ((s = getenv("clocks_in_mhz")) != NULL) { - /* convert all clock information to MHz */ - kbd->bi_intfreq /= 1000000L; - kbd->bi_busfreq /= 1000000L; - } + /* allocate space for kernel copy of board info */ + alloc_current = get_boot_kbd (alloc_current, &kbd); + set_clocks_in_mhz(kbd); /* find kernel */ kernel = @@ -115,13 +87,14 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, IH_ARCH_M68K, &rd_data_start, &rd_data_end); rd_len = rd_data_end - rd_data_start; - ramdisk_high (rd_data_start, rd_len, kdb, sp_limit, get_sp (), + alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, + kbd, sp_limit, get_sp (), &initrd_start, &initrd_end); debug("## Transferring control to Linux (at address %08lx) ...\n", (ulong) kernel); - SHOW_BOOT_PROGRESS(15); + show_boot_progress (15); /* * Linux Kernel Parameters (passing board info data): @@ -144,3 +117,14 @@ static ulong get_sp (void) return sp; } + +static void set_clocks_in_mhz (bd_t *kbd) +{ + char *s; + + if ((s = getenv("clocks_in_mhz")) != NULL) { + /* convert all clock information to MHz */ + kbd->bi_intfreq /= 1000000L; + kbd->bi_busfreq /= 1000000L; + } +} diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index d73d2fd..7eb8712 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -51,10 +51,7 @@ DECLARE_GLOBAL_DATA_PTR; extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); static ulong get_sp (void); - -#if defined(CONFIG_CMD_BDI) -extern int do_bdinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); -#endif +static void set_clocks_in_mhz (bd_t *kbd); void __attribute__((noinline)) do_bootm_linux(cmd_tbl_t *cmdtp, int flag, @@ -62,14 +59,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, image_header_t *hdr, int verify) { + ulong sp, sp_limit, alloc_current; + ulong initrd_start, initrd_end; ulong rd_data_start, rd_data_end, rd_len; ulong cmd_start, cmd_end; - char *cmdline; - - ulong sp_limit; - char *s; bd_t *kbd; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); @@ -88,60 +83,18 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, * memory, which means far enough below the current stack * pointer. */ + sp = get_sp(); + debug ("## Current stack ends at 0x%08lx ", sp); - sp_limit = get_sp(); - debug ("## Current stack ends at 0x%08lX ", sp_limit); - - sp_limit -= 2048; /* just to be sure */ - if (sp_limit > CFG_BOOTMAPSZ) - sp_limit = CFG_BOOTMAPSZ; - sp_limit &= ~0xF; - - debug ("=> set upper limit to 0x%08lX\n", sp_limit); + alloc_current = sp_limit = get_boot_sp_limit(sp); + debug ("=> set upper limit to 0x%08lx\n", sp_limit); - cmdline = (char *)((sp_limit - CFG_BARGSIZE) & ~0xF); - kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); + /* allocate space and init command line */ + alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end); - 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); - -#if defined(CONFIG_CMD_BDI) - do_bdinfo (NULL, 0, 0, NULL); -#endif -#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 */ - } + /* allocate space for kernel copy of board info */ + alloc_current = get_boot_kbd (alloc_current, &kbd); + set_clocks_in_mhz(kbd); /* find kernel */ kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); @@ -152,7 +105,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, rd_len = rd_data_end - rd_data_start; - ramdisk_high (rd_data_start, rd_len, kbd, sp_limit, get_sp (), + alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, + kbd, sp_limit, get_sp (), &initrd_start, &initrd_end); #if defined(CONFIG_OF_LIBFDT) @@ -266,8 +220,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, of_len = be32_to_cpu(fdt_totalsize(of_data)); - /* position on a 4K boundary before the kbd */ - of_start = (ulong)kbd - of_len; + /* position on a 4K boundary before the alloc_current */ + of_start = alloc_current - 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); @@ -353,6 +307,34 @@ static ulong get_sp (void) return sp; } +static void set_clocks_in_mhz (bd_t *kbd) +{ + char *s; + + 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 */ + } +} + #if defined(CONFIG_OF_LIBFDT) static void fdt_error (const char *msg) { -- cgit v0.10.2 From 7b325454fd231d4273de3fe373850f777fb086bf Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:58:20 +0100 Subject: [new uImage] Cleanup FDT handling in PPC do_boot_linux() Move FDT blob finding and relocation to a dedicated get_fdt() routine. It increases code readability and will make adding support for new uImage format easier. Signed-off-by: Marian Balakowicz diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 7eb8712..69ec459 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -41,6 +41,9 @@ #include static void fdt_error (const char *msg); +static ulong get_fdt (ulong alloc_current, cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + image_header_t *hdr, char **of_flat_tree); #endif #ifdef CFG_INIT_RAM_LOCK @@ -69,9 +72,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); #if defined(CONFIG_OF_LIBFDT) - image_header_t *fdt_hdr; - char *of_flat_tree = NULL; - ulong of_data = 0; + char *of_flat_tree; #endif /* @@ -111,131 +112,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ - if(argc > 3) { - of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); - fdt_hdr = (image_header_t *)of_flat_tree; - - if (fdt_check_header (of_flat_tree) == 0) { -#ifndef CFG_NO_FLASH - if (addr2info((ulong)of_flat_tree) != NULL) - 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); - - 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)) { - fdt_error ("fdt overwritten"); - do_reset (cmdtp, flag, argc, argv); - } - - puts (" Verifying Checksum ... "); - if (!image_check_hcrc (fdt_hdr)) { - fdt_error ("fdt header checksum invalid"); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_dcrc (fdt_hdr)) { - fdt_error ("fdt checksum invalid"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - - if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { - fdt_error ("uImage is not a fdt"); - do_reset (cmdtp, flag, argc, argv); - } - if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { - fdt_error ("uImage is compressed"); - do_reset (cmdtp, flag, argc, argv); - } - if (fdt_check_header (of_flat_tree + image_get_header_size ()) != 0) { - fdt_error ("uImage data is not a fdt"); - do_reset (cmdtp, flag, argc, argv); - } - - memmove ((void *)image_get_load (fdt_hdr), - (void *)(of_flat_tree + image_get_header_size ()), - image_get_data_size (fdt_hdr)); - - of_flat_tree = (char *)image_get_load (fdt_hdr); - } else { - fdt_error ("Did not find a Flattened Device Tree"); - 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)) { - ulong fdt_data, fdt_len; - - image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); - if (fdt_len) { - - of_flat_tree = (char *)fdt_data; - -#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 (fdt_check_header (of_flat_tree) != 0) { - fdt_error ("image is not a fdt"); - do_reset (cmdtp, flag, argc, argv); - } - - if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != fdt_len) { - fdt_error ("fdt size != image size"); - do_reset (cmdtp, flag, argc, argv); - } - } - } -#endif - - -#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 alloc_current */ - of_start = alloc_current - 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); + alloc_current = get_fdt (alloc_current, + cmdtp, flag, argc, argv, hdr, &of_flat_tree); - 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) { - fdt_error ("fdt move failed"); - 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). @@ -342,4 +221,156 @@ static void fdt_error (const char *msg) puts (msg); puts (" - must RESET the board to recover.\n"); } + +static ulong get_fdt (ulong alloc_current, + cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + image_header_t *hdr, char **of_flat_tree) +{ + image_header_t *fdt_hdr; + ulong fdt_relocate = 0; + char *fdt = NULL; + ulong new_alloc_current; + + if(argc > 3) { + fdt = (char *)simple_strtoul (argv[3], NULL, 16); + fdt_hdr = (image_header_t *)fdt; + + if (fdt_check_header (fdt) == 0) { + printf ("## Flattened Device Tree blob at %08lx\n", fdt); +#ifndef CFG_NO_FLASH + if (addr2info ((ulong)fdt) != NULL) + fdt_relocate = 1; +#endif + } else if (image_check_magic (fdt_hdr)) { + ulong image_start, image_end; + ulong load_start, load_end; + + printf ("## Flattened Device Tree Image at %08lx\n", + fdt_hdr); + + print_image_hdr (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)) { + fdt_error ("fdt overwritten"); + do_reset (cmdtp, flag, argc, argv); + } + + puts (" Verifying Checksum ... "); + if (!image_check_hcrc (fdt_hdr)) { + fdt_error ("fdt header checksum invalid"); + do_reset (cmdtp, flag, argc, argv); + } + + if (!image_check_dcrc (fdt_hdr)) { + fdt_error ("fdt checksum invalid"); + do_reset (cmdtp, flag, argc, argv); + } + puts ("OK\n"); + + if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { + fdt_error ("uImage is not a fdt"); + do_reset (cmdtp, flag, argc, argv); + } + if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { + fdt_error ("uImage is compressed"); + do_reset (cmdtp, flag, argc, argv); + } + if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) { + fdt_error ("uImage data is not a fdt"); + do_reset (cmdtp, flag, argc, argv); + } + + memmove ((void *)image_get_load (fdt_hdr), + (void *)image_get_data (fdt_hdr), + image_get_data_size (fdt_hdr)); + + fdt = (char *)image_get_load (fdt_hdr); + } else { + fdt_error ("Did not find a Flattened Device Tree"); + do_reset (cmdtp, flag, argc, argv); + } + printf (" Booting using the fdt at 0x%x\n", + fdt); + } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + ulong fdt_data, fdt_len; + + printf ("## Flattened Device Tree from multi " + "component Image at %08lX\n", (ulong)hdr); + + image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); + if (fdt_len) { + + fdt = (char *)fdt_data; + printf (" Booting using the fdt at 0x%x\n", fdt); + +#ifndef CFG_NO_FLASH + /* move the blob if it is in flash (set of_relocte) */ + if (addr2info ((ulong)fdt) != NULL) + fdt_relocate = 1; +#endif + + if (fdt_check_header (fdt) != 0) { + fdt_error ("image is not a fdt"); + do_reset (cmdtp, flag, argc, argv); + } + + if (be32_to_cpu (fdt_totalsize (fdt)) != fdt_len) { + fdt_error ("fdt size != image size"); + do_reset (cmdtp, flag, argc, argv); + } + } else { + debug (" Did not find a Flattened Device Tree"); + } + } + +#ifdef CFG_BOOTMAPSZ + /* + * The blob must be within CFG_BOOTMAPSZ, + * so we flag it to be copied if it is not. + */ + if (fdt >= (char *)CFG_BOOTMAPSZ) + fdt_relocate = 1; +#endif + + /* move flattend device tree if needed */ + if (fdt_relocate) { + int err; + ulong of_start, of_len; + + of_len = be32_to_cpu (fdt_totalsize (fdt)); + + /* position on a 4K boundary before the alloc_current */ + of_start = alloc_current - of_len; + of_start &= ~(4096 - 1); /* align on page */ + + debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", + (ulong)fdt, (ulong)fdt + of_len - 1, + of_len, of_len); + + printf (" Loading Device Tree to %08lx, end %08lx ... ", + of_start, of_start + of_len - 1); + + err = fdt_open_into (fdt, (void *)of_start, of_len); + if (err != 0) { + fdt_error ("fdt move failed"); + do_reset (cmdtp, flag, argc, argv); + } + puts ("OK\n"); + + *of_flat_tree = (char *)of_start; + new_alloc_current = of_start; + } else { + *of_flat_tree = fdt; + new_alloc_current = alloc_current; + } + + return new_alloc_current; +} #endif -- cgit v0.10.2 From 5cf746c303710329f8040d9c62ee354313e3e91f Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:59:09 +0100 Subject: [new uImage] Move kernel data find code to get_kernel() routine Verification of the kernel image (in old format) and finding kernel data is moved to a dedicated routine. The routine will also hold support for, to be added, new image format. Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 8b6616b..2ddb191 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -74,6 +74,9 @@ static void fixup_silent_linux (void); #endif static void print_type (image_header_t *hdr); +static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], int verify, + ulong *os_data, ulong *os_len); extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* @@ -121,85 +124,17 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int verify = getenv_verify(); image_header_t *hdr; - 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 { - img_addr = simple_strtoul(argv[1], NULL, 16); - } - - show_boot_progress (1); - printf ("## Booting image at %08lx ...\n", img_addr); - -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (img_addr)){ - hdr = (image_header_t *)CFG_LOAD_ADDR; - read_dataflash (img_addr, image_get_header_size (), (char *)hdr); - } else -#endif - hdr = (image_header_t *)img_addr; - - if (!image_check_magic(hdr)) { - puts ("Bad Magic Number\n"); - show_boot_progress (-1); - return 1; - } - show_boot_progress (2); - - if (!image_check_hcrc (hdr)) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-2); + /* get kernel image header, start address and length */ + hdr = get_kernel (cmdtp, flag, argc, argv, verify, + &os_data, &os_len); + if (hdr == NULL) return 1; - } - show_boot_progress (3); -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (img_addr)) - read_dataflash (img_addr + image_get_header_size (), - image_get_data_size (hdr), - (char *)image_get_data (hdr)); -#endif - - /* uImage is in a system RAM, pointed to by hdr */ - print_image_hdr (hdr); - - if (verify) { - puts (" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-3); - return 1; - } - puts ("OK\n"); - } - show_boot_progress (4); - - if (!image_check_target_arch (hdr)) { - printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr)); - show_boot_progress (-4); - return 1; - } - show_boot_progress (5); - - switch (image_get_type (hdr)) { - case IH_TYPE_KERNEL: - os_data = image_get_data (hdr); - os_len = image_get_data_size (hdr); - break; - case IH_TYPE_MULTI: - image_multi_getimg (hdr, 0, &os_data, &os_len); - break; - default: - printf ("Wrong Image Type for %s command\n", cmdtp->name); - show_boot_progress (-5); - return 1; - } show_boot_progress (6); /* @@ -229,7 +164,7 @@ 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) == img_addr) { + if (image_get_load (hdr) == (ulong)hdr) { printf (" XIP %s ... ", type_name); } else { printf (" Loading %s ... ", type_name); @@ -280,6 +215,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } puts ("OK\n"); + debug (" kernel loaded at 0x%08lx, end = 0x%08lx\n", load_start, load_end); show_boot_progress (7); if ((load_start < image_end) && (load_end > image_start)) { @@ -340,6 +276,103 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } +/** + * get_kernel - find kernel image + * @os_data: pointer to a ulong variable, will hold os data start address + * @os_len: pointer to a ulong variable, will hold os data length + * + * get_kernel() tries to find a kernel image, verifies its integrity + * and locates kernel data. + * + * returns: + * pointer to image header if valid image was found, plus kernel start + * address and length, otherwise NULL + */ +static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], int verify, + ulong *os_data, ulong *os_len) +{ + image_header_t *hdr; + ulong img_addr; + + if (argc < 2) { + img_addr = load_addr; + } else { + img_addr = simple_strtoul(argv[1], NULL, 16); + } + + show_boot_progress (1); + printf ("## Booting image at %08lx ...\n", img_addr); + +#ifdef CONFIG_HAS_DATAFLASH + if (addr_dataflash (img_addr)){ + hdr = (image_header_t *)CFG_LOAD_ADDR; + read_dataflash (img_addr, image_get_header_size (), (char *)hdr); + } else +#endif + hdr = (image_header_t *)img_addr; + + if (!image_check_magic(hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-1); + return NULL; + } + show_boot_progress (2); + + if (!image_check_hcrc (hdr)) { + puts ("Bad Header Checksum\n"); + show_boot_progress (-2); + return NULL; + } + show_boot_progress (3); + +#ifdef CONFIG_HAS_DATAFLASH + if (addr_dataflash (img_addr)) + read_dataflash (img_addr + image_get_header_size (), + image_get_data_size (hdr), + (char *)image_get_data (hdr)); +#endif + + /* uImage is in a system RAM, pointed to by hdr */ + print_image_hdr (hdr); + + if (verify) { + puts (" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + printf ("Bad Data CRC\n"); + show_boot_progress (-3); + return NULL; + } + puts ("OK\n"); + } + show_boot_progress (4); + + if (!image_check_target_arch (hdr)) { + printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr)); + show_boot_progress (-4); + return NULL; + } + show_boot_progress (5); + + switch (image_get_type (hdr)) { + case IH_TYPE_KERNEL: + *os_data = image_get_data (hdr); + *os_len = image_get_data_size (hdr); + break; + case IH_TYPE_MULTI: + image_multi_getimg (hdr, 0, os_data, os_len); + break; + default: + printf ("Wrong Image Type for %s command\n", cmdtp->name); + show_boot_progress (-5); + return NULL; + } + debug (" kernel data at 0x%08lx, end = 0x%08lx\n", + *os_data, *os_data + *os_len); + + return hdr; +} + U_BOOT_CMD( bootm, CFG_MAXARGS, 1, do_bootm, "bootm - boot application image from memory\n", @@ -502,7 +535,7 @@ U_BOOT_CMD( #endif /*******************************************************************/ -/* */ +/* helper routines */ /*******************************************************************/ void print_image_hdr (image_header_t *hdr) { -- cgit v0.10.2 From 75d3e8fbd93c14d9929d024c75af2d742c76db70 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 21 Feb 2008 17:20:18 +0100 Subject: [new uImage] Pull in libfdt if CONFIG_FIT is enabled New uImage format (Flattened Image Tree) requires libfdt functionality, print out error message if CONFIG_OF_LIBFDT is not defined. New uImage support is enabled by defining CONFIG_FIT (and CONFIG_OF_LIBFDT). This commit turns it on by default. Signed-off-by: Marian Balakowicz diff --git a/cpu/mpc5xxx/cpu.c b/cpu/mpc5xxx/cpu.c index e4d6168..7522afe 100644 --- a/cpu/mpc5xxx/cpu.c +++ b/cpu/mpc5xxx/cpu.c @@ -114,7 +114,7 @@ unsigned long get_tbclk (void) /* ------------------------------------------------------------------------- */ -#ifdef CONFIG_OF_LIBFDT +#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP) void ft_cpu_setup(void *blob, bd_t *bd) { int div = in_8((void*)CFG_MBAR + 0x204) & 0x0020 ? 8 : 4; diff --git a/cpu/mpc8260/cpu.c b/cpu/mpc8260/cpu.c index 55e61a1..414759e 100644 --- a/cpu/mpc8260/cpu.c +++ b/cpu/mpc8260/cpu.c @@ -300,7 +300,7 @@ void watchdog_reset (void) #endif /* CONFIG_WATCHDOG */ /* ------------------------------------------------------------------------- */ -#if defined(CONFIG_OF_LIBFDT) +#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP) void ft_cpu_setup (void *blob, bd_t *bd) { char * cpu_path = "/cpus/" OF_CPU; diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c index c878352..5d4ab82 100644 --- a/cpu/mpc8xx/cpu.c +++ b/cpu/mpc8xx/cpu.c @@ -638,7 +638,7 @@ void reset_8xx_watchdog (volatile immap_t * immr) #endif /* CONFIG_WATCHDOG */ /* ------------------------------------------------------------------------- */ -#if defined(CONFIG_OF_LIBFDT) +#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP) void ft_cpu_setup (void *blob, bd_t *bd) { char * cpu_path = "/cpus/" OF_CPU; diff --git a/include/image.h b/include/image.h index dbbbee9..ecfce72 100644 --- a/include/image.h +++ b/include/image.h @@ -35,10 +35,19 @@ #include #include + #ifndef USE_HOSTCC #include #include + +/* new uImage format support enabled by default */ +#define CONFIG_FIT 1 +#define CONFIG_OF_LIBFDT 1 + +#if defined(CONFIG_FIT) && !defined(CONFIG_OF_LIBFDT) +#error "CONFIG_OF_LIBFDT not enabled, required by CONFIG_FIT!" #endif +#endif /* USE_HOSTCC */ /* * Operating System Codes -- cgit v0.10.2 From fff888a1997ff7de9b29e24050fc4a0fd403ba16 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 21 Feb 2008 17:20:19 +0100 Subject: [new uImage] Add gen_get_image() routine This routine assures that image (whether legacy or FIT) is not in a special dataflash storage. If image address is a dataflash address image is moved to system RAM. Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 2ddb191..ebb6b69 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -44,10 +44,6 @@ #include #endif -#ifdef CONFIG_HAS_DATAFLASH -#include -#endif - DECLARE_GLOBAL_DATA_PTR; extern int gunzip (void *dst, int dstlen, unsigned char *src, unsigned long *lenp); @@ -304,12 +300,8 @@ static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag, show_boot_progress (1); printf ("## Booting image at %08lx ...\n", img_addr); -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (img_addr)){ - hdr = (image_header_t *)CFG_LOAD_ADDR; - read_dataflash (img_addr, image_get_header_size (), (char *)hdr); - } else -#endif + /* copy from dataflash if needed */ + img_addr = gen_get_image (img_addr); hdr = (image_header_t *)img_addr; if (!image_check_magic(hdr)) { @@ -324,16 +316,8 @@ static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag, show_boot_progress (-2); return NULL; } - show_boot_progress (3); -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (img_addr)) - read_dataflash (img_addr + image_get_header_size (), - image_get_data_size (hdr), - (char *)image_get_data (hdr)); -#endif - - /* uImage is in a system RAM, pointed to by hdr */ + show_boot_progress (3); print_image_hdr (hdr); if (verify) { diff --git a/common/image.c b/common/image.c index 39e5f23..ab6b8e6 100644 --- a/common/image.c +++ b/common/image.c @@ -41,6 +41,12 @@ #include #endif +#if defined(CONFIG_FIT) +#include +#include +#include +#endif + extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #ifdef CONFIG_CMD_BDI @@ -305,6 +311,103 @@ const char* image_get_comp_name (uint8_t comp) } /** + * gen_image_get_format - get image format type + * @img_addr: image start address + * + * gen_image_get_format() checks whether provided address points to a valid + * legacy or FIT image. + * + * returns: + * image format type or IMAGE_FORMAT_INVALID if no image is present + */ +int gen_image_get_format (void *img_addr) +{ + ulong format = IMAGE_FORMAT_INVALID; + image_header_t *hdr; +#if defined(CONFIG_FIT) + char *fit_hdr; +#endif + + hdr = (image_header_t *)img_addr; + if (image_check_magic(hdr)) + format = IMAGE_FORMAT_LEGACY; +#if defined(CONFIG_FIT) + else { + fit_hdr = (char *)img_addr; + if (fdt_check_header (fit_hdr) == 0) + format = IMAGE_FORMAT_FIT; + } +#endif + + return format; +} + +/** + * gen_get_image - get image from special storage (if necessary) + * @img_addr: image start address + * + * gen_get_image() checks if provided image start adddress is located + * in a dataflash storage. If so, image is moved to a system RAM memory. + * + * returns: + * image start address after possible relocation from special storage + */ +ulong gen_get_image (ulong img_addr) +{ + ulong ram_addr, h_size, d_size; + + h_size = image_get_header_size (); +#if defined(CONFIG_FIT) + if (sizeof(struct fdt_header) > h_size) + h_size = sizeof(struct fdt_header); +#endif + +#ifdef CONFIG_HAS_DATAFLASH + if (addr_dataflash (img_addr)){ + ram_addr = CFG_LOAD_ADDR; + debug (" Reading image header from dataflash address " + "%08lx to RAM address %08lx\n", img_addr, ram_addr); + read_dataflash (img_addr, h_size, (char *)ram_addr); + } else +#endif + return img_addr; + + ram_addr = img_addr; + + switch (gen_image_get_format ((void *)ram_addr)) { + case IMAGE_FORMAT_LEGACY: + d_size = image_get_data_size ((image_header_t *)ram_addr); + debug (" Legacy format image found at 0x%08lx, size 0x%08lx\n", + ram_addr, d_size); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + d_size = fdt_totalsize((void *)ram_addr) - h_size; + debug (" FIT/FDT format image found at 0x%08lx, size 0x%08lx\n", + ram_addr, d_size); + + break; +#endif + default: + printf (" No valid image found at 0x%08lx\n", img_addr); + return ram_addr; + } + +#ifdef CONFIG_HAS_DATAFLASH + if (addr_dataflash (img_addr)) { + debug (" Reading image remaining data from dataflash address " + "%08lx to RAM address %08lx\n", img_addr + h_size, + ram_addr + h_size); + + read_dataflash (img_addr + h_size, d_size, + (char *)(ram_addr + h_size)); + } +#endif + + return ram_addr; +} + +/** * image_get_ramdisk - get and verify ramdisk image * @cmdtp: command table pointer * @flag: command flag @@ -334,15 +437,8 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, show_boot_progress (9); -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (rd_addr)) { - rd_hdr = (image_header_t *)CFG_LOAD_ADDR; - debug (" Reading Ramdisk image header from dataflash address " - "%08lx to %08lx\n", rd_addr, (ulong)rd_hdr); - read_dataflash (rd_addr, image_get_header_size (), - (char *)rd_hdr); - } else -#endif + /* copy from dataflash if needed */ + rd_addr = gen_get_image (rd_addr); rd_hdr = (image_header_t *)rd_addr; if (!image_check_magic (rd_hdr)) { @@ -360,18 +456,6 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, show_boot_progress (10); print_image_hdr (rd_hdr); -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (rd_addr)) { - debug (" Reading Ramdisk image data from dataflash address " - "%08lx to %08lx\n", rd_addr + image_get_header_size, - (ulong)image_get_data (rd_hdr)); - - read_dataflash (rd_addr + image_get_header_size (), - image_get_data_size (rd_hdr), - (char *)image_get_data (rd_hdr)); - } -#endif - if (verify) { puts(" Verifying Checksum ... "); if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) { diff --git a/include/image.h b/include/image.h index ecfce72..b4de49d 100644 --- a/include/image.h +++ b/include/image.h @@ -343,6 +343,12 @@ const char* image_get_arch_name (uint8_t arch); const char* image_get_type_name (uint8_t type); const char* image_get_comp_name (uint8_t comp); +#define IMAGE_FORMAT_INVALID 0x00 +#define IMAGE_FORMAT_LEGACY 0x01 +#define IMAGE_FORMAT_FIT 0x02 +int gen_image_get_format (void *img_addr); +ulong gen_get_image (ulong img_addr); + image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong rd_addr, uint8_t arch, int verify); diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 69ec459..04a9665 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -234,6 +234,11 @@ static ulong get_fdt (ulong alloc_current, if(argc > 3) { fdt = (char *)simple_strtoul (argv[3], NULL, 16); + + debug ("## Checking for 'FDT'/'FDT image' at %08lx\n", fdt); + + /* copy from dataflash if needed */ + fdt = (char *)gen_get_image ((ulong)fdt); fdt_hdr = (image_header_t *)fdt; if (fdt_check_header (fdt) == 0) { -- cgit v0.10.2 From f50433d670ec2ee9e96abac67cdc6e5e061a810d Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 21 Feb 2008 17:20:20 +0100 Subject: [new uImage] Add fit_parse_conf() and fit_parse_subimage() routines Introducing routines for parsing new uImage format bootm arguments: []# - configuration specification []: - subimage specification New format images can contain multiple subimages of the same type. For example a single new format image file can contain three kernels, two ramdisks and a couple of FDT blobs. Subimage and configuration specifications are extensions to bootm (and other image-related commands) arguments' syntax that allow to specify which particular subimage should be operated on. Subimage specification is used to denote a particular subimage. Configurations are a bit more complex -- they are used to define a particualr booting setup, for example a (kernel, fdt blob) pair, or a (kernel, ramdisk, fdt blob) tuple, etc. Signed-off-by: Marian Balakowicz diff --git a/common/image.c b/common/image.c index ab6b8e6..7362328 100644 --- a/common/image.c +++ b/common/image.c @@ -774,4 +774,82 @@ ulong get_boot_kbd (ulong alloc_current, bd_t **kbd) } #endif /* CONFIG_PPC || CONFIG_M68K */ +#if defined(CONFIG_FIT) +/*****************************************************************************/ +/* New uImage format routines */ +/*****************************************************************************/ +static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr, + ulong *addr, const char **name) +{ + const char *sep; + + *addr = addr_curr; + *name = NULL; + + sep = strchr (spec, sepc); + if (sep) { + if (sep - spec > 0) + *addr = simple_strtoul (spec, NULL, 16); + + *name = sep + 1; + return 1; + } + + return 0; +} + +/** + * fit_parse_conf - parse FIT configuration spec + * @spec: input string, containing configuration spec + * @add_curr: current image address (to be used as a possible default) + * @addr: pointer to a ulong variable, will hold FIT image address of a given + * configuration + * @conf_name double pointer to a char, will hold pointer to a configuration + * unit name + * + * fit_parse_conf() expects configuration spec in the for of []#, + * where is a FIT image address that contains configuration + * with a unit name. + * + * Address part is optional, and if omitted default add_curr will + * be used instead. + * + * returns: + * 1 if spec is a valid configuration string, + * addr and conf_name are set accordingly + * 0 otherwise + */ +inline int fit_parse_conf (const char *spec, ulong addr_curr, + ulong *addr, const char **conf_name) +{ + return fit_parse_spec (spec, '#', addr_curr, addr, conf_name); +} + +/** + * fit_parse_subimage - parse FIT subimage spec + * @spec: input string, containing subimage spec + * @add_curr: current image address (to be used as a possible default) + * @addr: pointer to a ulong variable, will hold FIT image address of a given + * subimage + * @image_name: double pointer to a char, will hold pointer to a subimage name + * + * fit_parse_subimage() expects subimage spec in the for of + * []:, where is a FIT image address that contains + * subimage with a unit name. + * + * Address part is optional, and if omitted default add_curr will + * be used instead. + * + * returns: + * 1 if spec is a valid subimage string, + * addr and image_name are set accordingly + * 0 otherwise + */ +inline int fit_parse_subimage (const char *spec, ulong addr_curr, + ulong *addr, const char **image_name) +{ + return fit_parse_spec (spec, ':', addr_curr, addr, image_name); +} +#endif /* CONFIG_FIT */ + #endif /* USE_HOSTCC */ diff --git a/include/image.h b/include/image.h index b4de49d..4923612 100644 --- a/include/image.h +++ b/include/image.h @@ -367,6 +367,16 @@ ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end); ulong get_boot_kbd (ulong alloc_current, bd_t **kbd); #endif /* CONFIG_PPC || CONFIG_M68K */ +#if defined(CONFIG_FIT) +/* + * New uImage format + */ +inline int fit_parse_conf (const char *spec, ulong addr_curr, + ulong *addr, const char **conf_name); +inline int fit_parse_subimage (const char *spec, ulong addr_curr, + ulong *addr, const char **image_name); +#endif /* CONFIG_FIT */ + #endif /* USE_HOSTCC */ #endif /* __IMAGE_H__ */ -- cgit v0.10.2 From 2242f5369822bc7780db95c47985bb408ea9157b Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 21 Feb 2008 17:27:41 +0100 Subject: [new uImage] Rename and move print_image_hdr() routine Signed-off-by: Marian Balakowicz diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c index 30c6ca9..b171ca5 100644 --- a/board/mpl/common/common_util.c +++ b/board/mpl/common/common_util.c @@ -185,7 +185,7 @@ mpl_prg_image(uchar *ld_addr) puts("Bad Magic Number\n"); return 1; } - print_image_hdr(hdr); + image_print_contents (hdr); if (!image_check_os (hdr, IH_OS_U_BOOT)) { puts("No U-Boot Image\n"); return 1; diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index ebb6b69..bb60a84 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -36,10 +36,6 @@ #include #include -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) -#include -#endif - #ifdef CFG_HUSH_PARSER #include #endif @@ -69,7 +65,6 @@ static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); static void fixup_silent_linux (void); #endif -static void print_type (image_header_t *hdr); static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], int verify, ulong *os_data, ulong *os_len); @@ -318,7 +313,7 @@ static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag, } show_boot_progress (3); - print_image_hdr (hdr); + image_print_contents (hdr); if (verify) { puts (" Verifying Checksum ... "); @@ -445,7 +440,7 @@ static int image_info (ulong addr) return 1; } - print_image_hdr (hdr); + image_print_contents (hdr); puts (" Verifying Checksum ... "); if (!image_check_dcrc (hdr)) { @@ -493,7 +488,7 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) goto next_sector; printf ("Image at %08lX:\n", (ulong)hdr); - print_image_hdr (hdr); + image_print_contents (hdr); puts (" Verifying Checksum ... "); if (!image_check_dcrc (hdr)) { @@ -521,56 +516,6 @@ U_BOOT_CMD( /*******************************************************************/ /* helper routines */ /*******************************************************************/ -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)); - -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) - to_tm (timestamp, &tm); - 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)); - print_size (image_get_data_size (hdr), "\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)) { - int i; - ulong data, len; - ulong count = image_multi_count (hdr); - - puts (" Contents:\n"); - for (i = 0; i < count; i++) { - image_multi_getimg (hdr, i, &data, &len); - printf (" Image %d: %8ld Bytes = ", i, len); - print_size (len, "\n"); - } - } -} - -static void print_type (image_header_t *hdr) -{ - const char *os, *arch, *type, *comp; - - os = image_get_os_name (image_get_os (hdr)); - arch = image_get_arch_name (image_get_arch (hdr)); - type = image_get_type_name (image_get_type (hdr)); - comp = image_get_comp_name (image_get_comp (hdr)); - - printf ("%s %s %s (%s)", arch, os, type, comp); -} - #ifdef CONFIG_SILENT_CONSOLE static void fixup_silent_linux () { diff --git a/common/cmd_doc.c b/common/cmd_doc.c index b20a2e1..70bbd31 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -265,7 +265,7 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (image_check_magic (hdr)) { - print_image_hdr (hdr); + image_print_contents (hdr); cnt = image_get_image_size (hdr); cnt -= SECTORSIZE; diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index 3b8f80b..c97abfb 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -840,7 +840,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf ("Bad Magic Number\n"); return 1; } - print_image_hdr (hdr); + image_print_contents (hdr); imsize= image_get_image_size (hdr); nrofblk=imsize/512; diff --git a/common/cmd_ide.c b/common/cmd_ide.c index bcd1325..a396643 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -462,7 +462,7 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (50); - print_image_hdr (hdr); + image_print_contents (hdr); cnt = image_get_image_size (hdr); cnt += info.blksz - 1; diff --git a/common/cmd_nand.c b/common/cmd_nand.c index bfa39d7..7fd6667 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -521,7 +521,7 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, } show_boot_progress (57); - print_image_hdr (hdr); + image_print_contents (hdr); cnt = image_get_image_size (hdr); if (jffs2) { @@ -984,7 +984,7 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (image_check_magic (hdr)) { - print_image_hdr (hdr); + image_print_contents (hdr); cnt = image_get_image_size (hdr); cnt -= SECTORSIZE; diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index c2b27a5..5aae7ec 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -285,7 +285,7 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - print_image_hdr (hdr); + image_print_contents (hdr); cnt = image_get_image_size (hdr); cnt += info.blksz - 1; cnt /= info.blksz; diff --git a/common/cmd_usb.c b/common/cmd_usb.c index db2e754..2d7a85a 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -398,7 +398,7 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - print_image_hdr (hdr); + image_print_contents (hdr); cnt = image_get_image_size (hdr); cnt += info.blksz - 1; diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index ab579cd..7d83dc3 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -70,7 +70,7 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 1; } #ifdef DEBUG - print_image_hdr (hdr); + image_print_contents (hdr); #endif if (!image_check_type (hdr, IH_TYPE_MULTI)) { diff --git a/common/image.c b/common/image.c index 7362328..690e0af 100644 --- a/common/image.c +++ b/common/image.c @@ -41,6 +41,10 @@ #include #endif +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) +#include +#endif + #if defined(CONFIG_FIT) #include #include @@ -310,6 +314,56 @@ const char* image_get_comp_name (uint8_t comp) return name; } +static void image_print_type (image_header_t *hdr) +{ + const char *os, *arch, *type, *comp; + + os = image_get_os_name (image_get_os (hdr)); + arch = image_get_arch_name (image_get_arch (hdr)); + type = image_get_type_name (image_get_type (hdr)); + comp = image_get_comp_name (image_get_comp (hdr)); + + printf ("%s %s %s (%s)", arch, os, type, comp); +} + +void image_print_contents (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)); + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) + to_tm (timestamp, &tm); + 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: "); + image_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", + image_get_load (hdr), image_get_ep (hdr)); + + if (image_check_type (hdr, IH_TYPE_MULTI)) { + int i; + ulong data, len; + ulong count = image_multi_count (hdr); + + puts (" Contents:\n"); + for (i = 0; i < count; i++) { + image_multi_getimg (hdr, i, &data, &len); + printf (" Image %d: %8ld Bytes = ", i, len); + print_size (len, "\n"); + } + } +} + /** * gen_image_get_format - get image format type * @img_addr: image start address @@ -454,7 +508,7 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, } show_boot_progress (10); - print_image_hdr (rd_hdr); + image_print_contents (rd_hdr); if (verify) { puts(" Verifying Checksum ... "); diff --git a/include/common.h b/include/common.h index cd8aad0..3f05b5e 100644 --- a/include/common.h +++ b/include/common.h @@ -224,9 +224,6 @@ void flash_perror (int); /* common/cmd_autoscript.c */ int autoscript (ulong addr); -/* common/cmd_bootm.c */ -void print_image_hdr (image_header_t *hdr); - extern ulong load_addr; /* Default Load Address */ /* common/cmd_nvedit.c */ diff --git a/include/image.h b/include/image.h index 4923612..502d35a 100644 --- a/include/image.h +++ b/include/image.h @@ -342,6 +342,7 @@ const char* image_get_os_name (uint8_t os); const char* image_get_arch_name (uint8_t arch); const char* image_get_type_name (uint8_t type); const char* image_get_comp_name (uint8_t comp); +void image_print_contents (image_header_t *hdr); #define IMAGE_FORMAT_INVALID 0x00 #define IMAGE_FORMAT_LEGACY 0x01 diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 04a9665..d2ee3dc 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -254,7 +254,7 @@ static ulong get_fdt (ulong alloc_current, printf ("## Flattened Device Tree Image at %08lx\n", fdt_hdr); - print_image_hdr (fdt_hdr); + image_print_contents (fdt_hdr); image_start = (ulong)fdt_hdr; image_end = image_get_image_end (fdt_hdr); -- cgit v0.10.2 From 5583cbf736474ef754e128a54fb78632f57b48fd Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 21 Feb 2008 17:27:49 +0100 Subject: [new uImage] Fix erroneous use of image_get_magic() in fdc/usb cmds Signed-off-by: Marian Balakowicz diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index c97abfb..9ddc59b 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -836,7 +836,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } hdr = (image_header_t *)addr; - if (!image_get_magic (hdr)) { + if (!image_check_magic (hdr)) { printf ("Bad Magic Number\n"); return 1; } diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 2d7a85a..3f1aa7d 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -388,7 +388,7 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) hdr = (image_header_t *)addr; - if (!image_get_magic (hdr)) { + if (!image_check_magic (hdr)) { printf("\n** Bad Magic Number **\n"); return 1; } -- cgit v0.10.2 From d5934ad7756f038a393a9cfab76a4fe306d9d930 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Mon, 4 Feb 2008 08:28:09 +0100 Subject: [new uImage] Add dual format uImage support framework This patch adds framework for dual format images. Format detection is added and the bootm controll flow is updated to include cases for new FIT format uImages. When the legacy (image_header based) format is detected appropriate legacy specific handling is invoked. For the new (FIT based) format uImages dual boot framework has a minial support, that will only print out a corresponding debug messages. Implementation of the FIT specific handling will be added in following patches. Signed-off-by: Marian Balakowicz diff --git a/board/cray/L1/L1.c b/board/cray/L1/L1.c index 8e6d74e..c00acc8 100644 --- a/board/cray/L1/L1.c +++ b/board/cray/L1/L1.c @@ -140,6 +140,13 @@ int misc_init_r (void) char bootcmd[32]; hdr = (image_header_t *) (CFG_MONITOR_BASE - image_get_header_size ()); +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + timestamp = (time_t)image_get_time (hdr); to_tm (timestamp, &tm); printf ("Welcome to U-Boot on Cray L1. Compiled %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); diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c index cb8087b..976707d 100644 --- a/board/esd/common/auto_update.c +++ b/board/esd/common/auto_update.c @@ -91,6 +91,12 @@ int au_check_cksum_valid(int i, long nbytes) image_header_t *hdr; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif if ((au_image[i].type == AU_FIRMWARE) && (au_image[i].size != image_get_data_size (hdr))) { @@ -118,6 +124,13 @@ int au_check_header_valid(int i, long nbytes) unsigned long checksum; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG @@ -183,6 +196,12 @@ int au_do_update(int i, long sz) #endif hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif switch (au_image[i].type) { case AU_SCRIPT: diff --git a/board/mcc200/auto_update.c b/board/mcc200/auto_update.c index 8b520c8..fcae35a 100644 --- a/board/mcc200/auto_update.c +++ b/board/mcc200/auto_update.c @@ -143,6 +143,12 @@ int au_check_cksum_valid(int idx, long nbytes) image_header_t *hdr; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif if (nbytes != image_get_image_size (hdr)) { printf ("Image %s bad total SIZE\n", aufile[idx]); @@ -162,6 +168,13 @@ int au_check_header_valid(int idx, long nbytes) unsigned long checksum, fsize; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG @@ -233,6 +246,12 @@ int au_do_update(int idx, long sz) uint nbytes; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif /* execute a script */ if (image_check_type (hdr, IH_TYPE_SCRIPT)) { diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c index b171ca5..fffd25c 100644 --- a/board/mpl/common/common_util.c +++ b/board/mpl/common/common_util.c @@ -181,6 +181,13 @@ mpl_prg_image(uchar *ld_addr) image_header_t *hdr = (image_header_t *)ld_addr; int rc; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + if (!image_check_magic (hdr)) { puts("Bad Magic Number\n"); return 1; diff --git a/board/siemens/common/fpga.c b/board/siemens/common/fpga.c index 9d71946..a9a6dfe 100644 --- a/board/siemens/common/fpga.c +++ b/board/siemens/common/fpga.c @@ -137,6 +137,13 @@ static int fpga_load (fpga_t* fpga, ulong addr, int checkall) char msg[32]; int verify, i; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* * Check the image header and data of the net-list */ @@ -333,6 +340,13 @@ int fpga_init (void) } hdr = (image_header_t *)addr; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + if ((new_id = fpga_get_version(fpga, image_get_name (hdr))) == -1) return 1; diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c index bd9ee0c..8f67535 100644 --- a/board/trab/auto_update.c +++ b/board/trab/auto_update.c @@ -211,6 +211,12 @@ au_check_cksum_valid(int idx, long nbytes) image_header_t *hdr; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif if (nbytes != image_get_image_size (hdr)) { @@ -234,6 +240,13 @@ au_check_header_valid(int idx, long nbytes) unsigned char buf[4]; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG @@ -327,6 +340,12 @@ au_do_update(int idx, long sz) uint nbytes; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif /* disable the power switch */ *CPLD_VFD_BK |= POWER_OFF; @@ -417,6 +436,13 @@ au_update_eeprom(int idx) } hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* write the time field into EEPROM */ off = auee_off[idx].time; val = image_get_time (hdr); diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c index 53f8e83..f9ab1d9 100644 --- a/common/cmd_autoscript.c +++ b/common/cmd_autoscript.c @@ -53,7 +53,7 @@ int autoscript (ulong addr) { ulong len; - image_header_t *hdr = (image_header_t *)addr; + image_header_t *hdr; ulong *data; char *cmd; int rcode = 0; @@ -61,33 +61,47 @@ autoscript (ulong addr) verify = getenv_verify (); - if (!image_check_magic (hdr)) { - puts ("Bad magic number\n"); - return 1; - } + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (!image_check_hcrc (hdr)) { - puts ("Bad header crc\n"); - return 1; - } + if (!image_check_magic (hdr)) { + puts ("Bad magic number\n"); + return 1; + } - if (verify) { - if (!image_check_dcrc (hdr)) { - puts ("Bad data crc\n"); + if (!image_check_hcrc (hdr)) { + puts ("Bad header crc\n"); return 1; } - } - if (!image_check_type (hdr, IH_TYPE_SCRIPT)) { - puts ("Bad image type\n"); - return 1; - } + if (verify) { + if (!image_check_dcrc (hdr)) { + puts ("Bad data crc\n"); + return 1; + } + } + + if (!image_check_type (hdr, IH_TYPE_SCRIPT)) { + puts ("Bad image type\n"); + return 1; + } - /* get length of script */ - data = (ulong *)image_get_data (hdr); + /* get length of script */ + data = (ulong *)image_get_data (hdr); - if ((len = image_to_cpu (*data)) == 0) { - puts ("Empty Script\n"); + if ((len = image_to_cpu (*data)) == 0) { + puts ("Empty Script\n"); + return 1; + } + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("autoscript"); + return 1; +#endif + default: + puts ("Wrong image format for autoscript\n"); return 1; } diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index bb60a84..3f09988 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -65,8 +65,9 @@ static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); static void fixup_silent_linux (void); #endif -static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag, +static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], int verify, + bootm_headers_t *images, ulong *os_data, ulong *os_len); extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); @@ -80,7 +81,7 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); */ typedef void boot_os_fn (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, /* of image to boot */ + bootm_headers_t *images,/* pointers to os/initrd/fdt */ int verify); /* getenv("verify")[0] != 'n' */ extern boot_os_fn do_bootm_linux; @@ -102,6 +103,7 @@ static boot_os_fn do_bootm_artos; #endif ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ +static bootm_headers_t images; /* pointers to os/initrd/fdt images */ /*******************************************************************/ @@ -113,21 +115,47 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) const char *type_name; uint unc_len = CFG_BOOTM_LEN; int verify = getenv_verify(); + uint8_t comp, type, os; - image_header_t *hdr; + void *os_hdr; ulong os_data, os_len; - ulong image_start, image_end; ulong load_start, load_end; + memset ((void *)&images, 0, sizeof (images)); + /* get kernel image header, start address and length */ - hdr = get_kernel (cmdtp, flag, argc, argv, verify, - &os_data, &os_len); - if (hdr == NULL) + os_hdr = get_kernel (cmdtp, flag, argc, argv, verify, + &images, &os_data, &os_len); + if (os_len == 0) return 1; show_boot_progress (6); + /* get image parameters */ + switch (gen_image_get_format (os_hdr)) { + case IMAGE_FORMAT_LEGACY: + type = image_get_type (os_hdr); + comp = image_get_comp (os_hdr); + os = image_get_os (os_hdr); + + image_end = image_get_image_end (os_hdr); + load_start = image_get_load (os_hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("bootm"); + return 1; +#endif + default: + puts ("ERROR: unknown image format type!\n"); + return 1; + } + + image_start = (ulong)os_hdr; + load_end = 0; + type_name = image_get_type_name (type); + /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily @@ -146,21 +174,14 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) dcache_disable(); #endif - type_name = image_get_type_name (image_get_type (hdr)); - - 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)) { + switch (comp) { case IH_COMP_NONE: - if (image_get_load (hdr) == (ulong)hdr) { + if (load_start == (ulong)os_hdr) { printf (" XIP %s ... ", type_name); } else { printf (" Loading %s ... ", type_name); - memmove_wd ((void *)image_get_load (hdr), + memmove_wd ((void *)load_start, (void *)os_data, os_len, CHUNKSZ); load_end = load_start + os_len; @@ -169,7 +190,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; case IH_COMP_GZIP: printf (" Uncompressing %s ... ", type_name); - if (gunzip ((void *)image_get_load (hdr), unc_len, + if (gunzip ((void *)load_start, unc_len, (uchar *)os_data, &os_len) != 0) { puts ("GUNZIP ERROR - must RESET board to recover\n"); show_boot_progress (-6); @@ -186,7 +207,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * use slower decompression algorithm which requires * at most 2300 KB of memory. */ - int i = BZ2_bzBuffToBuffDecompress ((char*)image_get_load (hdr), + int i = BZ2_bzBuffToBuffDecompress ((char*)load_start, &unc_len, (char *)os_data, os_len, CFG_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { @@ -201,7 +222,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) default: if (iflag) enable_interrupts(); - printf ("Unimplemented compression type %d\n", image_get_comp (hdr)); + printf ("Unimplemented compression type %d\n", comp); show_boot_progress (-7); return 1; } @@ -219,42 +240,42 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress (8); - switch (image_get_os (hdr)) { + switch (os) { default: /* handled by (original) Linux case */ case IH_OS_LINUX: #ifdef CONFIG_SILENT_CONSOLE fixup_silent_linux(); #endif - do_bootm_linux (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_linux (cmdtp, flag, argc, argv, &images, verify); break; case IH_OS_NETBSD: - do_bootm_netbsd (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_netbsd (cmdtp, flag, argc, argv, &images, verify); break; #ifdef CONFIG_LYNXKDI case IH_OS_LYNXOS: - do_bootm_lynxkdi (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_lynxkdi (cmdtp, flag, argc, argv, &images, verify); break; #endif case IH_OS_RTEMS: - do_bootm_rtems (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_rtems (cmdtp, flag, argc, argv, &images, verify); break; #if defined(CONFIG_CMD_ELF) case IH_OS_VXWORKS: - do_bootm_vxworks (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_vxworks (cmdtp, flag, argc, argv, &images, verify); break; case IH_OS_QNX: - do_bootm_qnxelf (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_qnxelf (cmdtp, flag, argc, argv, &images, verify); break; #endif #ifdef CONFIG_ARTOS case IH_OS_ARTOS: - do_bootm_artos (cmdtp, flag, argc, argv, hdr, verify); + do_bootm_artos (cmdtp, flag, argc, argv, &images, verify); break; #endif } @@ -279,77 +300,119 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * pointer to image header if valid image was found, plus kernel start * address and length, otherwise NULL */ -static image_header_t *get_kernel (cmd_tbl_t *cmdtp, int flag, +static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], int verify, + bootm_headers_t *images, ulong *os_data, ulong *os_len) { image_header_t *hdr; ulong img_addr; +#if defined(CONFIG_FIT) + void *fit_hdr; + const char *fit_uname_config = NULL; + const char *fit_uname_kernel = NULL; +#endif + /* find out kernel image address */ if (argc < 2) { img_addr = load_addr; + debug ("* kernel: default image load address = 0x%08lx\n", + load_addr); +#if defined(CONFIG_FIT) + } else if (fit_parse_conf (argv[1], load_addr, &img_addr, + &fit_uname_config)) { + debug ("* kernel: config '%s' from image at 0x%08lx\n", + fit_uname_config, img_addr); + } else if (fit_parse_subimage (argv[1], load_addr, &img_addr, + &fit_uname_kernel)) { + debug ("* kernel: subimage '%s' from image at 0x%08lx\n", + fit_uname_kernel, img_addr); +#endif } else { img_addr = simple_strtoul(argv[1], NULL, 16); + debug ("* kernel: cmdline image address = 0x%08lx\n", img_addr); } show_boot_progress (1); - printf ("## Booting image at %08lx ...\n", img_addr); + printf ("## Booting kernel image at %08lx ...\n", img_addr); /* copy from dataflash if needed */ img_addr = gen_get_image (img_addr); - hdr = (image_header_t *)img_addr; - if (!image_check_magic(hdr)) { - puts ("Bad Magic Number\n"); - show_boot_progress (-1); - return NULL; - } - show_boot_progress (2); + /* check image type, for FIT images get FIT kernel node */ + switch (gen_image_get_format ((void *)img_addr)) { + case IMAGE_FORMAT_LEGACY: - if (!image_check_hcrc (hdr)) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-2); - return NULL; - } + debug ("* kernel: legacy format image\n"); + hdr = (image_header_t *)img_addr; - show_boot_progress (3); - image_print_contents (hdr); + if (!image_check_magic(hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-1); + return NULL; + } + show_boot_progress (2); - if (verify) { - puts (" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-3); + if (!image_check_hcrc (hdr)) { + puts ("Bad Header Checksum\n"); + show_boot_progress (-2); return NULL; } - puts ("OK\n"); - } - show_boot_progress (4); - if (!image_check_target_arch (hdr)) { - printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr)); - show_boot_progress (-4); - return NULL; - } - show_boot_progress (5); + show_boot_progress (3); + image_print_contents (hdr); + + if (verify) { + puts (" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + printf ("Bad Data CRC\n"); + show_boot_progress (-3); + return NULL; + } + puts ("OK\n"); + } + show_boot_progress (4); + + if (!image_check_target_arch (hdr)) { + printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr)); + show_boot_progress (-4); + return NULL; + } + show_boot_progress (5); + + switch (image_get_type (hdr)) { + case IH_TYPE_KERNEL: + *os_data = image_get_data (hdr); + *os_len = image_get_data_size (hdr); + break; + case IH_TYPE_MULTI: + image_multi_getimg (hdr, 0, os_data, os_len); + break; + default: + printf ("Wrong Image Type for %s command\n", cmdtp->name); + show_boot_progress (-5); + return NULL; + } + images->legacy_hdr_os = hdr; + images->legacy_hdr_valid = 1; - switch (image_get_type (hdr)) { - case IH_TYPE_KERNEL: - *os_data = image_get_data (hdr); - *os_len = image_get_data_size (hdr); - break; - case IH_TYPE_MULTI: - image_multi_getimg (hdr, 0, os_data, os_len); break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (void *)img_addr; + debug ("* kernel: FIT format image\n"); + fit_unsupported ("kernel"); + return NULL; +#endif default: - printf ("Wrong Image Type for %s command\n", cmdtp->name); - show_boot_progress (-5); + printf ("Wrong Image Format for %s command\n", cmdtp->name); return NULL; } + debug (" kernel data at 0x%08lx, end = 0x%08lx\n", *os_data, *os_data + *os_len); - return hdr; + return (void *)img_addr; } U_BOOT_CMD( @@ -426,29 +489,44 @@ int do_iminfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) static int image_info (ulong addr) { - image_header_t *hdr = (image_header_t *)addr; + void *hdr = (void *)addr; printf ("\n## Checking Image at %08lx ...\n", addr); - if (!image_check_magic (hdr)) { - puts (" Bad Magic Number\n"); - return 1; - } + switch (gen_image_get_format (hdr)) { + case IMAGE_FORMAT_LEGACY: + puts (" Legacy image found\n"); + if (!image_check_magic (hdr)) { + puts (" Bad Magic Number\n"); + return 1; + } - if (!image_check_hcrc (hdr)) { - puts (" Bad Header Checksum\n"); - return 1; - } + if (!image_check_hcrc (hdr)) { + puts (" Bad Header Checksum\n"); + return 1; + } - image_print_contents (hdr); + image_print_contents (hdr); - puts (" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { - puts (" Bad Data CRC\n"); - return 1; + puts (" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + puts (" Bad Data CRC\n"); + return 1; + } + puts ("OK\n"); + return 0; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + puts (" FIT image found\n"); + fit_unsupported ("iminfo"); + return 0; +#endif + default: + puts ("Unknown image format!\n"); + break; } - puts ("OK\n"); - return 0; + + return 1; } U_BOOT_CMD( @@ -470,7 +548,7 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { flash_info_t *info; int i, j; - image_header_t *hdr; + void *hdr; for (i = 0, info = &flash_info[0]; i < CFG_MAX_FLASH_BANKS; ++i, ++info) { @@ -479,23 +557,38 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) goto next_bank; for (j = 0; j < info->sector_count; ++j) { - hdr = (image_header_t *)info->start[j]; - - if (!hdr || !image_check_magic (hdr)) + hdr = (void *)info->start[j]; + if (!hdr) goto next_sector; - if (!image_check_hcrc (hdr)) + switch (gen_image_get_format (hdr)) { + case IMAGE_FORMAT_LEGACY: + if (!image_check_magic (hdr)) + goto next_sector; + + if (!image_check_hcrc (hdr)) + goto next_sector; + + printf ("Legacy Image at %08lX:\n", (ulong)hdr); + image_print_contents (hdr); + + puts (" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + puts ("Bad Data CRC\n"); + } else { + puts ("OK\n"); + } + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + printf ("FIT Image at %08lX:\n", (ulong)hdr); + fit_unsupported ("imls"); + break; +#endif + default: goto next_sector; - - printf ("Image at %08lX:\n", (ulong)hdr); - image_print_contents (hdr); - - puts (" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { - puts ("Bad Data CRC\n"); - } else { - puts ("OK\n"); } + next_sector: ; } next_bank: ; @@ -555,14 +648,22 @@ static void fixup_silent_linux () static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { void (*loader)(bd_t *, image_header_t *, char *, char *); - image_header_t *img_addr; + image_header_t *os_hdr, *hdr; ulong kernel_data, kernel_len; char *consdev; char *cmdline; +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("NetBSD"); + do_reset (cmdtp, flag, argc, argv); + } +#endif + hdr = images->legacy_hdr_os; + /* * Booting a (NetBSD) kernel image * @@ -574,12 +675,11 @@ static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, * line, the name of the console device, and (optionally) the * address of the original image header. */ - - img_addr = 0; + os_hdr = NULL; if (image_check_type (hdr, IH_TYPE_MULTI)) { image_multi_getimg (hdr, 1, &kernel_data, &kernel_len); if (kernel_len) - img_addr = hdr; + os_hdr = hdr; } consdev = ""; @@ -625,24 +725,41 @@ static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, * r5: console device * r6: boot args string */ - (*loader) (gd->bd, img_addr, consdev, cmdline); + (*loader) (gd->bd, os_hdr, consdev, cmdline); } #ifdef CONFIG_LYNXKDI static void do_bootm_lynxkdi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - lynxkdi_boot (hdr); + image_header_t *hdr = images->legacy_hdr_os; + +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("Lynx"); + do_reset (cmdtp, flag, argc, argv); + } +#endif + + lynxkdi_boot ((image_header_t *)hdr); } #endif /* CONFIG_LYNXKDI */ static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { + image_header_t *hdr = images->legacy_hdr_os; void (*entry_point)(bd_t *); +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("RTEMS"); + do_reset (cmdtp, flag, argc, argv); + } +#endif + entry_point = (void (*)(bd_t *))image_get_ep (hdr); printf ("## Transferring control to RTEMS (at address %08lx) ...\n", @@ -660,9 +777,17 @@ static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_CMD_ELF) static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { char str[80]; + image_header_t *hdr = images->legacy_hdr_os; + +#if defined(CONFIG_FIT) + if (hdr == NULL) { + fit_unsupported_reset ("VxWorks"); + do_reset (cmdtp, flag, argc, argv); + } +#endif sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */ setenv("loadaddr", str); @@ -671,10 +796,18 @@ static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, static void do_bootm_qnxelf(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { char *local_args[2]; char str[16]; + image_header_t *hdr = images->legacy_hdr_os; + +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("QNX"); + do_reset (cmdtp, flag, argc, argv); + } +#endif sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */ local_args[0] = argv[0]; @@ -686,7 +819,7 @@ static void do_bootm_qnxelf(cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_ARTOS) && defined(CONFIG_PPC) static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { ulong top; char *s, *cmdline; @@ -694,6 +827,14 @@ static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag, int i, j, nxt, len, envno, envsz; bd_t *kbd; void (*entry)(bd_t *bd, char *cmdline, char **fwenv, ulong top); + image_header_t *hdr = images->legacy_hdr_os; + +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("ARTOS"); + do_reset (cmdtp, flag, argc, argv); + } +#endif /* * Booting an ARTOS kernel image + application diff --git a/common/cmd_doc.c b/common/cmd_doc.c index 70bbd31..3358b04 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -261,17 +261,29 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (38); - hdr = (image_header_t *)addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (image_check_magic (hdr)) { + if (image_check_magic (hdr)) { - image_print_contents (hdr); + image_print_contents (hdr); - cnt = image_get_image_size (hdr); - cnt -= SECTORSIZE; - } else { - puts ("\n** Bad Magic Number **\n"); - show_boot_progress (-39); + cnt = image_get_image_size (hdr); + cnt -= SECTORSIZE; + } else { + puts ("\n** Bad Magic Number **\n"); + show_boot_progress (-39); + return 1; + } + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("docboot"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } show_boot_progress (39); diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index 9ddc59b..b6e023a 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -835,14 +835,28 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf("result%d: 0x%02X\n",i,pCMD->result[i]); return 1; } - hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf ("Bad Magic Number\n"); + + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; + if (!image_check_magic (hdr)) { + printf ("Bad Magic Number\n"); + return 1; + } + image_print_contents (hdr); + + imsize = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("fdcboot"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - image_print_contents (hdr); - imsize= image_get_image_size (hdr); nrofblk=imsize/512; if((imsize%512)>0) nrofblk++; @@ -861,20 +875,18 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* Loading ok, update default load address */ load_addr = addr; - if(image_check_type (hdr, IH_TYPE_KERNEL)) { - /* Check if we should attempt an auto-start */ - if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { - char *local_args[2]; - extern int do_bootm (cmd_tbl_t *, int, int, char *[]); + /* Check if we should attempt an auto-start */ + if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { + char *local_args[2]; + extern int do_bootm (cmd_tbl_t *, int, int, char *[]); - local_args[0] = argv[0]; - local_args[1] = NULL; + local_args[0] = argv[0]; + local_args[1] = NULL; - printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); + printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); - do_bootm (cmdtp, 0, 1, local_args); - rcode ++; - } + do_bootm (cmdtp, 0, 1, local_args); + rcode ++; } return rcode; } diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index 4030d04..10199f5 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -216,19 +216,31 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) break; case FPGA_LOADMK: - { - image_header_t header; - image_header_t *hdr = &header; - ulong data; - - memmove (&header, (char *)fpga_data, image_get_header_size ()); - if (!image_check_magic (hdr)) { - puts ("Bad Magic Number\n"); - return 1; + switch (gen_image_get_format (fpga_data)) { + case IMAGE_FORMAT_LEGACY: + { + image_header_t *hdr = (image_header_t *)fpga_data; + ulong data; + + if (!image_check_magic (hdr)) { + puts ("Bad Magic Number\n"); + return 1; + } + data = (ulong)image_get_data (hdr); + data_size = image_get_data_size (hdr); + rc = fpga_load (dev, (void *)data, data_size); } - data = ((ulong)fpga_data + image_get_header_size ()); - data_size = image_get_data_size (hdr); - rc = fpga_load (dev, (void *)data, data_size); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("fpga"); + rc = FPGA_FAIL; + break; +#endif + default: + puts ("** Unknown image type\n"); + rc = FPGA_FAIL; + break; } break; diff --git a/common/cmd_ide.c b/common/cmd_ide.c index a396643..bef04db 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -446,25 +446,38 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (48); - hdr = (image_header_t *)addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf("\n** Bad Magic Number **\n"); - show_boot_progress (-49); - return 1; - } - show_boot_progress (49); + if (!image_check_magic (hdr)) { + printf("\n** Bad Magic Number **\n"); + show_boot_progress (-49); + return 1; + } + show_boot_progress (49); + + if (!image_check_hcrc (hdr)) { + puts ("\n** Bad Header Checksum **\n"); + show_boot_progress (-50); + return 1; + } + show_boot_progress (50); - if (!image_check_hcrc (hdr)) { - puts ("\n** Bad Header Checksum **\n"); - show_boot_progress (-50); + image_print_contents (hdr); + + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("diskboot"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - show_boot_progress (50); - - image_print_contents (hdr); - cnt = image_get_image_size (hdr); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 7fd6667..b099afe 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -512,18 +512,32 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, } show_boot_progress (56); - hdr = (image_header_t *) addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; + + if (!image_check_magic (hdr)) { + printf("\n** Bad Magic Number 0x%x **\n", + image_get_magic (hdr)); + show_boot_progress (-57); + return 1; + } + show_boot_progress (57); + + image_print_contents (hdr); - if (!image_check_magic (hdr)) { - printf("\n** Bad Magic Number 0x%x **\n", image_get_magic (hdr)); - show_boot_progress (-57); + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("nand_load_image"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - show_boot_progress (57); - - image_print_contents (hdr); - cnt = image_get_image_size (hdr); if (jffs2) { nand_read_options_t opts; memset(&opts, 0, sizeof(opts)); @@ -980,17 +994,30 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (56); - hdr = (image_header_t *)addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (image_check_magic (hdr)) { + if (image_check_magic (hdr)) { - image_print_contents (hdr); + image_print_contents (hdr); - cnt = image_get_image_size (hdr); - cnt -= SECTORSIZE; - } else { - printf ("\n** Bad Magic Number 0x%x **\n", image_get_magic (hdr)); - show_boot_progress (-57); + cnt = image_get_image_size (hdr); + cnt -= SECTORSIZE; + } else { + printf ("\n** Bad Magic Number 0x%x **\n", + image_get_magic (hdr)); + show_boot_progress (-57); + return 1; + } + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("nboot"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } show_boot_progress (57); diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 5aae7ec..42b3072 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -273,20 +273,33 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - hdr = (image_header_t *)addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf("\n** Bad Magic Number **\n"); - return 1; - } + if (!image_check_magic (hdr)) { + printf("\n** Bad Magic Number **\n"); + return 1; + } - if (!image_check_hcrc (hdr)) { - puts ("\n** Bad Header Checksum **\n"); + if (!image_check_hcrc (hdr)) { + puts ("\n** Bad Header Checksum **\n"); + return 1; + } + + image_print_contents (hdr); + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("scsi"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - image_print_contents (hdr); - cnt = image_get_image_size (hdr); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 3f1aa7d..ad3873c 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -386,21 +386,34 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - hdr = (image_header_t *)addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf("\n** Bad Magic Number **\n"); - return 1; - } + if (!image_check_magic (hdr)) { + printf("\n** Bad Magic Number **\n"); + return 1; + } + + if (!image_check_hcrc (hdr)) { + puts ("\n** Bad Header Checksum **\n"); + return 1; + } - if (!image_check_hcrc (hdr)) { - puts ("\n** Bad Header Checksum **\n"); + image_print_contents (hdr); + + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("usbboot"); + return 1; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - image_print_contents (hdr); - - cnt = image_get_image_size (hdr); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index 7d83dc3..4dadc37 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -56,63 +56,76 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) dest = simple_strtoul(argv[3], NULL, 16); } - printf("## Copying from image at %08lx ...\n", addr); - hdr = (image_header_t *)addr; + switch (gen_image_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: - if (!image_check_magic (hdr)) { - printf("Bad Magic Number\n"); - return 1; - } - - if (!image_check_hcrc (hdr)) { - printf("Bad Header Checksum\n"); - return 1; - } -#ifdef DEBUG - image_print_contents (hdr); -#endif + printf("## Copying from legacy image at %08lx ...\n", addr); + hdr = (image_header_t *)addr; + if (!image_check_magic (hdr)) { + printf("Bad Magic Number\n"); + return 1; + } - if (!image_check_type (hdr, IH_TYPE_MULTI)) { - printf("Wrong Image Type for %s command\n", cmdtp->name); - return 1; - } + if (!image_check_hcrc (hdr)) { + printf("Bad Header Checksum\n"); + return 1; + } + #ifdef DEBUG + image_print_contents (hdr); + #endif - if (image_get_comp (hdr) != IH_COMP_NONE) { - printf("Wrong Compression Type for %s command\n", cmdtp->name); - return 1; - } + if (!image_check_type (hdr, IH_TYPE_MULTI)) { + printf("Wrong Image Type for %s command\n", + cmdtp->name); + return 1; + } - if (verify) { - printf(" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { - printf("Bad Data CRC\n"); + if (image_get_comp (hdr) != IH_COMP_NONE) { + printf("Wrong Compression Type for %s command\n", + cmdtp->name); return 1; } - printf("OK\n"); - } - data = image_get_data (hdr); - len_ptr = (ulong *) data; - - data += 4; /* terminator */ - for (i = 0; len_ptr[i]; ++i) { - data += 4; - if (argc > 2 && part > i) { - u_long tail; - len = image_to_cpu (len_ptr[i]); - tail = len % 4; - data += len; - if (tail) { - data += 4 - tail; + if (verify) { + printf(" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + printf("Bad Data CRC\n"); + return 1; } + printf("OK\n"); } - } - if (argc > 2 && part >= i) { - printf("Bad Image Part\n"); + + data = image_get_data (hdr); + len_ptr = (ulong *) data; + + data += 4; /* terminator */ + for (i = 0; len_ptr[i]; ++i) { + data += 4; + if (argc > 2 && part > i) { + u_long tail; + len = image_to_cpu (len_ptr[i]); + tail = len % 4; + data += len; + if (tail) { + data += 4 - tail; + } + } + } + if (argc > 2 && part >= i) { + printf("Bad Image Part\n"); + return 1; + } + len = image_to_cpu (len_ptr[part]); +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_unsupported ("imxtract"); + return 1; +#endif + default: + puts ("Invalid image type for imxtract\n"); return 1; } - len = image_to_cpu (len_ptr[part]); if (argc > 3) { memcpy((char *) dest, (char *) data, len); diff --git a/common/image.c b/common/image.c index 690e0af..ea27b0b 100644 --- a/common/image.c +++ b/common/image.c @@ -490,9 +490,6 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, image_header_t *rd_hdr; show_boot_progress (9); - - /* copy from dataflash if needed */ - rd_addr = gen_get_image (rd_addr); rd_hdr = (image_header_t *)rd_addr; if (!image_check_magic (rd_hdr)) { @@ -540,7 +537,7 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, * @flag: command flag * @argc: command argument count * @argv: command argument list - * @hdr: pointer to the posiibly multi componet kernel image + * @images: pointer to the bootm images strcture * @verify: checksum verification flag * @arch: expected ramdisk architecture * @rd_start: pointer to a ulong variable, will hold ramdisk start address @@ -558,56 +555,111 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, * board is reset if ramdisk image is found but corrupted */ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify, uint8_t arch, + bootm_headers_t *images, int verify, uint8_t arch, ulong *rd_start, ulong *rd_end) { - ulong rd_addr; + ulong rd_addr, rd_load; ulong rd_data, rd_len; image_header_t *rd_hdr; +#if defined(CONFIG_FIT) + void *fit_hdr; + const char *fit_uname_config = NULL; + const char *fit_uname_ramdisk = NULL; + ulong default_addr; +#endif - if (argc >= 3) { + /* + * Look for a '-' which indicates to ignore the + * ramdisk argument + */ + if ((argc >= 3) && (strcmp(argv[2], "-") == 0)) { + debug ("## Skipping init Ramdisk\n"); + rd_len = rd_data = 0; + } else if (argc >= 3) { +#if defined(CONFIG_FIT) /* - * Look for a '-' which indicates to ignore the - * ramdisk argument + * If the init ramdisk comes from the FIT image and the FIT image + * address is omitted in the command line argument, try to use + * os FIT image address or default load address. */ - if (strcmp(argv[2], "-") == 0) { - debug ("## Skipping init Ramdisk\n"); - rd_len = rd_data = 0; - } else { - /* - * Check if there is an initrd image at the - * address provided in the second bootm argument - */ - rd_addr = simple_strtoul (argv[2], NULL, 16); - printf ("## Loading init Ramdisk Image at %08lx ...\n", + if (images->fit_uname_os) + default_addr = (ulong)images->fit_hdr_os; + else + default_addr = load_addr; + + if (fit_parse_conf (argv[2], default_addr, + &rd_addr, &fit_uname_config)) { + debug ("* ramdisk: config '%s' from image at 0x%08lx\n", + fit_uname_config, rd_addr); + } else if (fit_parse_subimage (argv[2], default_addr, + &rd_addr, &fit_uname_ramdisk)) { + debug ("* ramdisk: subimage '%s' from image at 0x%08lx\n", + fit_uname_ramdisk, rd_addr); + } else +#endif + { + rd_addr = simple_strtoul(argv[2], NULL, 16); + debug ("* ramdisk: cmdline image address = 0x%08lx\n", rd_addr); + } + + /* copy from dataflash if needed */ + printf ("## Loading init Ramdisk Image at %08lx ...\n", + rd_addr); + rd_addr = gen_get_image (rd_addr); + + /* + * Check if there is an initrd image at the + * address provided in the second bootm argument + * check image type, for FIT images get FIT node. + */ + switch (gen_image_get_format ((void *)rd_addr)) { + case IMAGE_FORMAT_LEGACY: + + debug ("* ramdisk: legacy format image\n"); rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv, rd_addr, arch, verify); rd_data = image_get_data (rd_hdr); rd_len = image_get_data_size (rd_hdr); + rd_load = image_get_load (rd_hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (void *)rd_addr; + debug ("* ramdisk: FIT format image\n"); + fit_unsupported_reset ("ramdisk"); + do_reset (cmdtp, flag, argc, argv); +#endif + default: + printf ("Wrong Image Format for %s command\n", + cmdtp->name); + rd_data = rd_len = 0; + } #if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO) - /* - *we need to copy the ramdisk to SRAM to let Linux boot - */ - memmove ((void *)image_get_load (rd_hdr), - (uchar *)rd_data, rd_len); - - rd_data = image_get_load (rd_hdr); -#endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */ + /* + * We need to copy the ramdisk to SRAM to let Linux boot + */ + if (rd_data) { + memmove ((void *)rd_load, (uchar *)rd_data, rd_len); + rd_data = rd_load; } +#endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */ - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + } else if (images->legacy_hdr_valid && + image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) { /* - * Now check if we have a multifile image - * Get second entry data start address and len + * Now check if we have a legacy mult-component image, + * get second entry data start address and len. */ show_boot_progress (13); printf ("## Loading init Ramdisk from multi component " - "Image at %08lx ...\n", (ulong)hdr); - image_multi_getimg (hdr, 1, &rd_data, &rd_len); + "Image at %08lx ...\n", + (ulong)images->legacy_hdr_os); + + image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len); } else { /* * no initrd image @@ -904,6 +956,7 @@ inline int fit_parse_subimage (const char *spec, ulong addr_curr, { return fit_parse_spec (spec, ':', addr_curr, addr, image_name); } + #endif /* CONFIG_FIT */ #endif /* USE_HOSTCC */ diff --git a/include/image.h b/include/image.h index 502d35a..2f4b67d 100644 --- a/include/image.h +++ b/include/image.h @@ -44,6 +44,9 @@ #define CONFIG_FIT 1 #define CONFIG_OF_LIBFDT 1 +/* enable fit_format_error(), fit_format_warning() */ +#define CONFIG_FIT_VERBOSE 1 + #if defined(CONFIG_FIT) && !defined(CONFIG_OF_LIBFDT) #error "CONFIG_OF_LIBFDT not enabled, required by CONFIG_FIT!" #endif @@ -176,6 +179,33 @@ typedef struct image_header { } image_header_t; /* + * Legacy and FIT format headers used by do_bootm() and do_bootm_() + * routines. + */ +typedef struct bootm_headers { + /* + * Legacy os image header, if it is a multi component image + * then get_ramdisk() and get_fdt() will attempt to get + * data from second and third component accordingly. + */ + image_header_t *legacy_hdr_os; + ulong legacy_hdr_valid; + +#if defined(CONFIG_FIT) + void *fit_hdr_os; /* os FIT image header */ + char *fit_uname_os; /* os subimage node unit name */ + + void *fit_hdr_rd; /* init ramdisk FIT image header */ + char *fit_uname_rd; /* init ramdisk node unit name */ + +#if defined(CONFIG_PPC) + void *fit_hdr_fdt; /* FDT blob FIT image header */ + char *fit_uname_fdt; /* FDT blob node unit name */ +#endif +#endif +} bootm_headers_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. @@ -355,7 +385,7 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, ulong rd_addr, uint8_t arch, int verify); void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify, uint8_t arch, + bootm_headers_t *images, int verify, uint8_t arch, ulong *rd_start, ulong *rd_end); #if defined(CONFIG_PPC) || defined(CONFIG_M68K) @@ -368,14 +398,29 @@ ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end); ulong get_boot_kbd (ulong alloc_current, bd_t **kbd); #endif /* CONFIG_PPC || CONFIG_M68K */ +/*******************************************************************/ +/* New uImage format */ +/*******************************************************************/ #if defined(CONFIG_FIT) -/* - * New uImage format - */ inline int fit_parse_conf (const char *spec, ulong addr_curr, ulong *addr, const char **conf_name); inline int fit_parse_subimage (const char *spec, ulong addr_curr, ulong *addr, const char **image_name); + +#ifdef CONFIG_FIT_VERBOSE +#define fit_unsupported(msg) printf ("! %s:%d " \ + "FIT images not supported for '%s'\n", \ + __FILE__, __LINE__, (msg)) + +#define fit_unsupported_reset(msg) printf ("! %s:%d " \ + "FIT images not supported for '%s' " \ + "- must reset board to recover!\n", \ + __FILE__, __LINE__, (msg)) +#else +#define fit_unsupported(msg) +#define fit_unsupported_reset(msg) +#endif /* CONFIG_FIT_VERBOSE */ + #endif /* CONFIG_FIT */ #endif /* USE_HOSTCC */ diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index 31c2d67..4849c8a 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -56,24 +56,38 @@ static void setup_end_tag (bd_t *bd); static void setup_videolfb_tag (gd_t *gd); # endif - static struct tag *params; #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - ulong initrd_start, initrd_end; - void (*theKernel)(int zero, int arch, uint params); - bd_t *bd = gd->bd; - int machid = bd->bi_arch_number; - char *s; + ulong initrd_start, initrd_end; + ulong ep = 0; + bd_t *bd = gd->bd; + char *s; + int machid = bd->bi_arch_number; + void (*theKernel)(int zero, int arch, uint params); #ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); #endif - theKernel = (void (*)(int, int, uint))image_get_ep (hdr); + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + fit_unsupported_reset ("ARM linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + theKernel = (void (*)(int, int, uint))ep; s = getenv ("machid"); if (s) { @@ -81,7 +95,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], printf ("Using machid 0x%x from environment\n", machid); } - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_ARM, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index a934cae..c449394 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -34,6 +34,8 @@ DECLARE_GLOBAL_DATA_PTR; /* CPU-specific hook to allow flushing of caches, etc. */ extern void prepare_to_boot(void); +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + static struct tag *setup_start_tag(struct tag *params) { params->hdr.tag = ATAG_CORE; @@ -172,17 +174,29 @@ static void setup_end_tag(struct tag *params) } void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - ulong initrd_start, initrd_end; - - void (*theKernel)(int magic, void *tagtable); - struct tag *params, *params_start; - char *commandline = getenv("bootargs"); - - theKernel = (void *)image_get_ep (hdr); + ulong initrd_start, initrd_end; + ulong ep = 0; + void (*theKernel)(int magic, void *tagtable); + struct tag *params, *params_start; + char *commandline = getenv("bootargs"); + + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + fit_unsupported_reset ("AVR32 linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + theKernel = (void *)ep; - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_AVR32, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_blackfin/bootm.c b/lib_blackfin/bootm.c index 6299415..8010e5d 100644 --- a/lib_blackfin/bootm.c +++ b/lib_blackfin/bootm.c @@ -47,16 +47,30 @@ extern void flush_data_cache(void); static char *make_command_line(void); void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - int (*appl) (char *cmdline); - char *cmdline; + int (*appl) (char *cmdline); + char *cmdline; + ulong ep = 0; #ifdef SHARED_RESOURCES swap_to(FLASH); #endif - appl = (int (*)(char *))image_get_ep (hdr); + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + fit_unsupported_reset ("AVR32 linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + appl = (int (*)(char *))ep; + printf("Starting Kernel at = %x\n", appl); cmdline = make_command_line(); if (icache_status()) { diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c index ab6c2a9..3a6497c 100644 --- a/lib_i386/bootm.c +++ b/lib_i386/bootm.c @@ -32,22 +32,35 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - void *base_ptr; + void *base_ptr; + ulong os_data, os_len; + ulong initrd_start, initrd_end; + ulong ep; + image_header_t *hdr; - ulong os_data, os_len; - ulong initrd_start, initrd_end; - - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_I386, &initrd_start, &initrd_end); - /* if multi-part image, we need to advance base ptr */ - if (image_check_type (hdr, IH_TYPE_MULTI)) { - image_multi_getimg (hdr, 0, &os_data, &os_len); + if (images->legacy_hdr_valid) { + hdr = images->legacy_hdr_os; + if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* if multi-part image, we need to get first subimage */ + image_multi_getimg (hdr, 0, &os_data, &os_len); + } else { + /* otherwise get image data */ + os_data = image_get_data (hdr); + os_len = image_get_data_size (hdr); + } +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + fit_unsupported_reset ("I386 linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif } else { - os_data = image_get_data (hdr); - os_len = image_get_data_size (hdr); + puts ("Could not find kernel image!\n"); + do_reset (cmdtp, flag, argc, argv); } base_ptr = load_zimage ((void*)os_data, os_len, diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index ac04da0..ce8be05 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -42,10 +42,11 @@ DECLARE_GLOBAL_DATA_PTR; static ulong get_sp (void); static void set_clocks_in_mhz (bd_t *kbd); +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { ulong sp, sp_limit, alloc_current; @@ -53,8 +54,9 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, ulong initrd_start, initrd_end; ulong cmd_start, cmd_end; - bd_t *kbd; - void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); + bd_t *kbd; + ulong ep = 0; + void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); /* * Booting a (Linux) kernel image @@ -78,12 +80,22 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, alloc_current = get_boot_kbd (alloc_current, &kbd); set_clocks_in_mhz(kbd); - /* find kernel */ - kernel = - (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + fit_unsupported_reset ("M68K linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_M68K, &rd_data_start, &rd_data_end); rd_len = rd_data_end - rd_data_start; diff --git a/lib_microblaze/bootm.c b/lib_microblaze/bootm.c index bccfbe1..1455211 100644 --- a/lib_microblaze/bootm.c +++ b/lib_microblaze/bootm.c @@ -32,14 +32,29 @@ DECLARE_GLOBAL_DATA_PTR; +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { /* First parameter is mapped to $r5 for kernel boot args */ - void (*theKernel) (char *); - char *commandline = getenv ("bootargs"); + void (*theKernel) (char *); + char *commandline = getenv ("bootargs"); + ulong ep = 0; - theKernel = (void (*)(char *))image_get_ep (hdr); + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + fit_unsupported_reset ("MICROBLAZE linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + theKernel = (void (*)(char *))ep; show_boot_progress (15); diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c index fb91c76..5c2f28e 100644 --- a/lib_mips/bootm.c +++ b/lib_mips/bootm.c @@ -43,20 +43,32 @@ static int linux_env_idx; static void linux_params_init (ulong start, char * commandline); static void linux_env_set (char * env_name, char * env_val); +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - ulong initrd_start, initrd_end; - - void (*theKernel) (int, char **, char **, int *); - char *commandline = getenv ("bootargs"); - char env_buf[12]; - - theKernel = - (void (*)(int, char **, char **, int *))image_get_ep (hdr); + ulong initrd_start, initrd_end; + ulong ep = 0; + void (*theKernel) (int, char **, char **, int *); + char *commandline = getenv ("bootargs"); + char env_buf[12]; + + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + fit_unsupported_reset ("MIPS linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + theKernel = (void (*)(int, char **, char **, int *))ep; - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_MIPS, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_nios/bootm.c b/lib_nios/bootm.c index 55f7e3a..92a58f2 100644 --- a/lib_nios/bootm.c +++ b/lib_nios/bootm.c @@ -29,6 +29,6 @@ * */ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image__header_t *hdr, int verify) + bootm_headers_t *images, int verify) { } diff --git a/lib_nios2/bootm.c b/lib_nios2/bootm.c index cb84324..56d1d19 100644 --- a/lib_nios2/bootm.c +++ b/lib_nios2/bootm.c @@ -25,10 +25,26 @@ #include #include +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - void (*kernel)(void) = (void (*)(void))image_get_ep (hdr); + ulong ep = 0; + + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + fit_unsupported_reset ("NIOS2 linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + void (*kernel)(void) = (void (*)(void))ep; /* For now we assume the Microtronix linux ... which only * needs to be called ;-) diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index d2ee3dc..a1bbfc6 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -43,7 +43,7 @@ static void fdt_error (const char *msg); static ulong get_fdt (ulong alloc_current, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, char **of_flat_tree); + bootm_headers_t *images, char **of_flat_tree); #endif #ifdef CFG_INIT_RAM_LOCK @@ -59,7 +59,7 @@ static void set_clocks_in_mhz (bd_t *kbd); void __attribute__((noinline)) do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, + bootm_headers_t *images, int verify) { ulong sp, sp_limit, alloc_current; @@ -69,6 +69,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, ulong cmd_start, cmd_end; bd_t *kbd; + ulong ep = 0; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); #if defined(CONFIG_OF_LIBFDT) @@ -97,11 +98,22 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, alloc_current = get_boot_kbd (alloc_current, &kbd); set_clocks_in_mhz(kbd); - /* find kernel */ - kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + fit_unsupported_reset ("PPC linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - get_ramdisk (cmdtp, flag, argc, argv, hdr, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, verify, IH_ARCH_PPC, &rd_data_start, &rd_data_end); rd_len = rd_data_end - rd_data_start; @@ -113,7 +125,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ alloc_current = get_fdt (alloc_current, - cmdtp, flag, argc, argv, hdr, &of_flat_tree); + cmdtp, flag, argc, argv, images, &of_flat_tree); /* * Add the chosen node if it doesn't exist, add the env and bd_t @@ -225,33 +237,69 @@ static void fdt_error (const char *msg) static ulong get_fdt (ulong alloc_current, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, char **of_flat_tree) + bootm_headers_t *images, char **of_flat_tree) { + ulong fdt_addr; image_header_t *fdt_hdr; + char *fdt_blob = NULL; ulong fdt_relocate = 0; - char *fdt = NULL; ulong new_alloc_current; + ulong image_start, image_end; + ulong load_start, load_end; +#if defined(CONFIG_FIT) + void *fit_hdr; + const char *fit_uname_config = NULL; + const char *fit_uname_fdt = NULL; + ulong default_addr; +#endif - if(argc > 3) { - fdt = (char *)simple_strtoul (argv[3], NULL, 16); + if (argc > 3) { +#if defined(CONFIG_FIT) + /* + * If the FDT blob comes from the FIT image and the FIT image + * address is omitted in the command line argument, try to use + * ramdisk or os FIT image address or default load address. + */ + if (images->fit_uname_rd) + default_addr = (ulong)images->fit_hdr_rd; + else if (images->fit_uname_os) + default_addr = (ulong)images->fit_hdr_os; + else + default_addr = load_addr; + + if (fit_parse_conf (argv[3], default_addr, + &fdt_addr, &fit_uname_config)) { + debug ("* fdt: config '%s' from image at 0x%08lx\n", + fit_uname_config, fdt_addr); + } else if (fit_parse_subimage (argv[3], default_addr, + &fdt_addr, &fit_uname_fdt)) { + debug ("* fdt: subimage '%s' from image at 0x%08lx\n", + fit_uname_fdt, fdt_addr); + } else +#endif + { + fdt_addr = simple_strtoul(argv[3], NULL, 16); + debug ("* fdt: cmdline image address = 0x%08lx\n", + fdt_addr); + } - debug ("## Checking for 'FDT'/'FDT image' at %08lx\n", fdt); + debug ("## Checking for 'FDT'/'FDT image' at %08lx\n", + fdt_addr); /* copy from dataflash if needed */ - fdt = (char *)gen_get_image ((ulong)fdt); - fdt_hdr = (image_header_t *)fdt; + fdt_addr = gen_get_image (fdt_addr); - if (fdt_check_header (fdt) == 0) { - printf ("## Flattened Device Tree blob at %08lx\n", fdt); -#ifndef CFG_NO_FLASH - if (addr2info ((ulong)fdt) != NULL) - fdt_relocate = 1; -#endif - } else if (image_check_magic (fdt_hdr)) { - ulong image_start, image_end; - ulong load_start, load_end; + /* + * Check if there is an FDT image at the + * address provided in the second bootm argument + * check image type, for FIT images get a FIT node. + */ + switch (gen_image_get_format ((void *)fdt_addr)) { + case IMAGE_FORMAT_LEGACY: + debug ("* fdt: legacy format image\n"); - printf ("## Flattened Device Tree Image at %08lx\n", + fdt_hdr = (image_header_t *)fdt_addr; + printf ("## Flattened Device Tree Legacy Image at %08lx\n", fdt_hdr); image_print_contents (fdt_hdr); @@ -296,51 +344,87 @@ static ulong get_fdt (ulong alloc_current, (void *)image_get_data (fdt_hdr), image_get_data_size (fdt_hdr)); - fdt = (char *)image_get_load (fdt_hdr); - } else { - fdt_error ("Did not find a Flattened Device Tree"); + fdt_blob = (char *)image_get_load (fdt_hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + + /* check FDT blob vs FIT hdr */ + if (fit_uname_config || fit_uname_fdt) { + /* + * FIT image + */ + fit_hdr = (void *)fdt_addr; + debug ("* fdt: FIT format image\n"); + fit_unsupported_reset ("PPC fdt"); + do_reset (cmdtp, flag, argc, argv); + } else { + /* + * FDT blob + */ + printf ("## Flattened Device Tree blob at %08lx\n", fdt_blob); + fdt_blob = (char *)fdt_addr; + } + break; +#endif + default: + fdt_error ("Did not find a cmdline Flattened Device Tree"); do_reset (cmdtp, flag, argc, argv); } - printf (" Booting using the fdt at 0x%x\n", - fdt); - } else if (image_check_type (hdr, IH_TYPE_MULTI)) { + + printf (" Booting using the fdt blob at 0x%x\n", fdt_blob); + + } else if (images->legacy_hdr_valid && + image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) { + ulong fdt_data, fdt_len; + /* + * Now check if we have a legacy multi-component image, + * get second entry data start address and len. + */ printf ("## Flattened Device Tree from multi " - "component Image at %08lX\n", (ulong)hdr); + "component Image at %08lX\n", + (ulong)images->legacy_hdr_os); - image_multi_getimg (hdr, 2, &fdt_data, &fdt_len); + image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len); if (fdt_len) { - fdt = (char *)fdt_data; - printf (" Booting using the fdt at 0x%x\n", fdt); + fdt_blob = (char *)fdt_data; + printf (" Booting using the fdt at 0x%x\n", fdt_blob); -#ifndef CFG_NO_FLASH - /* move the blob if it is in flash (set of_relocte) */ - if (addr2info ((ulong)fdt) != NULL) - fdt_relocate = 1; -#endif - - if (fdt_check_header (fdt) != 0) { + if (fdt_check_header (fdt_blob) != 0) { fdt_error ("image is not a fdt"); do_reset (cmdtp, flag, argc, argv); } - if (be32_to_cpu (fdt_totalsize (fdt)) != fdt_len) { + if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { fdt_error ("fdt size != image size"); do_reset (cmdtp, flag, argc, argv); } } else { - debug (" Did not find a Flattened Device Tree"); + fdt_error ("Did not find a Flattened Device Tree " + "in a legacy multi-component image"); + do_reset (cmdtp, flag, argc, argv); } + } else { + debug ("## No Flattened Device Tree\n"); + *of_flat_tree = NULL; + return alloc_current; } +#ifndef CFG_NO_FLASH + /* move the blob if it is in flash (set fdt_relocate) */ + if (addr2info ((ulong)fdt_blob) != NULL) + fdt_relocate = 1; +#endif + #ifdef CFG_BOOTMAPSZ /* * The blob must be within CFG_BOOTMAPSZ, * so we flag it to be copied if it is not. */ - if (fdt >= (char *)CFG_BOOTMAPSZ) + if (fdt_blob >= (char *)CFG_BOOTMAPSZ) fdt_relocate = 1; #endif @@ -349,20 +433,20 @@ static ulong get_fdt (ulong alloc_current, int err; ulong of_start, of_len; - of_len = be32_to_cpu (fdt_totalsize (fdt)); + of_len = be32_to_cpu (fdt_totalsize (fdt_blob)); /* position on a 4K boundary before the alloc_current */ of_start = alloc_current - of_len; of_start &= ~(4096 - 1); /* align on page */ debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - (ulong)fdt, (ulong)fdt + of_len - 1, + (ulong)fdt_blob, (ulong)fdt_blob + of_len - 1, of_len, of_len); printf (" Loading Device Tree to %08lx, end %08lx ... ", of_start, of_start + of_len - 1); - err = fdt_open_into (fdt, (void *)of_start, of_len); + err = fdt_open_into (fdt_blob, (void *)of_start, of_len); if (err != 0) { fdt_error ("fdt move failed"); do_reset (cmdtp, flag, argc, argv); @@ -372,7 +456,7 @@ static ulong get_fdt (ulong alloc_current, *of_flat_tree = (char *)of_start; new_alloc_current = of_start; } else { - *of_flat_tree = fdt; + *of_flat_tree = fdt_blob; new_alloc_current = alloc_current; } diff --git a/lib_sh/bootm.c b/lib_sh/bootm.c index 4e5fe77..55e64f5 100644 --- a/lib_sh/bootm.c +++ b/lib_sh/bootm.c @@ -43,6 +43,8 @@ #define RAMDISK_IMAGE_START_MASK 0x07FF +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + #ifdef CFG_DEBUG static void hexdump (unsigned char *buf, int len) { @@ -58,10 +60,24 @@ static void hexdump (unsigned char *buf, int len) #endif void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - image_header_t *hdr, int verify) + bootm_headers_t *images, int verify) { - char *bootargs = getenv("bootargs"); - void (*kernel) (void) = (void (*)(void))image_get_ep (hdr); + ulong ep = 0; + char *bootargs = getenv("bootargs"); + + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + fit_unsupported_reset ("SH linux bootm"); + do_reset (cmdtp, flag, argc, argv); +#endif + } else { + puts ("Could not find kernel entry point!\n"); + do_reset (cmdtp, flag, argc, argv); + } + void (*kernel) (void) = (void (*)(void))ep; /* Setup parameters */ memset(PARAM, 0, 0x1000); /* Clear zero page */ -- cgit v0.10.2 From d2ced9eb19ec74f4a359949dbe353427fa6d55ca Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Mon, 4 Feb 2008 08:28:17 +0100 Subject: [new uImage] POWERPC: Split get_fdt() into get and relocate routines PPC specific FDT blob handling code is divided into two separate routines: get_fdt() - find and verify a FDT blob (either raw or image embedded) fdt_relocate() - move FDT blob to within BOOTMAP if needed Signed-off-by: Marian Balakowicz Acked-by: Kumar Gala diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index a1bbfc6..d5e019e 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -41,9 +41,11 @@ #include static void fdt_error (const char *msg); -static ulong get_fdt (ulong alloc_current, cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - bootm_headers_t *images, char **of_flat_tree); +static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images, char **of_flat_tree, ulong *of_size); +static ulong fdt_relocate (ulong alloc_current, + cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + char **of_flat_tree, ulong *of_size); #endif #ifdef CFG_INIT_RAM_LOCK @@ -73,7 +75,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); #if defined(CONFIG_OF_LIBFDT) - char *of_flat_tree; + char *of_flat_tree = NULL; + ulong of_size = 0; #endif /* @@ -124,14 +127,16 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ - alloc_current = get_fdt (alloc_current, - cmdtp, flag, argc, argv, images, &of_flat_tree); + get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); + + alloc_current = fdt_relocate (alloc_current, + cmdtp, flag, argc, argv, &of_flat_tree, &of_size); /* * 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 (of_size) { if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { fdt_error ("/chosen node create failed"); do_reset (cmdtp, flag, argc, argv); @@ -234,16 +239,12 @@ static void fdt_error (const char *msg) puts (" - must RESET the board to recover.\n"); } -static ulong get_fdt (ulong alloc_current, - cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - bootm_headers_t *images, char **of_flat_tree) +static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images, char **of_flat_tree, ulong *of_size) { ulong fdt_addr; image_header_t *fdt_hdr; char *fdt_blob = NULL; - ulong fdt_relocate = 0; - ulong new_alloc_current; ulong image_start, image_end; ulong load_start, load_end; #if defined(CONFIG_FIT) @@ -410,13 +411,37 @@ static ulong get_fdt (ulong alloc_current, } else { debug ("## No Flattened Device Tree\n"); *of_flat_tree = NULL; + *of_size = 0; + return; + } + + *of_flat_tree = fdt_blob; + *of_size = be32_to_cpu (fdt_totalsize (fdt_blob)); + debug (" of_flat_tree at 0x%08lx size 0x%08lx\n", + *of_flat_tree, *of_size); +} + +static ulong fdt_relocate (ulong alloc_current, + cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + char **of_flat_tree, ulong *of_size) +{ + char *fdt_blob = *of_flat_tree; + ulong relocate = 0; + ulong new_alloc_current; + + /* nothing to do */ + if (*of_size == 0) return alloc_current; + + if (fdt_check_header (fdt_blob) != 0) { + fdt_error ("image is not a fdt"); + do_reset (cmdtp, flag, argc, argv); } #ifndef CFG_NO_FLASH - /* move the blob if it is in flash (set fdt_relocate) */ + /* move the blob if it is in flash (set relocate) */ if (addr2info ((ulong)fdt_blob) != NULL) - fdt_relocate = 1; + relocate = 1; #endif #ifdef CFG_BOOTMAPSZ @@ -425,15 +450,15 @@ static ulong get_fdt (ulong alloc_current, * so we flag it to be copied if it is not. */ if (fdt_blob >= (char *)CFG_BOOTMAPSZ) - fdt_relocate = 1; + relocate = 1; #endif /* move flattend device tree if needed */ - if (fdt_relocate) { + if (relocate) { int err; ulong of_start, of_len; - of_len = be32_to_cpu (fdt_totalsize (fdt_blob)); + of_len = *of_size; /* position on a 4K boundary before the alloc_current */ of_start = alloc_current - of_len; -- cgit v0.10.2 From 6f0f9dfc4ee880fbf400a2ebe14238181a6c3f91 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 27 Feb 2008 11:00:47 +0100 Subject: [new uImage] Optimize gen_get_image() flow control When CONFIG_HAS_DATAFLASH is not defined gen_get_image() routine has nothing to do, update its control flow to better reflect that simple case. Signed-off-by: Marian Balakowicz Acked-by: Kumar Gala diff --git a/common/image.c b/common/image.c index ea27b0b..dd55264 100644 --- a/common/image.c +++ b/common/image.c @@ -408,55 +408,57 @@ int gen_image_get_format (void *img_addr) */ ulong gen_get_image (ulong img_addr) { - ulong ram_addr, h_size, d_size; - - h_size = image_get_header_size (); -#if defined(CONFIG_FIT) - if (sizeof(struct fdt_header) > h_size) - h_size = sizeof(struct fdt_header); -#endif + ulong ram_addr = img_addr; #ifdef CONFIG_HAS_DATAFLASH + ulong h_size, d_size; + if (addr_dataflash (img_addr)){ + /* ger RAM address */ ram_addr = CFG_LOAD_ADDR; + + /* get header size */ + h_size = image_get_header_size (); +#if defined(CONFIG_FIT) + if (sizeof(struct fdt_header) > h_size) + h_size = sizeof(struct fdt_header); +#endif + + /* read in header */ debug (" Reading image header from dataflash address " "%08lx to RAM address %08lx\n", img_addr, ram_addr); - read_dataflash (img_addr, h_size, (char *)ram_addr); - } else -#endif - return img_addr; - ram_addr = img_addr; + read_dataflash (img_addr, h_size, (char *)ram_addr); - switch (gen_image_get_format ((void *)ram_addr)) { - case IMAGE_FORMAT_LEGACY: - d_size = image_get_data_size ((image_header_t *)ram_addr); - debug (" Legacy format image found at 0x%08lx, size 0x%08lx\n", - ram_addr, d_size); - break; + /* get data size */ + switch (gen_image_get_format ((void *)ram_addr)) { + case IMAGE_FORMAT_LEGACY: + d_size = image_get_data_size ((image_header_t *)ram_addr); + debug (" Legacy format image found at 0x%08lx, size 0x%08lx\n", + ram_addr, d_size); + break; #if defined(CONFIG_FIT) - case IMAGE_FORMAT_FIT: - d_size = fdt_totalsize((void *)ram_addr) - h_size; - debug (" FIT/FDT format image found at 0x%08lx, size 0x%08lx\n", - ram_addr, d_size); - - break; + case IMAGE_FORMAT_FIT: + d_size = fdt_totalsize((void *)ram_addr) - h_size; + debug (" FIT/FDT format image found at 0x%08lx, size 0x%08lx\n", + ram_addr, d_size); + break; #endif - default: - printf (" No valid image found at 0x%08lx\n", img_addr); - return ram_addr; - } + default: + printf (" No valid image found at 0x%08lx\n", img_addr); + return ram_addr; + } -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (img_addr)) { + /* read in image data */ debug (" Reading image remaining data from dataflash address " "%08lx to RAM address %08lx\n", img_addr + h_size, ram_addr + h_size); read_dataflash (img_addr + h_size, d_size, (char *)(ram_addr + h_size)); + } -#endif +#endif /* CONFIG_HAS_DATAFLASH */ return ram_addr; } -- cgit v0.10.2 From 823afe7cefe00dafefc6696c1cc7aa828c394234 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 27 Feb 2008 11:00:47 +0100 Subject: [Makefile] Sort COBJS in lib_ Makefiles Signed-off-by: Marian Balakowicz diff --git a/lib_arm/Makefile b/lib_arm/Makefile index 18c9e97..12a8748 100644 --- a/lib_arm/Makefile +++ b/lib_arm/Makefile @@ -25,13 +25,21 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = _ashldi3.o _ashrdi3.o _divsi3.o _modsi3.o _udivsi3.o _umodsi3.o - -COBJS = board.o bootm.o \ - cache.o div0.o interrupts.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SOBJS-y += _ashldi3.o +SOBJS-y += _ashrdi3.o +SOBJS-y += _divsi3.o +SOBJS-y += _modsi3.o +SOBJS-y += _udivsi3.o +SOBJS-y += _umodsi3.o + +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += div0.o +COBJS-y += interrupts.o + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_avr32/Makefile b/lib_avr32/Makefile index ebe237b..37b8051 100644 --- a/lib_avr32/Makefile +++ b/lib_avr32/Makefile @@ -27,12 +27,14 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = memset.o +SOBJS-y += memset.o -COBJS = board.o interrupts.o bootm.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += interrupts.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_blackfin/Makefile b/lib_blackfin/Makefile index ac3fb28..dfaed6d 100644 --- a/lib_blackfin/Makefile +++ b/lib_blackfin/Makefile @@ -29,12 +29,21 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = memcpy.o memcmp.o memset.o memmove.o - -COBJS = post.o tests.o board.o bootm.o bf533_string.o cache.o muldi3.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SOBJS-y += memcmp.o +SOBJS-y += memcpy.o +SOBJS-y += memmove.o +SOBJS-y += memset.o + +COBJS-y += bf533_string.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += muldi3.o +COBJS-y += post.o +COBJS-y += tests.o + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_i386/Makefile b/lib_i386/Makefile index ef0ba54..4cc29f4 100644 --- a/lib_i386/Makefile +++ b/lib_i386/Makefile @@ -25,13 +25,22 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = bios.o bios_pci.o realmode_switch.o - -COBJS = board.o bios_setup.o bootm.o zimage.o realmode.o \ - pci_type1.o pci.o video_bios.o video.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SOBJS-y += bios.o +SOBJS-y += bios_pci.o +SOBJS-y += realmode_switch.o + +COBJS-y += bios_setup.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += pci.o +COBJS-y += pci_type1.o +COBJS-y += realmode.o +COBJS-y += video_bios.o +COBJS-y += video.o +COBJS-y += zimage.o + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_m68k/Makefile b/lib_m68k/Makefile index d515223..f6924cd 100644 --- a/lib_m68k/Makefile +++ b/lib_m68k/Makefile @@ -25,12 +25,17 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = +SOBJS-y += -COBJS = cache.o traps.o time.o interrupts.o board.o bootm.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += interrupts.o +COBJS-y += time.o +COBJS-y += traps.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_microblaze/Makefile b/lib_microblaze/Makefile index 9b317a2..141b082 100644 --- a/lib_microblaze/Makefile +++ b/lib_microblaze/Makefile @@ -25,12 +25,15 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = +SOBJS-y += -COBJS = board.o bootm.o time.o cache.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += time.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_mips/Makefile b/lib_mips/Makefile index 93cca7a..799eaf2 100644 --- a/lib_mips/Makefile +++ b/lib_mips/Makefile @@ -25,12 +25,14 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = +SOBJS-y += -COBJS = board.o time.o bootm.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += time.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_nios/Makefile b/lib_nios/Makefile index d8ae7bd..c41d981 100644 --- a/lib_nios/Makefile +++ b/lib_nios/Makefile @@ -25,12 +25,17 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = +SOBJS-y += -COBJS = board.o cache.o divmod.o bootm.o mult.o time.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += divmod.o +COBJS-y += mult.o +COBJS-y += time.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_nios2/Makefile b/lib_nios2/Makefile index 5f996d3..717aa9b 100644 --- a/lib_nios2/Makefile +++ b/lib_nios2/Makefile @@ -25,12 +25,16 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = cache.o +SOBJS-y += cache.o -COBJS = board.o divmod.o bootm.o mult.o time.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += divmod.o +COBJS-y += mult.o +COBJS-y += time.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_ppc/Makefile b/lib_ppc/Makefile index 61507b0..3d76b70 100644 --- a/lib_ppc/Makefile +++ b/lib_ppc/Makefile @@ -25,14 +25,21 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = ppccache.o ppcstring.o ticks.o - -COBJS = board.o \ - bat_rw.o cache.o extable.o kgdb.o time.o interrupts.o \ - bootm.o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SOBJS-y += ppccache.o +SOBJS-y += ppcstring.o +SOBJS-y += ticks.o + +COBJS-y += bat_rw.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += extable.o +COBJS-y += interrupts.o +COBJS-y += kgdb.o +COBJS-y += time.o + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_sh/Makefile b/lib_sh/Makefile index edb03d0..a5772a0 100644 --- a/lib_sh/Makefile +++ b/lib_sh/Makefile @@ -22,12 +22,14 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = +SOBJS-y += -COBJS = board.o bootm.o # time.o +COBJS-y += board.o +COBJS-y += bootm.o +#COBJS-y += time.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) -- cgit v0.10.2 From 8a5ea3e6168fe6a2780eeaf257a3b19f30dec658 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 27 Feb 2008 11:01:04 +0100 Subject: [new uImage] Move image verify flag to bootm_headers structure Do not pass image verification flag directly to related routines. Simplify argument passing and move it to the bootm_header structure which contains curently processed image specific data and is already being passed on the argument list. Signed-off-by: Marian Balakowicz Acked-by: Kumar Gala diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 3f09988..ce2de2e 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -65,10 +65,8 @@ static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); static void fixup_silent_linux (void); #endif -static void *get_kernel (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], int verify, - bootm_headers_t *images, - ulong *os_data, ulong *os_len); +static void *get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char *argv[], + bootm_headers_t *images, ulong *os_data, ulong *os_len); extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* @@ -81,8 +79,7 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); */ typedef void boot_os_fn (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images,/* pointers to os/initrd/fdt */ - int verify); /* getenv("verify")[0] != 'n' */ + bootm_headers_t *images); /* pointers to os/initrd/fdt */ extern boot_os_fn do_bootm_linux; static boot_os_fn do_bootm_netbsd; @@ -114,7 +111,6 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong iflag; const char *type_name; uint unc_len = CFG_BOOTM_LEN; - int verify = getenv_verify(); uint8_t comp, type, os; void *os_hdr; @@ -123,9 +119,10 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong load_start, load_end; memset ((void *)&images, 0, sizeof (images)); + images.verify = getenv_verify(); /* get kernel image header, start address and length */ - os_hdr = get_kernel (cmdtp, flag, argc, argv, verify, + os_hdr = get_kernel (cmdtp, flag, argc, argv, &images, &os_data, &os_len); if (os_len == 0) return 1; @@ -246,36 +243,36 @@ 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, &images, verify); + do_bootm_linux (cmdtp, flag, argc, argv, &images); break; case IH_OS_NETBSD: - do_bootm_netbsd (cmdtp, flag, argc, argv, &images, verify); + do_bootm_netbsd (cmdtp, flag, argc, argv, &images); break; #ifdef CONFIG_LYNXKDI case IH_OS_LYNXOS: - do_bootm_lynxkdi (cmdtp, flag, argc, argv, &images, verify); + do_bootm_lynxkdi (cmdtp, flag, argc, argv, &images); break; #endif case IH_OS_RTEMS: - do_bootm_rtems (cmdtp, flag, argc, argv, &images, verify); + do_bootm_rtems (cmdtp, flag, argc, argv, &images); break; #if defined(CONFIG_CMD_ELF) case IH_OS_VXWORKS: - do_bootm_vxworks (cmdtp, flag, argc, argv, &images, verify); + do_bootm_vxworks (cmdtp, flag, argc, argv, &images); break; case IH_OS_QNX: - do_bootm_qnxelf (cmdtp, flag, argc, argv, &images, verify); + do_bootm_qnxelf (cmdtp, flag, argc, argv, &images); break; #endif #ifdef CONFIG_ARTOS case IH_OS_ARTOS: - do_bootm_artos (cmdtp, flag, argc, argv, &images, verify); + do_bootm_artos (cmdtp, flag, argc, argv, &images); break; #endif } @@ -300,10 +297,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * pointer to image header if valid image was found, plus kernel start * address and length, otherwise NULL */ -static void *get_kernel (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], int verify, - bootm_headers_t *images, - ulong *os_data, ulong *os_len) +static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images, ulong *os_data, ulong *os_len) { image_header_t *hdr; ulong img_addr; @@ -362,7 +357,7 @@ static void *get_kernel (cmd_tbl_t *cmdtp, int flag, show_boot_progress (3); image_print_contents (hdr); - if (verify) { + if (images->verify) { puts (" Verifying Checksum ... "); if (!image_check_dcrc (hdr)) { printf ("Bad Data CRC\n"); @@ -648,7 +643,7 @@ static void fixup_silent_linux () static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { void (*loader)(bd_t *, image_header_t *, char *, char *); image_header_t *os_hdr, *hdr; @@ -731,7 +726,7 @@ static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, #ifdef CONFIG_LYNXKDI static void do_bootm_lynxkdi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { image_header_t *hdr = images->legacy_hdr_os; @@ -748,7 +743,7 @@ static void do_bootm_lynxkdi (cmd_tbl_t *cmdtp, int flag, static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { image_header_t *hdr = images->legacy_hdr_os; void (*entry_point)(bd_t *); @@ -777,7 +772,7 @@ static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_CMD_ELF) static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { char str[80]; image_header_t *hdr = images->legacy_hdr_os; @@ -796,7 +791,7 @@ static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, static void do_bootm_qnxelf(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { char *local_args[2]; char str[16]; @@ -819,7 +814,7 @@ static void do_bootm_qnxelf(cmd_tbl_t *cmdtp, int flag, #if defined(CONFIG_ARTOS) && defined(CONFIG_PPC) static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { ulong top; char *s, *cmdline; diff --git a/common/image.c b/common/image.c index dd55264..5ca77b9 100644 --- a/common/image.c +++ b/common/image.c @@ -58,6 +58,10 @@ extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #endif DECLARE_GLOBAL_DATA_PTR; + +static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong rd_addr, uint8_t arch, int verify); #else #include "mkimage.h" #endif /* USE_HOSTCC*/ @@ -485,7 +489,7 @@ ulong gen_get_image (ulong img_addr) * pointer to a ramdisk image header, if image was found and valid * otherwise, board is reset */ -image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, +static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong rd_addr, uint8_t arch, int verify) { @@ -539,8 +543,7 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, * @flag: command flag * @argc: command argument count * @argv: command argument list - * @images: pointer to the bootm images strcture - * @verify: checksum verification flag + * @images: pointer to the bootm images structure * @arch: expected ramdisk architecture * @rd_start: pointer to a ulong variable, will hold ramdisk start address * @rd_end: pointer to a ulong variable, will hold ramdisk end @@ -557,7 +560,7 @@ image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, * board is reset if ramdisk image is found but corrupted */ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify, uint8_t arch, + bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end) { ulong rd_addr, rd_load; @@ -621,7 +624,7 @@ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], debug ("* ramdisk: legacy format image\n"); rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv, - rd_addr, arch, verify); + rd_addr, arch, images->verify); rd_data = image_get_data (rd_hdr); rd_len = image_get_data_size (rd_hdr); diff --git a/include/image.h b/include/image.h index 2f4b67d..1bc090a 100644 --- a/include/image.h +++ b/include/image.h @@ -202,6 +202,7 @@ typedef struct bootm_headers { void *fit_hdr_fdt; /* FDT blob FIT image header */ char *fit_uname_fdt; /* FDT blob node unit name */ #endif + int verify; /* getenv("verify")[0] != 'n' */ #endif } bootm_headers_t; @@ -380,12 +381,8 @@ void image_print_contents (image_header_t *hdr); int gen_image_get_format (void *img_addr); ulong gen_get_image (ulong img_addr); -image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong rd_addr, uint8_t arch, int verify); - void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify, uint8_t arch, + bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end); #if defined(CONFIG_PPC) || defined(CONFIG_M68K) diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index 4849c8a..e1a9ee2 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -62,7 +62,7 @@ static struct tag *params; extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { ulong initrd_start, initrd_end; ulong ep = 0; @@ -95,7 +95,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], printf ("Using machid 0x%x from environment\n", machid); } - get_ramdisk (cmdtp, flag, argc, argv, images, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_ARM, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index c449394..69a69df 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -174,7 +174,7 @@ static void setup_end_tag(struct tag *params) } void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { ulong initrd_start, initrd_end; ulong ep = 0; @@ -196,7 +196,7 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } theKernel = (void *)ep; - get_ramdisk (cmdtp, flag, argc, argv, images, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_AVR32, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_blackfin/bootm.c b/lib_blackfin/bootm.c index 8010e5d..26ac88b 100644 --- a/lib_blackfin/bootm.c +++ b/lib_blackfin/bootm.c @@ -47,7 +47,7 @@ extern void flush_data_cache(void); static char *make_command_line(void); void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { int (*appl) (char *cmdline); char *cmdline; diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c index 3a6497c..aea58d1 100644 --- a/lib_i386/bootm.c +++ b/lib_i386/bootm.c @@ -32,7 +32,7 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { void *base_ptr; ulong os_data, os_len; @@ -40,7 +40,7 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong ep; image_header_t *hdr; - get_ramdisk (cmdtp, flag, argc, argv, images, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_I386, &initrd_start, &initrd_end); if (images->legacy_hdr_valid) { diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index ce8be05..c611497 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -46,7 +46,7 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { ulong sp, sp_limit, alloc_current; @@ -95,7 +95,7 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - get_ramdisk (cmdtp, flag, argc, argv, images, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_M68K, &rd_data_start, &rd_data_end); rd_len = rd_data_end - rd_data_start; diff --git a/lib_microblaze/bootm.c b/lib_microblaze/bootm.c index 1455211..5881df6 100644 --- a/lib_microblaze/bootm.c +++ b/lib_microblaze/bootm.c @@ -35,7 +35,7 @@ DECLARE_GLOBAL_DATA_PTR; extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { /* First parameter is mapped to $r5 for kernel boot args */ void (*theKernel) (char *); diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c index 5c2f28e..998aa22 100644 --- a/lib_mips/bootm.c +++ b/lib_mips/bootm.c @@ -46,7 +46,7 @@ static void linux_env_set (char * env_name, char * env_val); extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { ulong initrd_start, initrd_end; ulong ep = 0; @@ -68,7 +68,7 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], } theKernel = (void (*)(int, char **, char **, int *))ep; - get_ramdisk (cmdtp, flag, argc, argv, images, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_MIPS, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_nios/bootm.c b/lib_nios/bootm.c index 92a58f2..fb2e9b5 100644 --- a/lib_nios/bootm.c +++ b/lib_nios/bootm.c @@ -29,6 +29,6 @@ * */ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { } diff --git a/lib_nios2/bootm.c b/lib_nios2/bootm.c index 56d1d19..70d2bb0 100644 --- a/lib_nios2/bootm.c +++ b/lib_nios2/bootm.c @@ -28,7 +28,7 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { ulong ep = 0; diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index d5e019e..319d4ba 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -59,10 +59,8 @@ static ulong get_sp (void); static void set_clocks_in_mhz (bd_t *kbd); void __attribute__((noinline)) -do_bootm_linux(cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - bootm_headers_t *images, - int verify) +do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images) { ulong sp, sp_limit, alloc_current; @@ -116,7 +114,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - get_ramdisk (cmdtp, flag, argc, argv, images, verify, + get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_PPC, &rd_data_start, &rd_data_end); rd_len = rd_data_end - rd_data_start; diff --git a/lib_sh/bootm.c b/lib_sh/bootm.c index 55e64f5..de5c9ea 100644 --- a/lib_sh/bootm.c +++ b/lib_sh/bootm.c @@ -60,7 +60,7 @@ static void hexdump (unsigned char *buf, int len) #endif void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, int verify) + bootm_headers_t *images) { ulong ep = 0; char *bootargs = getenv("bootargs"); -- cgit v0.10.2 From 1efd43601f90de21ec6c0ebb9880823e822927b1 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 27 Feb 2008 11:02:07 +0100 Subject: [new uImage] Add image_get_kernel() routine Legacy image specific verification is factored out to a separate helper routine to keep get_kernel() generic and simple. Signed-off-by: Marian Balakowicz Acked-by: Kumar Gala diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index ce2de2e..e5ed167 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -297,6 +297,57 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * pointer to image header if valid image was found, plus kernel start * address and length, otherwise NULL */ +static image_header_t *image_get_kernel (ulong img_addr, int verify) +{ + image_header_t *hdr = (image_header_t *)img_addr; + + if (!image_check_magic(hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-1); + return NULL; + } + show_boot_progress (2); + + if (!image_check_hcrc (hdr)) { + puts ("Bad Header Checksum\n"); + show_boot_progress (-2); + return NULL; + } + + show_boot_progress (3); + image_print_contents (hdr); + + if (verify) { + puts (" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + printf ("Bad Data CRC\n"); + show_boot_progress (-3); + return NULL; + } + puts ("OK\n"); + } + show_boot_progress (4); + + if (!image_check_target_arch (hdr)) { + printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr)); + show_boot_progress (-4); + return NULL; + } + return hdr; +} + +/** + * get_kernel - find kernel image + * @os_data: pointer to a ulong variable, will hold os data start address + * @os_len: pointer to a ulong variable, will hold os data length + * + * get_kernel() tries to find a kernel image, verifies its integrity + * and locates kernel data. + * + * returns: + * pointer to image header if valid image was found, plus kernel start + * address and length, otherwise NULL + */ static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, ulong *os_data, ulong *os_len) { @@ -339,40 +390,9 @@ static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], case IMAGE_FORMAT_LEGACY: debug ("* kernel: legacy format image\n"); - hdr = (image_header_t *)img_addr; - - if (!image_check_magic(hdr)) { - puts ("Bad Magic Number\n"); - show_boot_progress (-1); + hdr = image_get_kernel (img_addr, images->verify); + if (!hdr) return NULL; - } - show_boot_progress (2); - - if (!image_check_hcrc (hdr)) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-2); - return NULL; - } - - show_boot_progress (3); - image_print_contents (hdr); - - if (images->verify) { - puts (" Verifying Checksum ... "); - if (!image_check_dcrc (hdr)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-3); - return NULL; - } - puts ("OK\n"); - } - show_boot_progress (4); - - if (!image_check_target_arch (hdr)) { - printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr)); - show_boot_progress (-4); - return NULL; - } show_boot_progress (5); switch (image_get_type (hdr)) { -- cgit v0.10.2 From ff0734cff0fb5397ce2f4602f4f3e5ec9c8a36e8 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 27 Feb 2008 11:02:26 +0100 Subject: [new uImage] POWERPC: Add image_get_fdt() routine FDT blob may be passed either: (1) raw (2) or embedded in the legacy uImage (3) or embedded in the new uImage. For the (2) case embedding image must be verified before we get FDT from it. This patch factors out legacy image specific verification routine to the separate helper routine. Signed-off-by: Marian Balakowicz Acked-by: Kumar Gala diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 319d4ba..ad05bc5 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -237,6 +237,39 @@ static void fdt_error (const char *msg) puts (" - must RESET the board to recover.\n"); } +static image_header_t *image_get_fdt (ulong fdt_addr) +{ + image_header_t *fdt_hdr = (image_header_t *)fdt_addr; + + image_print_contents (fdt_hdr); + + puts (" Verifying Checksum ... "); + if (!image_check_hcrc (fdt_hdr)) { + fdt_error ("fdt header checksum invalid"); + return NULL; + } + + if (!image_check_dcrc (fdt_hdr)) { + fdt_error ("fdt checksum invalid"); + return NULL; + } + puts ("OK\n"); + + if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { + fdt_error ("uImage is not a fdt"); + return NULL; + } + if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { + fdt_error ("uImage is compressed"); + return NULL; + } + if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) { + fdt_error ("uImage data is not a fdt"); + return NULL; + } + return fdt_hdr; +} + static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size) { @@ -297,12 +330,17 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], case IMAGE_FORMAT_LEGACY: debug ("* fdt: legacy format image\n"); - fdt_hdr = (image_header_t *)fdt_addr; + /* verify fdt_addr points to a valid image header */ printf ("## Flattened Device Tree Legacy Image at %08lx\n", - fdt_hdr); - - image_print_contents (fdt_hdr); + fdt_addr); + fdt_hdr = image_get_fdt (fdt_addr); + if (!fdt_hdr) + do_reset (cmdtp, flag, argc, argv); + /* + * move image data to the load address, + * make sure we don't overwrite initial image + */ image_start = (ulong)fdt_hdr; image_end = image_get_image_end (fdt_hdr); @@ -313,35 +351,9 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_error ("fdt overwritten"); do_reset (cmdtp, flag, argc, argv); } - - puts (" Verifying Checksum ... "); - if (!image_check_hcrc (fdt_hdr)) { - fdt_error ("fdt header checksum invalid"); - do_reset (cmdtp, flag, argc, argv); - } - - if (!image_check_dcrc (fdt_hdr)) { - fdt_error ("fdt checksum invalid"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - - if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { - fdt_error ("uImage is not a fdt"); - do_reset (cmdtp, flag, argc, argv); - } - if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { - fdt_error ("uImage is compressed"); - do_reset (cmdtp, flag, argc, argv); - } - if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) { - fdt_error ("uImage data is not a fdt"); - do_reset (cmdtp, flag, argc, argv); - } - memmove ((void *)image_get_load (fdt_hdr), - (void *)image_get_data (fdt_hdr), - image_get_data_size (fdt_hdr)); + (void *)image_get_data (fdt_hdr), + image_get_data_size (fdt_hdr)); fdt_blob = (char *)image_get_load (fdt_hdr); break; -- cgit v0.10.2 From 4efbe9dbb129f857f27856936112c8c02f016be6 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 27 Feb 2008 11:02:26 +0100 Subject: [new uImage] Correct raw FDT blob handlig when CONFIG_FIT is disabled Dual format image code must properly handle all three FDT passing methods: - raw FDT blob passed - FDT blob embedded in the legacy uImage - FDT blob embedded in the new uImage This patch enables proper raw FDT handling when no FIT imaeg support is compiled in. This is a bit tricky as we must dected FIT format even when FIT uImage handling is not enabled as both FIT uImages and raw FDT blobs use tha same low level format (libfdt). Signed-off-by: Marian Balakowicz diff --git a/common/image.c b/common/image.c index 5ca77b9..c689b0e 100644 --- a/common/image.c +++ b/common/image.c @@ -375,6 +375,10 @@ void image_print_contents (image_header_t *hdr) * gen_image_get_format() checks whether provided address points to a valid * legacy or FIT image. * + * New uImage format and FDT blob are based on a libfdt. FDT blob + * may be passed directly or embedded in a FIT image. In both situations + * gen_image_get_format() must be able to dectect libfdt header. + * * returns: * image format type or IMAGE_FORMAT_INVALID if no image is present */ @@ -382,14 +386,14 @@ int gen_image_get_format (void *img_addr) { ulong format = IMAGE_FORMAT_INVALID; image_header_t *hdr; -#if defined(CONFIG_FIT) +#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) char *fit_hdr; #endif hdr = (image_header_t *)img_addr; if (image_check_magic(hdr)) format = IMAGE_FORMAT_LEGACY; -#if defined(CONFIG_FIT) +#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) else { fit_hdr = (char *)img_addr; if (fdt_check_header (fit_hdr) == 0) diff --git a/include/image.h b/include/image.h index 1bc090a..08566ea 100644 --- a/include/image.h +++ b/include/image.h @@ -376,8 +376,9 @@ const char* image_get_comp_name (uint8_t comp); void image_print_contents (image_header_t *hdr); #define IMAGE_FORMAT_INVALID 0x00 -#define IMAGE_FORMAT_LEGACY 0x01 -#define IMAGE_FORMAT_FIT 0x02 +#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */ +#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */ + int gen_image_get_format (void *img_addr); ulong gen_get_image (ulong img_addr); diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index ad05bc5..d80d69a 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -357,11 +357,15 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_blob = (char *)image_get_load (fdt_hdr); break; -#if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - - /* check FDT blob vs FIT hdr */ - if (fit_uname_config || fit_uname_fdt) { + /* + * This case will catch both: new uImage format + * (libfdt based) and raw FDT blob (also libfdt + * based). + */ +#if defined(CONFIG_FIT) + /* check FDT blob vs FIT blob */ + if (0) { /* FIXME: call FIT format verification */ /* * FIT image */ @@ -369,15 +373,17 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], debug ("* fdt: FIT format image\n"); fit_unsupported_reset ("PPC fdt"); do_reset (cmdtp, flag, argc, argv); - } else { + } else +#endif + { /* * FDT blob */ + debug ("* fdt: raw FDT blob\n"); printf ("## Flattened Device Tree blob at %08lx\n", fdt_blob); fdt_blob = (char *)fdt_addr; } break; -#endif default: fdt_error ("Did not find a cmdline Flattened Device Tree"); do_reset (cmdtp, flag, argc, argv); -- cgit v0.10.2 From a6612bdfe7ef37b9787b66800cf02aaded05fbeb Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:43 -0600 Subject: [new uImage] Don't pass kdb to ramdisk_high since we may not have one We don't actually need the kdb param as we are just using it to get bd->bi_memsize which we can get from gd->bd->bi_memsize. Also, if we boot via OF we might not actually fill out a kdb. Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz diff --git a/common/image.c b/common/image.c index c689b0e..92c067f 100644 --- a/common/image.c +++ b/common/image.c @@ -694,7 +694,6 @@ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * ramdisk_high - relocate init ramdisk * @rd_data: ramdisk data start address * @rd_len: ramdisk data length - * @kbd: kernel board info copy (within BOOTMAPSZ boundary) * @sp_limit: stack pointer limit (including BOOTMAPSZ) * @sp: current stack pointer * @initrd_start: pointer to a ulong variable, will hold final init ramdisk @@ -712,7 +711,7 @@ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * - returns new allc_current, next free address below BOOTMAPSZ */ ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, - bd_t *kbd, ulong sp_limit, ulong sp, + ulong sp_limit, ulong sp, ulong *initrd_start, ulong *initrd_end) { char *s; @@ -734,9 +733,9 @@ ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, #ifdef CONFIG_LOGBUFFER /* 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); + if (initrd_high < (gd->bd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD)) + initrd_high = gd->bd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD; + debug ("## Logbuffer at 0x%08lx ", gd->bd->bi_memsize - LOGBUFF_LEN); #endif debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n", initrd_high, initrd_copy_to_ram); diff --git a/include/image.h b/include/image.h index 08566ea..1cec1db 100644 --- a/include/image.h +++ b/include/image.h @@ -388,7 +388,7 @@ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CONFIG_PPC) || defined(CONFIG_M68K) ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, - bd_t *kbd, ulong sp_limit, ulong sp, + ulong sp_limit, ulong sp, ulong *initrd_start, ulong *initrd_end); ulong get_boot_sp_limit (ulong sp); diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index c611497..74240af 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -100,8 +100,7 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, rd_len = rd_data_end - rd_data_start; alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, - kbd, sp_limit, get_sp (), - &initrd_start, &initrd_end); + sp_limit, get_sp (), &initrd_start, &initrd_end); debug("## Transferring control to Linux (at address %08lx) ...\n", (ulong) kernel); diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index d80d69a..fa28b43 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -120,8 +120,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], rd_len = rd_data_end - rd_data_start; alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, - kbd, sp_limit, get_sp (), - &initrd_start, &initrd_end); + sp_limit, get_sp (), &initrd_start, &initrd_end); #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ -- cgit v0.10.2 From 27953493ef025fb698d68c5dee39b36f01f4d530 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:44 -0600 Subject: [new uImage] ppc: Determine if we are booting an OF style If we are bootin OF style than we can skip setting up some things that are used for the old boot method. Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index fa28b43..3e89da1 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -71,10 +71,10 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bd_t *kbd; ulong ep = 0; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); + ulong of_size = 0; #if defined(CONFIG_OF_LIBFDT) char *of_flat_tree = NULL; - ulong of_size = 0; #endif /* @@ -92,12 +92,19 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], alloc_current = sp_limit = get_boot_sp_limit(sp); debug ("=> set upper limit to 0x%08lx\n", sp_limit); - /* allocate space and init command line */ - alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end); +#if defined(CONFIG_OF_LIBFDT) + /* find flattened device tree */ + get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); +#endif - /* allocate space for kernel copy of board info */ - alloc_current = get_boot_kbd (alloc_current, &kbd); - set_clocks_in_mhz(kbd); + if (!of_size) { + /* allocate space and init command line */ + alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end); + + /* allocate space for kernel copy of board info */ + alloc_current = get_boot_kbd (alloc_current, &kbd); + set_clocks_in_mhz(kbd); + } /* find kernel entry point */ if (images->legacy_hdr_valid) { @@ -123,9 +130,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], sp_limit, get_sp (), &initrd_start, &initrd_end); #if defined(CONFIG_OF_LIBFDT) - /* find flattened device tree */ - get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); - alloc_current = fdt_relocate (alloc_current, cmdtp, flag, argc, argv, &of_flat_tree, &of_size); -- cgit v0.10.2 From d2bc095a639672def11d5d043b5688d0dbd692ec Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:45 -0600 Subject: [new uImage] ppc: Re-order ramdisk/fdt handling sequence Doing the fdt before the ramdisk allows us to grow the fdt w/o concern however it does mean we have to go in and fixup the initrd info since we don't know where it will be. Signed-off-by: Kumar Gala diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 3e89da1..de6995e 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -71,6 +71,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bd_t *kbd; ulong ep = 0; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); + int ret; ulong of_size = 0; #if defined(CONFIG_OF_LIBFDT) @@ -126,9 +127,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], rd_len = rd_data_end - rd_data_start; - alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, - sp_limit, get_sp (), &initrd_start, &initrd_end); - #if defined(CONFIG_OF_LIBFDT) alloc_current = fdt_relocate (alloc_current, cmdtp, flag, argc, argv, &of_flat_tree, &of_size); @@ -138,7 +136,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * if the user wants it (the logic is in the subroutines). */ if (of_size) { - if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { + /* pass in dummy initrd info, we'll fix up later */ + if (fdt_chosen(of_flat_tree, rd_data_start, rd_data_end, 0) < 0) { fdt_error ("/chosen node create failed"); do_reset (cmdtp, flag, argc, argv); } @@ -161,6 +160,38 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } #endif /* CONFIG_OF_LIBFDT */ + alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, + sp_limit, get_sp (), &initrd_start, &initrd_end); + +#if defined(CONFIG_OF_LIBFDT) + /* fixup the initrd now that we know where it should be */ + if ((of_flat_tree) && (initrd_start && initrd_end)) { + uint64_t addr, size; + int total = fdt_num_mem_rsv(of_flat_tree); + int j; + + /* Look for the dummy entry and delete it */ + for (j = 0; j < total; j++) { + fdt_get_mem_rsv(of_flat_tree, j, &addr, &size); + if (addr == rd_data_start) { + fdt_del_mem_rsv(of_flat_tree, j); + break; + } + } + + ret = fdt_add_mem_rsv(of_flat_tree, initrd_start, + initrd_end - initrd_start + 1); + if (ret < 0) { + printf("fdt_chosen: %s\n", fdt_strerror(ret)); + do_reset (cmdtp, flag, argc, argv); + } + + do_fixup_by_path_u32(of_flat_tree, "/chosen", + "linux,initrd-start", initrd_start, 0); + do_fixup_by_path_u32(of_flat_tree, "/chosen", + "linux,initrd-end", initrd_end, 0); + } +#endif debug ("## Transferring control to Linux (at address %08lx) ...\n", (ulong)kernel); -- cgit v0.10.2 From 274cea2bddbca10cdad7daa518951b75c44ef6bc Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:46 -0600 Subject: [new uImage] rework error handling so common functions don't reset Changed image_get_ramdisk() to just return NULL on error and have get_ramdisk() propogate that error to the caller. It's left to the caller to call do_reset() if it wants to. Also moved calling do_reset() in get_fdt() and fdt_relocate() on ppc to a common location. In the future we will change get_fdt() and fdt_relocate() to return success/failure and not call do_reset() at all. Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz diff --git a/common/image.c b/common/image.c index 92c067f..d4acb6b 100644 --- a/common/image.c +++ b/common/image.c @@ -51,8 +51,6 @@ #include #endif -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - #ifdef CONFIG_CMD_BDI extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #endif @@ -491,7 +489,7 @@ ulong gen_get_image (ulong img_addr) * * returns: * pointer to a ramdisk image header, if image was found and valid - * otherwise, board is reset + * otherwise, return NULL */ static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], @@ -505,13 +503,13 @@ static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, if (!image_check_magic (rd_hdr)) { puts ("Bad Magic Number\n"); show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); + return NULL; } if (!image_check_hcrc (rd_hdr)) { puts ("Bad Header Checksum\n"); show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); + return NULL; } show_boot_progress (10); @@ -522,7 +520,7 @@ static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) { puts ("Bad Data CRC\n"); show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); + return NULL; } puts("OK\n"); } @@ -535,7 +533,7 @@ static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, printf ("No Linux %s Ramdisk Image\n", image_get_arch_name(arch)); show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); + return NULL; } return rd_hdr; @@ -561,9 +559,9 @@ static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, * rd_start and rd_end are set to ramdisk start/end addresses if * ramdisk image is found and valid * rd_start and rd_end are set to 0 if no ramdisk exists - * board is reset if ramdisk image is found but corrupted + * return 1 if ramdisk image is found but corrupted */ -void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end) { @@ -630,6 +628,12 @@ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv, rd_addr, arch, images->verify); + if (rd_hdr == NULL) { + *rd_start = 0; + *rd_end = 0; + return 1; + } + rd_data = image_get_data (rd_hdr); rd_len = image_get_data_size (rd_hdr); rd_load = image_get_load (rd_hdr); @@ -639,7 +643,7 @@ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fit_hdr = (void *)rd_addr; debug ("* ramdisk: FIT format image\n"); fit_unsupported_reset ("ramdisk"); - do_reset (cmdtp, flag, argc, argv); + return 1; #endif default: printf ("Wrong Image Format for %s command\n", @@ -687,6 +691,8 @@ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } debug (" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n", *rd_start, *rd_end); + + return 0; } #if defined(CONFIG_PPC) || defined(CONFIG_M68K) diff --git a/include/image.h b/include/image.h index 1cec1db..025ec0f 100644 --- a/include/image.h +++ b/include/image.h @@ -382,7 +382,7 @@ void image_print_contents (image_header_t *hdr); int gen_image_get_format (void *img_addr); ulong gen_get_image (ulong img_addr); -void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end); diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index 74240af..c9d2a27 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -35,6 +35,8 @@ DECLARE_GLOBAL_DATA_PTR; +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + #define PHYSADDR(x) x #define LINUX_MAX_ENVS 256 @@ -52,6 +54,7 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, ulong rd_data_start, rd_data_end, rd_len; ulong initrd_start, initrd_end; + int ret; ulong cmd_start, cmd_end; bd_t *kbd; @@ -95,9 +98,12 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - get_ramdisk (cmdtp, flag, argc, argv, images, + ret = get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_M68K, &rd_data_start, &rd_data_end); + if (ret) + goto error; + rd_len = rd_data_end - rd_data_start; alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, sp_limit, get_sp (), &initrd_start, &initrd_end); @@ -117,6 +123,11 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, */ (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); /* does not return */ + return ; + +error: + do_reset (cmdtp, flag, argc, argv); + return ; } static ulong get_sp (void) diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index de6995e..9f48b8d 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -41,7 +41,7 @@ #include static void fdt_error (const char *msg); -static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size); static ulong fdt_relocate (ulong alloc_current, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], @@ -95,7 +95,10 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ - get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); + ret = get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); + + if (ret) + goto error; #endif if (!of_size) { @@ -113,18 +116,21 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { fit_unsupported_reset ("PPC linux bootm"); - do_reset (cmdtp, flag, argc, argv); + goto error; #endif } else { puts ("Could not find kernel entry point!\n"); - do_reset (cmdtp, flag, argc, argv); + goto error; } kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - get_ramdisk (cmdtp, flag, argc, argv, images, + ret = get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_PPC, &rd_data_start, &rd_data_end); + if (ret) + goto error; + rd_len = rd_data_end - rd_data_start; #if defined(CONFIG_OF_LIBFDT) @@ -139,18 +145,18 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* pass in dummy initrd info, we'll fix up later */ if (fdt_chosen(of_flat_tree, rd_data_start, rd_data_end, 0) < 0) { fdt_error ("/chosen node create failed"); - do_reset (cmdtp, flag, argc, argv); + goto error; } #ifdef CONFIG_OF_HAS_UBOOT_ENV if (fdt_env(of_flat_tree) < 0) { fdt_error ("/u-boot-env node create failed"); - do_reset (cmdtp, flag, argc, argv); + goto error; } #endif #ifdef CONFIG_OF_HAS_BD_T if (fdt_bd_t(of_flat_tree) < 0) { fdt_error ("/bd_t node create failed"); - do_reset (cmdtp, flag, argc, argv); + goto error; } #endif #ifdef CONFIG_OF_BOARD_SETUP @@ -183,7 +189,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], initrd_end - initrd_start + 1); if (ret < 0) { printf("fdt_chosen: %s\n", fdt_strerror(ret)); - do_reset (cmdtp, flag, argc, argv); + goto error; } do_fixup_by_path_u32(of_flat_tree, "/chosen", @@ -225,6 +231,11 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], */ (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); /* does not return */ + return ; + +error: + do_reset (cmdtp, flag, argc, argv); + return ; } static ulong get_sp (void) @@ -304,7 +315,7 @@ static image_header_t *image_get_fdt (ulong fdt_addr) return fdt_hdr; } -static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size) { ulong fdt_addr; @@ -369,7 +380,7 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_addr); fdt_hdr = image_get_fdt (fdt_addr); if (!fdt_hdr) - do_reset (cmdtp, flag, argc, argv); + goto error; /* * move image data to the load address, @@ -383,7 +394,7 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if ((load_start < image_end) && (load_end > image_start)) { fdt_error ("fdt overwritten"); - do_reset (cmdtp, flag, argc, argv); + goto error; } memmove ((void *)image_get_load (fdt_hdr), (void *)image_get_data (fdt_hdr), @@ -406,7 +417,7 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fit_hdr = (void *)fdt_addr; debug ("* fdt: FIT format image\n"); fit_unsupported_reset ("PPC fdt"); - do_reset (cmdtp, flag, argc, argv); + goto error; } else #endif { @@ -420,7 +431,7 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], break; default: fdt_error ("Did not find a cmdline Flattened Device Tree"); - do_reset (cmdtp, flag, argc, argv); + goto error; } printf (" Booting using the fdt blob at 0x%x\n", fdt_blob); @@ -446,29 +457,35 @@ static void get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (fdt_check_header (fdt_blob) != 0) { fdt_error ("image is not a fdt"); - do_reset (cmdtp, flag, argc, argv); + goto error; } if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { fdt_error ("fdt size != image size"); - do_reset (cmdtp, flag, argc, argv); + goto error; } } else { fdt_error ("Did not find a Flattened Device Tree " "in a legacy multi-component image"); - do_reset (cmdtp, flag, argc, argv); + goto error; } } else { debug ("## No Flattened Device Tree\n"); *of_flat_tree = NULL; *of_size = 0; - return; + return 0; } *of_flat_tree = fdt_blob; *of_size = be32_to_cpu (fdt_totalsize (fdt_blob)); debug (" of_flat_tree at 0x%08lx size 0x%08lx\n", *of_flat_tree, *of_size); + + return 0; + +error: + do_reset (cmdtp, flag, argc, argv); + return 1; } static ulong fdt_relocate (ulong alloc_current, @@ -485,7 +502,7 @@ static ulong fdt_relocate (ulong alloc_current, if (fdt_check_header (fdt_blob) != 0) { fdt_error ("image is not a fdt"); - do_reset (cmdtp, flag, argc, argv); + goto error; } #ifndef CFG_NO_FLASH @@ -524,7 +541,7 @@ static ulong fdt_relocate (ulong alloc_current, err = fdt_open_into (fdt_blob, (void *)of_start, of_len); if (err != 0) { fdt_error ("fdt move failed"); - do_reset (cmdtp, flag, argc, argv); + goto error; } puts ("OK\n"); @@ -536,5 +553,9 @@ static ulong fdt_relocate (ulong alloc_current, } return new_alloc_current; + +error: + do_reset (cmdtp, flag, argc, argv); + return 1; } #endif -- cgit v0.10.2 From 4648c2e7a173b0d7f17bef4adaa0623090c9e904 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 19 Feb 2008 22:03:47 -0600 Subject: [new uImage] ppc: Allow boards to specify effective amount of memory For historical reasons we limited the stack to 256M because some boards could only map that much via BATS. However newer boards are capable of mapping more memory (for example 85xx is capable of doing up to 2G). Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz diff --git a/lib_ppc/board.c b/lib_ppc/board.c index 45d1328..fbf1c5d 100644 --- a/lib_ppc/board.c +++ b/lib_ppc/board.c @@ -361,6 +361,20 @@ init_fnc_t *init_sequence[] = { NULL, /* Terminate this list */ }; +#ifndef CONFIG_MAX_MEM_MAPPED +#define CONFIG_MAX_MEM_MAPPED (256 << 20) +#endif +ulong get_effective_memsize(void) +{ +#ifndef CONFIG_VERY_BIG_RAM + return gd->ram_size; +#else + /* limit stack to what we can reasonable map */ + return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ? + CONFIG_MAX_MEM_MAPPED : gd->ram_size); +#endif +} + /************************************************************************ * * This is the first part of the initialization sequence that is @@ -419,13 +433,7 @@ void board_init_f (ulong bootflag) */ len = (ulong)&_end - CFG_MONITOR_BASE; -#ifndef CONFIG_VERY_BIG_RAM - addr = CFG_SDRAM_BASE + gd->ram_size; -#else - /* only allow stack below 256M */ - addr = CFG_SDRAM_BASE + - (gd->ram_size > 256 << 20) ? 256 << 20 : gd->ram_size; -#endif + addr = CFG_SDRAM_BASE + get_effective_memsize(); #ifdef CONFIG_LOGBUFFER /* reserve kernel log buffer */ -- cgit v0.10.2 From 4ed6552f715983bfc7d212c1199a1f796f1144ad Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:47 -0600 Subject: [new uImage] Introduce lmb from linux kernel for memory mgmt of boot images Introduce the LMB lib used on PPC in the kernel as a clean way to manage the memory spaces used by various boot images and structures. This code will allow us to simplify the code in bootm and its support functions. Signed-off-by: Kumar Gala diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index e5ed167..92c18d0 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #ifdef CFG_HUSH_PARSER @@ -118,8 +119,19 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong image_start, image_end; ulong load_start, load_end; + struct lmb lmb; + memset ((void *)&images, 0, sizeof (images)); images.verify = getenv_verify(); + images.lmb = &lmb; + + lmb_init(&lmb); + +#ifdef CFG_SDRAM_BASE + lmb_add(&lmb, CFG_SDRAM_BASE, gd->bd->bi_memsize); +#else + lmb_add(&lmb, 0, gd->bd->bi_memsize); +#endif /* get kernel image header, start address and length */ os_hdr = get_kernel (cmdtp, flag, argc, argv, @@ -237,6 +249,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress (8); + lmb_reserve(&lmb, load_start, (load_end - load_start)); + switch (os) { default: /* handled by (original) Linux case */ case IH_OS_LINUX: diff --git a/include/image.h b/include/image.h index 025ec0f..cb4acd8 100644 --- a/include/image.h +++ b/include/image.h @@ -37,6 +37,7 @@ #include #ifndef USE_HOSTCC +#include #include #include @@ -203,6 +204,7 @@ typedef struct bootm_headers { char *fit_uname_fdt; /* FDT blob node unit name */ #endif int verify; /* getenv("verify")[0] != 'n' */ + struct lmb *lmb; /* for memory mgmt */ #endif } bootm_headers_t; diff --git a/include/lmb.h b/include/lmb.h new file mode 100644 index 0000000..cc64cbb --- /dev/null +++ b/include/lmb.h @@ -0,0 +1,54 @@ +#ifndef _LINUX_LMB_H +#define _LINUX_LMB_H +#ifdef __KERNEL__ + +#include +/* + * Logical memory blocks. + * + * Copyright (C) 2001 Peter Bergner, IBM Corp. + * + * 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. + */ + +#define MAX_LMB_REGIONS 8 + +struct lmb_property { + ulong base; + ulong size; +}; + +struct lmb_region { + unsigned long cnt; + ulong size; + struct lmb_property region[MAX_LMB_REGIONS+1]; +}; + +struct lmb { + struct lmb_region memory; + struct lmb_region reserved; +}; + +extern struct lmb lmb; + +extern void lmb_init(struct lmb *lmb); +extern long lmb_add(struct lmb *lmb, ulong base, ulong size); +extern long lmb_reserve(struct lmb *lmb, ulong base, ulong size); +extern ulong lmb_alloc(struct lmb *lmb, ulong size, ulong align); +extern ulong lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr); +extern ulong __lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr); +extern int lmb_is_reserved(struct lmb *lmb, ulong addr); + +extern void lmb_dump_all(struct lmb *lmb); + +static inline ulong +lmb_size_bytes(struct lmb_region *type, unsigned long region_nr) +{ + return type->region[region_nr].size; +} +#endif /* __KERNEL__ */ + +#endif /* _LINUX_LMB_H */ diff --git a/lib_generic/Makefile b/lib_generic/Makefile index 9713353..b10793b 100644 --- a/lib_generic/Makefile +++ b/lib_generic/Makefile @@ -34,6 +34,7 @@ COBJS-y += crc32.o COBJS-y += ctype.o COBJS-y += display_options.o COBJS-y += div64.o +COBJS-y += lmb.o COBJS-y += ldiv.o COBJS-y += sha1.o COBJS-y += string.o diff --git a/lib_generic/lmb.c b/lib_generic/lmb.c new file mode 100644 index 0000000..3b8c805 --- /dev/null +++ b/lib_generic/lmb.c @@ -0,0 +1,280 @@ +/* + * Procedures for maintaining information about logical memory blocks. + * + * Peter Bergner, IBM Corp. June 2001. + * Copyright (C) 2001 Peter Bergner. + * + * 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. + */ + +#include +#include + +#define LMB_ALLOC_ANYWHERE 0 + +void lmb_dump_all(struct lmb *lmb) +{ +#ifdef DEBUG + unsigned long i; + + debug("lmb_dump_all:\n"); + debug(" memory.cnt = 0x%lx\n", lmb->memory.cnt); + debug(" memory.size = 0x%08x\n", lmb->memory.size); + for (i=0; i < lmb->memory.cnt ;i++) { + debug(" memory.reg[0x%x].base = 0x%08x\n", i, + lmb->memory.region[i].base); + debug(" .size = 0x%08x\n", + lmb->memory.region[i].size); + } + + debug("\n reserved.cnt = 0x%lx\n", lmb->reserved.cnt); + debug(" reserved.size = 0x%08x\n", lmb->reserved.size); + for (i=0; i < lmb->reserved.cnt ;i++) { + debug(" reserved.reg[0x%x].base = 0x%08x\n", i, + lmb->reserved.region[i].base); + debug(" .size = 0x%08x\n", + lmb->reserved.region[i].size); + } +#endif /* DEBUG */ +} + +static unsigned long lmb_addrs_overlap(ulong base1, + ulong size1, ulong base2, ulong size2) +{ + return ((base1 < (base2+size2)) && (base2 < (base1+size1))); +} + +static long lmb_addrs_adjacent(ulong base1, ulong size1, + ulong base2, ulong size2) +{ + if (base2 == base1 + size1) + return 1; + else if (base1 == base2 + size2) + return -1; + + return 0; +} + +static long lmb_regions_adjacent(struct lmb_region *rgn, + unsigned long r1, unsigned long r2) +{ + ulong base1 = rgn->region[r1].base; + ulong size1 = rgn->region[r1].size; + ulong base2 = rgn->region[r2].base; + ulong size2 = rgn->region[r2].size; + + return lmb_addrs_adjacent(base1, size1, base2, size2); +} + +static void lmb_remove_region(struct lmb_region *rgn, unsigned long r) +{ + unsigned long i; + + for (i = r; i < rgn->cnt - 1; i++) { + rgn->region[i].base = rgn->region[i + 1].base; + rgn->region[i].size = rgn->region[i + 1].size; + } + rgn->cnt--; +} + +/* Assumption: base addr of region 1 < base addr of region 2 */ +static void lmb_coalesce_regions(struct lmb_region *rgn, + unsigned long r1, unsigned long r2) +{ + rgn->region[r1].size += rgn->region[r2].size; + lmb_remove_region(rgn, r2); +} + +void lmb_init(struct lmb *lmb) +{ + /* Create a dummy zero size LMB which will get coalesced away later. + * This simplifies the lmb_add() code below... + */ + lmb->memory.region[0].base = 0; + lmb->memory.region[0].size = 0; + lmb->memory.cnt = 1; + lmb->memory.size = 0; + + /* Ditto. */ + lmb->reserved.region[0].base = 0; + lmb->reserved.region[0].size = 0; + lmb->reserved.cnt = 1; + lmb->reserved.size = 0; +} + +/* This routine called with relocation disabled. */ +static long lmb_add_region(struct lmb_region *rgn, ulong base, ulong size) +{ + unsigned long coalesced = 0; + long adjacent, i; + + if ((rgn->cnt == 1) && (rgn->region[0].size == 0)) { + rgn->region[0].base = base; + rgn->region[0].size = size; + return 0; + } + + /* First try and coalesce this LMB with another. */ + for (i=0; i < rgn->cnt; i++) { + ulong rgnbase = rgn->region[i].base; + ulong rgnsize = rgn->region[i].size; + + if ((rgnbase == base) && (rgnsize == size)) + /* Already have this region, so we're done */ + return 0; + + adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize); + if ( adjacent > 0 ) { + rgn->region[i].base -= size; + rgn->region[i].size += size; + coalesced++; + break; + } + else if ( adjacent < 0 ) { + rgn->region[i].size += size; + coalesced++; + break; + } + } + + if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) { + lmb_coalesce_regions(rgn, i, i+1); + coalesced++; + } + + if (coalesced) + return coalesced; + if (rgn->cnt >= MAX_LMB_REGIONS) + return -1; + + /* Couldn't coalesce the LMB, so add it to the sorted table. */ + for (i = rgn->cnt-1; i >= 0; i--) { + if (base < rgn->region[i].base) { + rgn->region[i+1].base = rgn->region[i].base; + rgn->region[i+1].size = rgn->region[i].size; + } else { + rgn->region[i+1].base = base; + rgn->region[i+1].size = size; + break; + } + } + + if (base < rgn->region[0].base) { + rgn->region[0].base = base; + rgn->region[0].size = size; + } + + rgn->cnt++; + + return 0; +} + +/* This routine may be called with relocation disabled. */ +long lmb_add(struct lmb *lmb, ulong base, ulong size) +{ + struct lmb_region *_rgn = &(lmb->memory); + + return lmb_add_region(_rgn, base, size); +} + +long lmb_reserve(struct lmb *lmb, ulong base, ulong size) +{ + struct lmb_region *_rgn = &(lmb->reserved); + + return lmb_add_region(_rgn, base, size); +} + +long lmb_overlaps_region(struct lmb_region *rgn, ulong base, + ulong size) +{ + unsigned long i; + + for (i=0; i < rgn->cnt; i++) { + ulong rgnbase = rgn->region[i].base; + ulong rgnsize = rgn->region[i].size; + if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) { + break; + } + } + + return (i < rgn->cnt) ? i : -1; +} + +ulong lmb_alloc(struct lmb *lmb, ulong size, ulong align) +{ + return lmb_alloc_base(lmb, size, align, LMB_ALLOC_ANYWHERE); +} + +ulong lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr) +{ + ulong alloc; + + alloc = __lmb_alloc_base(lmb, size, align, max_addr); + + if (alloc == 0) + printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", + size, max_addr); + + return alloc; +} + +static ulong lmb_align_down(ulong addr, ulong size) +{ + return addr & ~(size - 1); +} + +static ulong lmb_align_up(ulong addr, ulong size) +{ + return (addr + (size - 1)) & ~(size - 1); +} + +ulong __lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr) +{ + long i, j; + ulong base = 0; + + for (i = lmb->memory.cnt-1; i >= 0; i--) { + ulong lmbbase = lmb->memory.region[i].base; + ulong lmbsize = lmb->memory.region[i].size; + + if (max_addr == LMB_ALLOC_ANYWHERE) + base = lmb_align_down(lmbbase + lmbsize - size, align); + else if (lmbbase < max_addr) { + base = min(lmbbase + lmbsize, max_addr); + base = lmb_align_down(base - size, align); + } else + continue; + + while ((lmbbase <= base) && + ((j = lmb_overlaps_region(&(lmb->reserved), base, size)) >= 0) ) + base = lmb_align_down(lmb->reserved.region[j].base - size, + align); + + if ((base != 0) && (lmbbase <= base)) + break; + } + + if (i < 0) + return 0; + + if (lmb_add_region(&(lmb->reserved), base, lmb_align_up(size, align)) < 0) + return 0; + + return base; +} + +int lmb_is_reserved(struct lmb *lmb, ulong addr) +{ + int i; + + for (i = 0; i < lmb->reserved.cnt; i++) { + ulong upper = lmb->reserved.region[i].base + + lmb->reserved.region[i].size - 1; + if ((addr >= lmb->reserved.region[i].base) && (addr <= upper)) + return 1; + } + return 0; +} -- cgit v0.10.2 From f5614e7926863bf0225ec860d9b319741a9c4004 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:48 -0600 Subject: [new uImage] Add autostart flag to bootm_headers structure The autostart env variable was dropped as part of the initial new uImage cleanup. Add it back here so the arch specific code can decide if it wants to really boot or not. Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 92c18d0..92c2f4e 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -123,6 +123,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) memset ((void *)&images, 0, sizeof (images)); images.verify = getenv_verify(); + images.autostart = getenv_autostart(); images.lmb = &lmb; lmb_init(&lmb); diff --git a/common/image.c b/common/image.c index d4acb6b..4f2ff9c 100644 --- a/common/image.c +++ b/common/image.c @@ -126,6 +126,12 @@ int getenv_verify (void) return (s && (*s == 'n')) ? 0 : 1; } +int getenv_autostart (void) +{ + char *s = getenv ("autostart"); + 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) diff --git a/include/image.h b/include/image.h index cb4acd8..5ce2ca4 100644 --- a/include/image.h +++ b/include/image.h @@ -204,6 +204,7 @@ typedef struct bootm_headers { char *fit_uname_fdt; /* FDT blob node unit name */ #endif int verify; /* getenv("verify")[0] != 'n' */ + int autostart; /* getenv("autostart")[0] != 'n' */ struct lmb *lmb; /* for memory mgmt */ #endif } bootm_headers_t; @@ -314,6 +315,7 @@ int image_check_dcrc (image_header_t *hdr); #ifndef USE_HOSTCC int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize); int getenv_verify (void); +int getenv_autostart (void); void memmove_wd (void *to, void *from, size_t len, ulong chunksz); #endif -- cgit v0.10.2 From e822d7fc4dd4755d4d0a22f05e33f33d1a0481da Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:49 -0600 Subject: [new uImage] Use lmb for bootm allocations Convert generic ramdisk_high(), get_boot_cmdline(), get_boot_kbd() functions over to using lmb for allocation of the ramdisk, command line and kernel bd info. Convert PPC specific fdt_relocate() to use lmb for allocation of the device tree. Provided a weak function that board code can call to do additional lmb reserves if needed. Also introduce the concept of bootmap_base to specify the offset in physical memory that the bootmap is located at. This is used for allocations of the cmdline, kernel bd, and device tree as they should be contained within bootmap_base and bootmap_base + CFG_BOOTMAPSZ. Signed-off-by: Kumar Gala diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 92c2f4e..a32a5a2 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -103,6 +103,12 @@ static boot_os_fn do_bootm_artos; ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ static bootm_headers_t images; /* pointers to os/initrd/fdt images */ +void __board_lmb_reserve(struct lmb *lmb) +{ + /* please define platform specific board_lmb_reserve() */ +} +void board_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__board_lmb_reserve"))); + /*******************************************************************/ /* bootm - boot application image from image in memory */ @@ -134,6 +140,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) lmb_add(&lmb, 0, gd->bd->bi_memsize); #endif + board_lmb_reserve(&lmb); + /* get kernel image header, start address and length */ os_hdr = get_kernel (cmdtp, flag, argc, argv, &images, &os_data, &os_len); diff --git a/common/image.c b/common/image.c index 4f2ff9c..0b71811 100644 --- a/common/image.c +++ b/common/image.c @@ -704,10 +704,9 @@ int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CONFIG_PPC) || defined(CONFIG_M68K) /** * ramdisk_high - relocate init ramdisk + * @lmb: pointer to lmb handle, will be used for memory mgmt * @rd_data: ramdisk data start address * @rd_len: ramdisk data length - * @sp_limit: stack pointer limit (including BOOTMAPSZ) - * @sp: current stack pointer * @initrd_start: pointer to a ulong variable, will hold final init ramdisk * start address (after possible relocation) * @initrd_end: pointer to a ulong variable, will hold final init ramdisk @@ -720,16 +719,16 @@ int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * - initrd_start and initrd_end are set to final (after relocation) ramdisk * start/end addresses if ramdisk image start and len were provided * otherwise set initrd_start and initrd_end set to zeros - * - returns new allc_current, next free address below BOOTMAPSZ + * - returns: + * 0 - success + * -1 - failure */ -ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, - ulong sp_limit, ulong sp, - ulong *initrd_start, ulong *initrd_end) +int ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, + ulong *initrd_start, ulong *initrd_end) { char *s; ulong initrd_high; int initrd_copy_to_ram = 1; - ulong new_alloc_current = alloc_current; if ((s = getenv ("initrd_high")) != NULL) { /* a value of "no" or a similar string will act like 0, @@ -743,12 +742,6 @@ ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, initrd_high = ~0; } -#ifdef CONFIG_LOGBUFFER - /* Prevent initrd from overwriting logbuffer */ - if (initrd_high < (gd->bd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD)) - initrd_high = gd->bd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD; - debug ("## Logbuffer at 0x%08lx ", gd->bd->bi_memsize - LOGBUFF_LEN); -#endif debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n", initrd_high, initrd_copy_to_ram); @@ -757,40 +750,17 @@ ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, debug (" in-place initrd\n"); *initrd_start = rd_data; *initrd_end = rd_data + rd_len; + lmb_reserve(lmb, rd_data, rd_len); } else { - new_alloc_current = alloc_current - rd_len; - *initrd_start = new_alloc_current; - *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 - * for command line args and board info. - */ - nsp = sp; - nsp -= 2048; /* just to be sure */ - nsp &= ~0xF; - - if (nsp > initrd_high) /* limit as specified */ - nsp = initrd_high; - - nsp -= rd_len; - nsp &= ~(4096 - 1); /* align on page */ - - if (nsp >= sp_limit) { - *initrd_start = nsp; - new_alloc_current = alloc_current; - } + if (initrd_high) + *initrd_start = lmb_alloc_base(lmb, rd_len, 0x1000, initrd_high); + else + *initrd_start = lmb_alloc(lmb, rd_len, 0x1000); + + if (*initrd_start == 0) { + puts("ramdisk - allocation error\n"); + goto error; } - show_boot_progress (12); *initrd_end = *initrd_start + rd_len; @@ -808,56 +778,40 @@ ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, } debug (" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", *initrd_start, *initrd_end); + return 0; - return new_alloc_current; -} - -/** - * get_boot_sp_limit - calculate stack pointer limit - * @sp: current stack pointer - * - * get_boot_sp_limit() takes current stack pointer adrress and calculates - * stack pointer limit, below which kernel boot data (cmdline, board info, - * etc.) will be allocated. - * - * returns: - * stack pointer limit - */ -ulong get_boot_sp_limit(ulong sp) -{ - ulong sp_limit = sp; - - sp_limit -= 2048; /* just to be sure */ - - /* make sure sp_limit is within kernel mapped space */ - if (sp_limit > CFG_BOOTMAPSZ) - sp_limit = CFG_BOOTMAPSZ; - sp_limit &= ~0xF; - - return sp_limit; +error: + return -1; } /** * get_boot_cmdline - allocate and initialize kernel cmdline - * @alloc_current: current boot allocation address (counting down - * from sp_limit) + * @lmb: pointer to lmb handle, will be used for memory mgmt * @cmd_start: pointer to a ulong variable, will hold cmdline start * @cmd_end: pointer to a ulong variable, will hold cmdline end + * @bootmap_base: ulong variable, holds offset in physical memory to + * base of bootmap * * get_boot_cmdline() allocates space for kernel command line below - * provided alloc_current address. If "bootargs" U-boot environemnt + * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt * variable is present its contents is copied to allocated kernel * command line. * * returns: - * alloc_current after cmdline allocation + * 0 - success + * -1 - failure */ -ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end) +int get_boot_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, + ulong bootmap_base) { char *cmdline; char *s; - cmdline = (char *)((alloc_current - CFG_BARGSIZE) & ~0xF); + cmdline = (char *)lmb_alloc_base(lmb, CFG_BARGSIZE, 0xf, + CFG_BOOTMAPSZ + bootmap_base); + + if (cmdline == NULL) + return -1; if ((s = getenv("bootargs")) == NULL) s = ""; @@ -869,25 +823,31 @@ ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end) debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end); - return (ulong)cmdline; + return 0; } /** * get_boot_kbd - allocate and initialize kernel copy of board info - * @alloc_current: current boot allocation address (counting down - * from sp_limit) + * @lmb: pointer to lmb handle, will be used for memory mgmt * @kbd: double pointer to board info data + * @bootmap_base: ulong variable, holds offset in physical memory to + * base of bootmap * - * get_boot_kbd() - allocates space for kernel copy of board info data. - * Space is allocated below provided alloc_current address and kernel - * board info is initialized with the current u-boot board info data. + * get_boot_kbd() allocates space for kernel copy of board info data below + * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with + * the current u-boot board info data. * * returns: - * alloc_current after kbd allocation + * 0 - success + * -1 - failure */ -ulong get_boot_kbd (ulong alloc_current, bd_t **kbd) +int get_boot_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base) { - *kbd = (bd_t *) (((ulong)alloc_current - sizeof(bd_t)) & ~0xF); + *kbd = (bd_t *)lmb_alloc_base(lmb, sizeof(bd_t), 0xf, + CFG_BOOTMAPSZ + bootmap_base); + if (*kbd == NULL) + return -1; + **kbd = *(gd->bd); debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd); @@ -896,7 +856,7 @@ ulong get_boot_kbd (ulong alloc_current, bd_t **kbd) do_bdinfo(NULL, 0, 0, NULL); #endif - return (ulong)*kbd; + return 0; } #endif /* CONFIG_PPC || CONFIG_M68K */ diff --git a/include/image.h b/include/image.h index 5ce2ca4..97eb520 100644 --- a/include/image.h +++ b/include/image.h @@ -391,13 +391,11 @@ int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong *rd_start, ulong *rd_end); #if defined(CONFIG_PPC) || defined(CONFIG_M68K) -ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, - ulong sp_limit, ulong sp, - ulong *initrd_start, ulong *initrd_end); - -ulong get_boot_sp_limit (ulong sp); -ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end); -ulong get_boot_kbd (ulong alloc_current, bd_t **kbd); +int ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, + ulong *initrd_start, ulong *initrd_end); +int get_boot_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, + ulong bootmap_base); +int get_boot_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base); #endif /* CONFIG_PPC || CONFIG_M68K */ /*******************************************************************/ diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index c9d2a27..8429ca0 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -50,16 +50,18 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { - ulong sp, sp_limit, alloc_current; + ulong sp; ulong rd_data_start, rd_data_end, rd_len; ulong initrd_start, initrd_end; int ret; ulong cmd_start, cmd_end; + ulong bootmap_base = 0; bd_t *kbd; ulong ep = 0; void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); + struct lmb *lmb = images->lmb; /* * Booting a (Linux) kernel image @@ -73,14 +75,23 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, sp = get_sp(); debug ("## Current stack ends at 0x%08lx ", sp); - alloc_current = sp_limit = get_boot_sp_limit(sp); - debug ("=> set upper limit to 0x%08lx\n", sp_limit); + /* adjust sp by 1K to be safe */ + sp -= 1024; + lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + gd->ram_size - sp)); /* allocate space and init command line */ - alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end); + ret = get_boot_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); + if (ret) { + puts("ERROR with allocation of cmdline\n"); + goto error; + } /* allocate space for kernel copy of board info */ - alloc_current = get_boot_kbd (alloc_current, &kbd); + ret = get_boot_kbd (lmb, &kbd, bootmap_base); + if (ret) { + puts("ERROR with allocation of kernel bd\n"); + goto error; + } set_clocks_in_mhz(kbd); /* find kernel entry point */ @@ -105,8 +116,9 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, goto error; rd_len = rd_data_end - rd_data_start; - alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, - sp_limit, get_sp (), &initrd_start, &initrd_end); + ret = ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end); + if (ret) + goto error; debug("## Transferring control to Linux (at address %08lx) ...\n", (ulong) kernel); diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 9f48b8d..d74a3f4 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -43,7 +43,7 @@ static void fdt_error (const char *msg); static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size); -static ulong fdt_relocate (ulong alloc_current, +static int fdt_relocate (struct lmb *lmb, ulong bootmap_base, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char **of_flat_tree, ulong *of_size); #endif @@ -55,6 +55,7 @@ static ulong fdt_relocate (ulong alloc_current, DECLARE_GLOBAL_DATA_PTR; extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern ulong get_effective_memsize(void); static ulong get_sp (void); static void set_clocks_in_mhz (bd_t *kbd); @@ -62,22 +63,25 @@ void __attribute__((noinline)) do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { - ulong sp, sp_limit, alloc_current; + ulong sp; ulong initrd_start, initrd_end; ulong rd_data_start, rd_data_end, rd_len; - ulong cmd_start, cmd_end; + ulong cmd_start, cmd_end, bootmap_base; bd_t *kbd; ulong ep = 0; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); int ret; ulong of_size = 0; + struct lmb *lmb = images->lmb; #if defined(CONFIG_OF_LIBFDT) char *of_flat_tree = NULL; #endif + bootmap_base = 0; + /* * Booting a (Linux) kernel image * @@ -90,8 +94,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], sp = get_sp(); debug ("## Current stack ends at 0x%08lx ", sp); - alloc_current = sp_limit = get_boot_sp_limit(sp); - debug ("=> set upper limit to 0x%08lx\n", sp_limit); + /* adjust sp by 1K to be safe */ + sp -= 1024; + lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + get_effective_memsize() - sp)); #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ @@ -103,10 +108,18 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (!of_size) { /* allocate space and init command line */ - alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end); + ret = get_boot_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); + if (ret) { + puts("ERROR with allocation of cmdline\n"); + goto error; + } /* allocate space for kernel copy of board info */ - alloc_current = get_boot_kbd (alloc_current, &kbd); + ret = get_boot_kbd (lmb, &kbd, bootmap_base); + if (ret) { + puts("ERROR with allocation of kernel bd\n"); + goto error; + } set_clocks_in_mhz(kbd); } @@ -134,8 +147,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], rd_len = rd_data_end - rd_data_start; #if defined(CONFIG_OF_LIBFDT) - alloc_current = fdt_relocate (alloc_current, - cmdtp, flag, argc, argv, &of_flat_tree, &of_size); + ret = fdt_relocate (lmb, bootmap_base, + cmdtp, flag, argc, argv, &of_flat_tree, &of_size); /* * Add the chosen node if it doesn't exist, add the env and bd_t @@ -166,8 +179,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } #endif /* CONFIG_OF_LIBFDT */ - alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, - sp_limit, get_sp (), &initrd_start, &initrd_end); + ret = ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end); + if (ret) + goto error; #if defined(CONFIG_OF_LIBFDT) /* fixup the initrd now that we know where it should be */ @@ -488,17 +502,17 @@ error: return 1; } -static ulong fdt_relocate (ulong alloc_current, +static int fdt_relocate (struct lmb *lmb, ulong bootmap_base, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char **of_flat_tree, ulong *of_size) { char *fdt_blob = *of_flat_tree; ulong relocate = 0; - ulong new_alloc_current; + ulong of_len = 0; /* nothing to do */ if (*of_size == 0) - return alloc_current; + return 0; if (fdt_check_header (fdt_blob) != 0) { fdt_error ("image is not a fdt"); @@ -511,25 +525,28 @@ static ulong fdt_relocate (ulong alloc_current, relocate = 1; #endif -#ifdef CFG_BOOTMAPSZ /* * The blob must be within CFG_BOOTMAPSZ, * so we flag it to be copied if it is not. */ if (fdt_blob >= (char *)CFG_BOOTMAPSZ) relocate = 1; -#endif + + of_len = be32_to_cpu (fdt_totalsize (fdt)); /* move flattend device tree if needed */ if (relocate) { int err; - ulong of_start, of_len; - - of_len = *of_size; + ulong of_start; /* position on a 4K boundary before the alloc_current */ - of_start = alloc_current - of_len; - of_start &= ~(4096 - 1); /* align on page */ + of_start = lmb_alloc_base(lmb, of_len, 0x1000, + (CFG_BOOTMAPSZ + bootmap_base)); + + if (of_start == 0) { + puts("device tree - allocation error\n"); + goto error; + } debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", (ulong)fdt_blob, (ulong)fdt_blob + of_len - 1, @@ -546,16 +563,14 @@ static ulong fdt_relocate (ulong alloc_current, puts ("OK\n"); *of_flat_tree = (char *)of_start; - new_alloc_current = of_start; } else { *of_flat_tree = fdt_blob; - new_alloc_current = alloc_current; + lmb_reserve(lmb, (ulong)fdt, of_len); } - return new_alloc_current; + return 0; error: - do_reset (cmdtp, flag, argc, argv); return 1; } #endif -- cgit v0.10.2 From d3f2fa0d278467b2232e4eb2372f905c3febfbeb Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:50 -0600 Subject: [new uImage] Provide ability to restrict region used for boot images Allow the user to set 'bootm_low' and 'bootm_size' env vars as a way to restrict what memory range is used for bootm. Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index a32a5a2..8595ef6 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -124,6 +124,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong os_data, os_len; ulong image_start, image_end; ulong load_start, load_end; + ulong mem_start, mem_size; struct lmb lmb; @@ -134,11 +135,10 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) lmb_init(&lmb); -#ifdef CFG_SDRAM_BASE - lmb_add(&lmb, CFG_SDRAM_BASE, gd->bd->bi_memsize); -#else - lmb_add(&lmb, 0, gd->bd->bi_memsize); -#endif + mem_start = getenv_bootm_low(); + mem_size = getenv_bootm_size(); + + lmb_add(&lmb, mem_start, mem_size); board_lmb_reserve(&lmb); diff --git a/common/image.c b/common/image.c index 0b71811..9e446fa 100644 --- a/common/image.c +++ b/common/image.c @@ -132,6 +132,32 @@ int getenv_autostart (void) return (s && (*s == 'n')) ? 0 : 1; } +ulong getenv_bootm_low(void) +{ + char *s = getenv ("bootm_low"); + if (s) { + ulong tmp = simple_strtoul (s, NULL, 16); + return tmp; + } + +#ifdef CFG_SDRAM_BASE + return CFG_SDRAM_BASE; +#else + return 0; +#endif +} + +ulong getenv_bootm_size(void) +{ + char *s = getenv ("bootm_size"); + if (s) { + ulong tmp = simple_strtoul (s, NULL, 16); + return tmp; + } + + return gd->bd->bi_memsize; +} + void memmove_wd (void *to, void *from, size_t len, ulong chunksz) { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) diff --git a/include/image.h b/include/image.h index 97eb520..ee692ac 100644 --- a/include/image.h +++ b/include/image.h @@ -316,6 +316,8 @@ int image_check_dcrc (image_header_t *hdr); int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize); int getenv_verify (void); int getenv_autostart (void); +ulong getenv_bootm_low(void); +ulong getenv_bootm_size(void); void memmove_wd (void *to, void *from, size_t len, ulong chunksz); #endif diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index 8429ca0..eca044e 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -57,12 +57,14 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int ret; ulong cmd_start, cmd_end; - ulong bootmap_base = 0; + ulong bootmap_base; bd_t *kbd; ulong ep = 0; void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); struct lmb *lmb = images->lmb; + bootmap_base = getenv_bootm_low(); + /* * Booting a (Linux) kernel image * diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index d74a3f4..59cc2a4 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -59,6 +59,10 @@ extern ulong get_effective_memsize(void); static ulong get_sp (void); static void set_clocks_in_mhz (bd_t *kbd); +#ifndef CFG_LINUX_LOWMEM_MAX_SIZE +#define CFG_LINUX_LOWMEM_MAX_SIZE (768*1024*1024) +#endif + void __attribute__((noinline)) do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) @@ -67,6 +71,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong initrd_start, initrd_end; ulong rd_data_start, rd_data_end, rd_len; + ulong size; ulong cmd_start, cmd_end, bootmap_base; bd_t *kbd; @@ -80,7 +85,24 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char *of_flat_tree = NULL; #endif - bootmap_base = 0; + bootmap_base = getenv_bootm_low(); + size = getenv_bootm_size(); + +#ifdef DEBUG + if (((u64)bootmap_base + size) > (CFG_SDRAM_BASE + (u64)gd->ram_size)) + puts("WARNING: bootm_low + bootm_size exceed total memory\n"); + if ((bootmap_base + size) > get_effective_memsize()) + puts("WARNING: bootm_low + bootm_size exceed eff. memory\n"); +#endif + + size = min(size, get_effective_memsize()); + size = min(size, CFG_LINUX_LOWMEM_MAX_SIZE); + + if (size < getenv_bootm_size()) { + ulong base = bootmap_base + size; + printf("WARNING: adjusting available memory to %x\n", size); + lmb_reserve(lmb, base, getenv_bootm_size() - size); + } /* * Booting a (Linux) kernel image @@ -92,7 +114,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * pointer. */ sp = get_sp(); - debug ("## Current stack ends at 0x%08lx ", sp); + debug ("## Current stack ends at 0x%08lx\n", sp); /* adjust sp by 1K to be safe */ sp -= 1024; -- cgit v0.10.2 From 75fa002c47171b73fb4c1f2c2fe4d6391c136276 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 27 Feb 2008 21:51:51 -0600 Subject: [new uImage] Respect autostart setting in linux bootm Signed-off-by: Kumar Gala Acked-by: Marian Balakowicz diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index e1a9ee2..77d35fc 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -133,6 +133,9 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], setup_end_tag (bd); #endif + if (!images->autostart) + return ; + /* we assume that the kernel is in place */ printf ("\nStarting kernel ...\n\n"); diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index 69a69df..918e4cf 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -214,6 +214,9 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], params = setup_ethernet_tags(params); setup_end_tag(params); + if (!images->autostart) + return ; + printf("\nStarting kernel at %p (params at %p)...\n\n", theKernel, params_start); diff --git a/lib_blackfin/bootm.c b/lib_blackfin/bootm.c index 26ac88b..33979a9 100644 --- a/lib_blackfin/bootm.c +++ b/lib_blackfin/bootm.c @@ -53,6 +53,9 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], char *cmdline; ulong ep = 0; + if (!images->autostart) + return ; + #ifdef SHARED_RESOURCES swap_to(FLASH); #endif diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c index aea58d1..89a423c 100644 --- a/lib_i386/bootm.c +++ b/lib_i386/bootm.c @@ -72,6 +72,9 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } + if (!images->autostart) + return ; + #ifdef DEBUG printf ("## Transferring control to Linux (at address %08x) ...\n", (u32)base_ptr); diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index eca044e..e12d1d4 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -127,6 +127,8 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, show_boot_progress (15); + if (!images->autostart) + return; /* * Linux Kernel Parameters (passing board info data): * r3: ptr to board info data @@ -140,7 +142,8 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, return ; error: - do_reset (cmdtp, flag, argc, argv); + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); return ; } diff --git a/lib_microblaze/bootm.c b/lib_microblaze/bootm.c index 5881df6..99c4533 100644 --- a/lib_microblaze/bootm.c +++ b/lib_microblaze/bootm.c @@ -63,5 +63,8 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], (ulong) theKernel); #endif + if (!images->autostart) + return ; + theKernel (commandline); } diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c index 998aa22..39869c1 100644 --- a/lib_mips/bootm.c +++ b/lib_mips/bootm.c @@ -106,6 +106,9 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], sprintf (env_buf, "0x%X", (uint) (gd->bd->bi_flashsize)); linux_env_set ("flash_size", env_buf); + if (!images->autostart) + return ; + /* we assume that the kernel is in place */ printf ("\nStarting kernel ...\n\n"); diff --git a/lib_nios2/bootm.c b/lib_nios2/bootm.c index 70d2bb0..4b940cb 100644 --- a/lib_nios2/bootm.c +++ b/lib_nios2/bootm.c @@ -46,6 +46,9 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } void (*kernel)(void) = (void (*)(void))ep; + if (!images->autostart) + return ; + /* For now we assume the Microtronix linux ... which only * needs to be called ;-) */ diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 59cc2a4..1afef46 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -242,6 +242,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) unlock_ram_in_cache(); #endif + if (!images->autostart) + return ; #if defined(CONFIG_OF_LIBFDT) if (of_flat_tree) { /* device tree; boot new style */ @@ -270,7 +272,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], return ; error: - do_reset (cmdtp, flag, argc, argv); + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); return ; } diff --git a/lib_sh/bootm.c b/lib_sh/bootm.c index de5c9ea..8055841 100644 --- a/lib_sh/bootm.c +++ b/lib_sh/bootm.c @@ -79,6 +79,9 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } void (*kernel) (void) = (void (*)(void))ep; + if (!images->autostart) + return ; + /* Setup parameters */ memset(PARAM, 0, 0x1000); /* Clear zero page */ strcpy(COMMAND_LINE, bootargs); -- cgit v0.10.2 From 9a4daad0a35eb5143037eea9f786a3e9d672bdd6 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Fri, 29 Feb 2008 14:58:34 +0100 Subject: [new uImage] Update naming convention for bootm/uImage related code This patch introduces the following prefix convention for the image format handling and bootm related code: genimg_ - dual format shared code image_ - legacy uImage format specific code fit_ - new uImage format specific code boot_ - booting process related code Related routines are renamed and a few pieces of code are moved around and re-grouped. Signed-off-by: Marian Balakowicz diff --git a/board/cray/L1/L1.c b/board/cray/L1/L1.c index c00acc8..77f7f48 100644 --- a/board/cray/L1/L1.c +++ b/board/cray/L1/L1.c @@ -141,7 +141,7 @@ int misc_init_r (void) hdr = (image_header_t *) (CFG_MONITOR_BASE - image_get_header_size ()); #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c index 976707d..1bf81c6 100644 --- a/board/esd/common/auto_update.c +++ b/board/esd/common/auto_update.c @@ -92,7 +92,7 @@ int au_check_cksum_valid(int i, long nbytes) hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } @@ -125,7 +125,7 @@ int au_check_header_valid(int i, long nbytes) hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } @@ -197,7 +197,7 @@ int au_do_update(int i, long sz) hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } diff --git a/board/mcc200/auto_update.c b/board/mcc200/auto_update.c index fcae35a..5580c11 100644 --- a/board/mcc200/auto_update.c +++ b/board/mcc200/auto_update.c @@ -144,7 +144,7 @@ int au_check_cksum_valid(int idx, long nbytes) hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } @@ -169,7 +169,7 @@ int au_check_header_valid(int idx, long nbytes) hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } @@ -247,7 +247,7 @@ int au_do_update(int idx, long sz) hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c index fffd25c..785d204 100644 --- a/board/mpl/common/common_util.c +++ b/board/mpl/common/common_util.c @@ -74,7 +74,7 @@ mpl_prg(uchar *src, ulong size) info = &flash_info[0]; #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI) - if (image_to_cpu (magic[0]) != IH_MAGIC) { + if (uimage_to_cpu (magic[0]) != IH_MAGIC) { puts("Bad Magic number\n"); return -1; } @@ -182,7 +182,7 @@ mpl_prg_image(uchar *ld_addr) int rc; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } diff --git a/board/siemens/common/fpga.c b/board/siemens/common/fpga.c index a9a6dfe..48c1850 100644 --- a/board/siemens/common/fpga.c +++ b/board/siemens/common/fpga.c @@ -138,7 +138,7 @@ static int fpga_load (fpga_t* fpga, ulong addr, int checkall) int verify, i; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } @@ -341,7 +341,7 @@ int fpga_init (void) hdr = (image_header_t *)addr; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c index 8f67535..fa08bff 100644 --- a/board/trab/auto_update.c +++ b/board/trab/auto_update.c @@ -212,7 +212,7 @@ au_check_cksum_valid(int idx, long nbytes) hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } @@ -241,7 +241,7 @@ au_check_header_valid(int idx, long nbytes) hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } @@ -341,7 +341,7 @@ au_do_update(int idx, long sz) hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } @@ -437,7 +437,7 @@ au_update_eeprom(int idx) hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) - if (gen_image_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c index f9ab1d9..60ffc7d 100644 --- a/common/cmd_autoscript.c +++ b/common/cmd_autoscript.c @@ -61,7 +61,7 @@ autoscript (ulong addr) verify = getenv_verify (); - switch (gen_image_get_format ((void *)addr)) { + switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; @@ -90,7 +90,7 @@ autoscript (ulong addr) /* get length of script */ data = (ulong *)image_get_data (hdr); - if ((len = image_to_cpu (*data)) == 0) { + if ((len = uimage_to_cpu (*data)) == 0) { puts ("Empty Script\n"); return 1; } diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 8595ef6..10403aa 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -66,7 +66,7 @@ static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); static void fixup_silent_linux (void); #endif -static void *get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char *argv[], +static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char *argv[], bootm_headers_t *images, ulong *os_data, ulong *os_len); extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); @@ -143,7 +143,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) board_lmb_reserve(&lmb); /* get kernel image header, start address and length */ - os_hdr = get_kernel (cmdtp, flag, argc, argv, + os_hdr = boot_get_kernel (cmdtp, flag, argc, argv, &images, &os_data, &os_len); if (os_len == 0) return 1; @@ -151,7 +151,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress (6); /* get image parameters */ - switch (gen_image_get_format (os_hdr)) { + switch (genimg_get_format (os_hdr)) { case IMAGE_FORMAT_LEGACY: type = image_get_type (os_hdr); comp = image_get_comp (os_hdr); @@ -172,7 +172,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) image_start = (ulong)os_hdr; load_end = 0; - type_name = image_get_type_name (type); + type_name = genimg_get_type_name (type); /* * We have reached the point of no return: we are going to @@ -309,16 +309,16 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } /** - * get_kernel - find kernel image - * @os_data: pointer to a ulong variable, will hold os data start address - * @os_len: pointer to a ulong variable, will hold os data length + * image_get_kernel - verify legacy format kernel image + * @img_addr: in RAM address of the legacy format image to be verified + * @verify: data CRC verification flag * - * get_kernel() tries to find a kernel image, verifies its integrity - * and locates kernel data. + * image_get_kernel() verifies legacy image integrity and returns pointer to + * legacy image header if image verification was completed successfully. * * returns: - * pointer to image header if valid image was found, plus kernel start - * address and length, otherwise NULL + * pointer to a legacy image header if valid image was found + * otherwise return NULL */ static image_header_t *image_get_kernel (ulong img_addr, int verify) { @@ -360,18 +360,18 @@ static image_header_t *image_get_kernel (ulong img_addr, int verify) } /** - * get_kernel - find kernel image + * boot_get_kernel - find kernel image * @os_data: pointer to a ulong variable, will hold os data start address * @os_len: pointer to a ulong variable, will hold os data length * - * get_kernel() tries to find a kernel image, verifies its integrity + * boot_get_kernel() tries to find a kernel image, verifies its integrity * and locates kernel data. * * returns: * pointer to image header if valid image was found, plus kernel start * address and length, otherwise NULL */ -static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, ulong *os_data, ulong *os_len) { image_header_t *hdr; @@ -406,10 +406,10 @@ static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], printf ("## Booting kernel image at %08lx ...\n", img_addr); /* copy from dataflash if needed */ - img_addr = gen_get_image (img_addr); + img_addr = genimg_get_image (img_addr); /* check image type, for FIT images get FIT kernel node */ - switch (gen_image_get_format ((void *)img_addr)) { + switch (genimg_get_format ((void *)img_addr)) { case IMAGE_FORMAT_LEGACY: debug ("* kernel: legacy format image\n"); @@ -531,7 +531,7 @@ static int image_info (ulong addr) printf ("\n## Checking Image at %08lx ...\n", addr); - switch (gen_image_get_format (hdr)) { + switch (genimg_get_format (hdr)) { case IMAGE_FORMAT_LEGACY: puts (" Legacy image found\n"); if (!image_check_magic (hdr)) { @@ -599,7 +599,7 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (!hdr) goto next_sector; - switch (gen_image_get_format (hdr)) { + switch (genimg_get_format (hdr)) { case IMAGE_FORMAT_LEGACY: if (!image_check_magic (hdr)) goto next_sector; diff --git a/common/cmd_doc.c b/common/cmd_doc.c index 3358b04..293b1aa 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -261,7 +261,7 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (38); - switch (gen_image_get_format ((void *)addr)) { + switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index b6e023a..80301b9 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -836,7 +836,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - switch (gen_image_get_format ((void *)addr)) { + switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; if (!image_check_magic (hdr)) { diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index 10199f5..0bb82f6 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -216,7 +216,7 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) break; case FPGA_LOADMK: - switch (gen_image_get_format (fpga_data)) { + switch (genimg_get_format (fpga_data)) { case IMAGE_FORMAT_LEGACY: { image_header_t *hdr = (image_header_t *)fpga_data; diff --git a/common/cmd_ide.c b/common/cmd_ide.c index bef04db..79b7dfb 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -446,7 +446,7 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (48); - switch (gen_image_get_format ((void *)addr)) { + switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; diff --git a/common/cmd_nand.c b/common/cmd_nand.c index b099afe..86959dc 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -512,7 +512,7 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, } show_boot_progress (56); - switch (gen_image_get_format ((void *)addr)) { + switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; @@ -994,7 +994,7 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (56); - switch (gen_image_get_format ((void *)addr)) { + switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 42b3072..7868805 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -273,7 +273,7 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - switch (gen_image_get_format ((void *)addr)) { + switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; diff --git a/common/cmd_usb.c b/common/cmd_usb.c index ad3873c..8ee7d27 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -386,7 +386,7 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - switch (gen_image_get_format ((void *)addr)) { + switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index 4dadc37..360b05e 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -57,7 +57,7 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } - switch (gen_image_get_format ((void *)addr)) { + switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: printf("## Copying from legacy image at %08lx ...\n", addr); @@ -104,7 +104,7 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) data += 4; if (argc > 2 && part > i) { u_long tail; - len = image_to_cpu (len_ptr[i]); + len = uimage_to_cpu (len_ptr[i]); tail = len % 4; data += len; if (tail) { @@ -116,7 +116,7 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) printf("Bad Image Part\n"); return 1; } - len = image_to_cpu (len_ptr[part]); + len = uimage_to_cpu (len_ptr[part]); #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: fit_unsupported ("imxtract"); diff --git a/common/image.c b/common/image.c index 9e446fa..99ed3b8 100644 --- a/common/image.c +++ b/common/image.c @@ -68,6 +68,9 @@ static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, unsigned long crc32 (unsigned long, const unsigned char *, unsigned int); +/*****************************************************************************/ +/* Legacy format routines */ +/*****************************************************************************/ int image_check_hcrc (image_header_t *hdr) { ulong hcrc; @@ -120,61 +123,6 @@ int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz) return (dcrc == image_get_dcrc (hdr)); } -int getenv_verify (void) -{ - char *s = getenv ("verify"); - return (s && (*s == 'n')) ? 0 : 1; -} - -int getenv_autostart (void) -{ - char *s = getenv ("autostart"); - return (s && (*s == 'n')) ? 0 : 1; -} - -ulong getenv_bootm_low(void) -{ - char *s = getenv ("bootm_low"); - if (s) { - ulong tmp = simple_strtoul (s, NULL, 16); - return tmp; - } - -#ifdef CFG_SDRAM_BASE - return CFG_SDRAM_BASE; -#else - return 0; -#endif -} - -ulong getenv_bootm_size(void) -{ - char *s = getenv ("bootm_size"); - if (s) { - ulong tmp = simple_strtoul (s, NULL, 16); - return tmp; - } - - return gd->bd->bi_memsize; -} - -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 */ - /** * image_multi_count - get component (sub-image) count * @hdr: pointer to the header of the multi component image @@ -262,7 +210,185 @@ void image_multi_getimg (image_header_t *hdr, ulong idx, } #ifndef USE_HOSTCC -const char* image_get_os_name (uint8_t os) +static void image_print_type (image_header_t *hdr) +{ + const char *os, *arch, *type, *comp; + + os = genimg_get_os_name (image_get_os (hdr)); + arch = genimg_get_arch_name (image_get_arch (hdr)); + type = genimg_get_type_name (image_get_type (hdr)); + comp = genimg_get_comp_name (image_get_comp (hdr)); + + printf ("%s %s %s (%s)", arch, os, type, comp); +} + +void image_print_contents (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)); + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) + to_tm (timestamp, &tm); + 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: "); + image_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", + image_get_load (hdr), image_get_ep (hdr)); + + if (image_check_type (hdr, IH_TYPE_MULTI)) { + int i; + ulong data, len; + ulong count = image_multi_count (hdr); + + puts (" Contents:\n"); + for (i = 0; i < count; i++) { + image_multi_getimg (hdr, i, &data, &len); + printf (" Image %d: %8ld Bytes = ", i, len); + print_size (len, "\n"); + } + } +} + +/** + * image_get_ramdisk - get and verify ramdisk image + * @cmdtp: command table pointer + * @flag: command flag + * @argc: command argument count + * @argv: command argument list + * @rd_addr: ramdisk image start address + * @arch: expected ramdisk architecture + * @verify: checksum verification flag + * + * image_get_ramdisk() returns a pointer to the verified ramdisk image + * header. Routine receives image start address and expected architecture + * flag. Verification done covers data and header integrity and os/type/arch + * fields checking. + * + * If dataflash support is enabled routine checks for dataflash addresses + * and handles required dataflash reads. + * + * returns: + * pointer to a ramdisk image header, if image was found and valid + * otherwise, return NULL + */ +static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + ulong rd_addr, uint8_t arch, int verify) +{ + image_header_t *rd_hdr; + + show_boot_progress (9); + rd_hdr = (image_header_t *)rd_addr; + + if (!image_check_magic (rd_hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-10); + return NULL; + } + + if (!image_check_hcrc (rd_hdr)) { + puts ("Bad Header Checksum\n"); + show_boot_progress (-11); + return NULL; + } + + show_boot_progress (10); + image_print_contents (rd_hdr); + + if (verify) { + puts(" Verifying Checksum ... "); + if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) { + puts ("Bad Data CRC\n"); + show_boot_progress (-12); + return NULL; + } + puts("OK\n"); + } + + show_boot_progress (11); + + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, arch) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { + printf ("No Linux %s Ramdisk Image\n", + genimg_get_arch_name(arch)); + show_boot_progress (-13); + return NULL; + } + + return rd_hdr; +} + +/*****************************************************************************/ +/* Shared dual-format routines */ +/*****************************************************************************/ +int getenv_verify (void) +{ + char *s = getenv ("verify"); + return (s && (*s == 'n')) ? 0 : 1; +} + +int getenv_autostart (void) +{ + char *s = getenv ("autostart"); + return (s && (*s == 'n')) ? 0 : 1; +} + +ulong getenv_bootm_low(void) +{ + char *s = getenv ("bootm_low"); + if (s) { + ulong tmp = simple_strtoul (s, NULL, 16); + return tmp; + } + +#ifdef CFG_SDRAM_BASE + return CFG_SDRAM_BASE; +#else + return 0; +#endif +} + +ulong getenv_bootm_size(void) +{ + char *s = getenv ("bootm_size"); + if (s) { + ulong tmp = simple_strtoul (s, NULL, 16); + return tmp; + } + + return gd->bd->bi_memsize; +} + +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 */ + +const char* genimg_get_os_name (uint8_t os) { const char *name; @@ -286,7 +412,7 @@ const char* image_get_os_name (uint8_t os) return name; } -const char* image_get_arch_name (uint8_t arch) +const char* genimg_get_arch_name (uint8_t arch) { const char *name; @@ -315,7 +441,7 @@ const char* image_get_arch_name (uint8_t arch) return name; } -const char* image_get_type_name (uint8_t type) +const char* genimg_get_type_name (uint8_t type) { const char *name; @@ -334,7 +460,7 @@ const char* image_get_type_name (uint8_t type) return name; } -const char* image_get_comp_name (uint8_t comp) +const char* genimg_get_comp_name (uint8_t comp) { const char *name; @@ -348,71 +474,21 @@ const char* image_get_comp_name (uint8_t comp) return name; } -static void image_print_type (image_header_t *hdr) -{ - const char *os, *arch, *type, *comp; - - os = image_get_os_name (image_get_os (hdr)); - arch = image_get_arch_name (image_get_arch (hdr)); - type = image_get_type_name (image_get_type (hdr)); - comp = image_get_comp_name (image_get_comp (hdr)); - - printf ("%s %s %s (%s)", arch, os, type, comp); -} - -void image_print_contents (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)); - -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) - to_tm (timestamp, &tm); - 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: "); - image_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", - image_get_load (hdr), image_get_ep (hdr)); - - if (image_check_type (hdr, IH_TYPE_MULTI)) { - int i; - ulong data, len; - ulong count = image_multi_count (hdr); - - puts (" Contents:\n"); - for (i = 0; i < count; i++) { - image_multi_getimg (hdr, i, &data, &len); - printf (" Image %d: %8ld Bytes = ", i, len); - print_size (len, "\n"); - } - } -} - /** - * gen_image_get_format - get image format type + * genimg_get_format - get image format type * @img_addr: image start address * - * gen_image_get_format() checks whether provided address points to a valid + * genimg_get_format() checks whether provided address points to a valid * legacy or FIT image. * * New uImage format and FDT blob are based on a libfdt. FDT blob * may be passed directly or embedded in a FIT image. In both situations - * gen_image_get_format() must be able to dectect libfdt header. + * genimg_get_format() must be able to dectect libfdt header. * * returns: * image format type or IMAGE_FORMAT_INVALID if no image is present */ -int gen_image_get_format (void *img_addr) +int genimg_get_format (void *img_addr) { ulong format = IMAGE_FORMAT_INVALID; image_header_t *hdr; @@ -435,16 +511,16 @@ int gen_image_get_format (void *img_addr) } /** - * gen_get_image - get image from special storage (if necessary) + * genimg_get_image - get image from special storage (if necessary) * @img_addr: image start address * - * gen_get_image() checks if provided image start adddress is located + * genimg_get_image() checks if provided image start adddress is located * in a dataflash storage. If so, image is moved to a system RAM memory. * * returns: * image start address after possible relocation from special storage */ -ulong gen_get_image (ulong img_addr) +ulong genimg_get_image (ulong img_addr) { ulong ram_addr = img_addr; @@ -469,7 +545,7 @@ ulong gen_get_image (ulong img_addr) read_dataflash (img_addr, h_size, (char *)ram_addr); /* get data size */ - switch (gen_image_get_format ((void *)ram_addr)) { + switch (genimg_get_format ((void *)ram_addr)) { case IMAGE_FORMAT_LEGACY: d_size = image_get_data_size ((image_header_t *)ram_addr); debug (" Legacy format image found at 0x%08lx, size 0x%08lx\n", @@ -502,77 +578,7 @@ ulong gen_get_image (ulong img_addr) } /** - * image_get_ramdisk - get and verify ramdisk image - * @cmdtp: command table pointer - * @flag: command flag - * @argc: command argument count - * @argv: command argument list - * @rd_addr: ramdisk image start address - * @arch: expected ramdisk architecture - * @verify: checksum verification flag - * - * image_get_ramdisk() returns a pointer to the verified ramdisk image - * header. Routine receives image start address and expected architecture - * flag. Verification done covers data and header integrity and os/type/arch - * fields checking. - * - * If dataflash support is enabled routine checks for dataflash addresses - * and handles required dataflash reads. - * - * returns: - * pointer to a ramdisk image header, if image was found and valid - * otherwise, return NULL - */ -static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong rd_addr, uint8_t arch, int verify) -{ - image_header_t *rd_hdr; - - show_boot_progress (9); - rd_hdr = (image_header_t *)rd_addr; - - if (!image_check_magic (rd_hdr)) { - puts ("Bad Magic Number\n"); - show_boot_progress (-10); - return NULL; - } - - if (!image_check_hcrc (rd_hdr)) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-11); - return NULL; - } - - show_boot_progress (10); - image_print_contents (rd_hdr); - - if (verify) { - puts(" Verifying Checksum ... "); - if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) { - puts ("Bad Data CRC\n"); - show_boot_progress (-12); - return NULL; - } - puts("OK\n"); - } - - show_boot_progress (11); - - if (!image_check_os (rd_hdr, IH_OS_LINUX) || - !image_check_arch (rd_hdr, arch) || - !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { - printf ("No Linux %s Ramdisk Image\n", - image_get_arch_name(arch)); - show_boot_progress (-13); - return NULL; - } - - return rd_hdr; -} - -/** - * get_ramdisk - main ramdisk handling routine + * boot_get_ramdisk - main ramdisk handling routine * @cmdtp: command table pointer * @flag: command flag * @argc: command argument count @@ -582,7 +588,7 @@ static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, * @rd_start: pointer to a ulong variable, will hold ramdisk start address * @rd_end: pointer to a ulong variable, will hold ramdisk end * - * get_ramdisk() is responsible for finding a valid ramdisk image. + * boot_get_ramdisk() is responsible for finding a valid ramdisk image. * Curently supported are the following ramdisk sources: * - multicomponent kernel/ramdisk image, * - commandline provided address of decicated ramdisk image. @@ -593,7 +599,7 @@ static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, * rd_start and rd_end are set to 0 if no ramdisk exists * return 1 if ramdisk image is found but corrupted */ -int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end) { @@ -645,14 +651,14 @@ int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], /* copy from dataflash if needed */ printf ("## Loading init Ramdisk Image at %08lx ...\n", rd_addr); - rd_addr = gen_get_image (rd_addr); + rd_addr = genimg_get_image (rd_addr); /* * Check if there is an initrd image at the * address provided in the second bootm argument * check image type, for FIT images get FIT node. */ - switch (gen_image_get_format ((void *)rd_addr)) { + switch (genimg_get_format ((void *)rd_addr)) { case IMAGE_FORMAT_LEGACY: debug ("* ramdisk: legacy format image\n"); @@ -729,7 +735,7 @@ int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CONFIG_PPC) || defined(CONFIG_M68K) /** - * ramdisk_high - relocate init ramdisk + * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt * @rd_data: ramdisk data start address * @rd_len: ramdisk data length @@ -738,18 +744,18 @@ int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * @initrd_end: pointer to a ulong variable, will hold final init ramdisk * end address (after possible relocation) * - * ramdisk_high() takes a relocation hint from "initrd_high" environement + * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement * variable and if requested ramdisk data is moved to a specified location. * + * Initrd_start and initrd_end are set to final (after relocation) ramdisk + * start/end addresses if ramdisk image start and len were provided, + * otherwise set initrd_start and initrd_end set to zeros. + * * returns: - * - initrd_start and initrd_end are set to final (after relocation) ramdisk - * start/end addresses if ramdisk image start and len were provided - * otherwise set initrd_start and initrd_end set to zeros - * - returns: - * 0 - success - * -1 - failure + * 0 - success + * -1 - failure */ -int ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, +int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, ulong *initrd_start, ulong *initrd_end) { char *s; @@ -779,12 +785,12 @@ int ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, lmb_reserve(lmb, rd_data, rd_len); } else { if (initrd_high) - *initrd_start = lmb_alloc_base(lmb, rd_len, 0x1000, initrd_high); + *initrd_start = lmb_alloc_base (lmb, rd_len, 0x1000, initrd_high); else - *initrd_start = lmb_alloc(lmb, rd_len, 0x1000); + *initrd_start = lmb_alloc (lmb, rd_len, 0x1000); if (*initrd_start == 0) { - puts("ramdisk - allocation error\n"); + puts ("ramdisk - allocation error\n"); goto error; } show_boot_progress (12); @@ -793,7 +799,7 @@ int ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, printf (" Loading Ramdisk to %08lx, end %08lx ... ", *initrd_start, *initrd_end); - memmove_wd((void *)*initrd_start, + memmove_wd ((void *)*initrd_start, (void *)rd_data, rd_len, CHUNKSZ); puts ("OK\n"); @@ -804,6 +810,7 @@ int ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, } debug (" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", *initrd_start, *initrd_end); + return 0; error: @@ -811,14 +818,14 @@ error: } /** - * get_boot_cmdline - allocate and initialize kernel cmdline + * boot_get_cmdline - allocate and initialize kernel cmdline * @lmb: pointer to lmb handle, will be used for memory mgmt * @cmd_start: pointer to a ulong variable, will hold cmdline start * @cmd_end: pointer to a ulong variable, will hold cmdline end * @bootmap_base: ulong variable, holds offset in physical memory to * base of bootmap * - * get_boot_cmdline() allocates space for kernel command line below + * boot_get_cmdline() allocates space for kernel command line below * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt * variable is present its contents is copied to allocated kernel * command line. @@ -827,7 +834,7 @@ error: * 0 - success * -1 - failure */ -int get_boot_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, +int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, ulong bootmap_base) { char *cmdline; @@ -853,13 +860,13 @@ int get_boot_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, } /** - * get_boot_kbd - allocate and initialize kernel copy of board info + * boot_get_kbd - allocate and initialize kernel copy of board info * @lmb: pointer to lmb handle, will be used for memory mgmt * @kbd: double pointer to board info data * @bootmap_base: ulong variable, holds offset in physical memory to * base of bootmap * - * get_boot_kbd() allocates space for kernel copy of board info data below + * boot_get_kbd() allocates space for kernel copy of board info data below * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with * the current u-boot board info data. * @@ -867,7 +874,7 @@ int get_boot_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, * 0 - success * -1 - failure */ -int get_boot_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base) +int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base) { *kbd = (bd_t *)lmb_alloc_base(lmb, sizeof(bd_t), 0xf, CFG_BOOTMAPSZ + bootmap_base); diff --git a/include/image.h b/include/image.h index ee692ac..b520691 100644 --- a/include/image.h +++ b/include/image.h @@ -161,9 +161,9 @@ #define IH_NMLEN 32 /* Image Name Length */ /* - * all data in network byte order (aka natural aka bigendian) + * Legacy format image header, + * all data in network byte order (aka natural aka bigendian). */ - typedef struct image_header { uint32_t ih_magic; /* Image Header Magic Number */ uint32_t ih_hcrc; /* Image Header CRC Checksum */ @@ -186,7 +186,7 @@ typedef struct image_header { typedef struct bootm_headers { /* * Legacy os image header, if it is a multi component image - * then get_ramdisk() and get_fdt() will attempt to get + * then boot_get_ramdisk() and get_fdt() will attempt to get * data from second and third component accordingly. */ image_header_t *legacy_hdr_os; @@ -216,9 +216,40 @@ typedef struct bootm_headers { */ #define CHUNKSZ (64 * 1024) -#define image_to_cpu(x) ntohl(x) -#define cpu_to_image(x) htonl(x) +#define uimage_to_cpu(x) ntohl(x) +#define cpu_to_uimage(x) htonl(x) + +#ifndef USE_HOSTCC +/* Image format types, returned by _get_format() routine */ +#define IMAGE_FORMAT_INVALID 0x00 +#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */ +#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */ + +int genimg_get_format (void *img_addr); +ulong genimg_get_image (ulong img_addr); + +const char* genimg_get_os_name (uint8_t os); +const char* genimg_get_arch_name (uint8_t arch); +const char* genimg_get_type_name (uint8_t type); +const char* genimg_get_comp_name (uint8_t comp); + +int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images, uint8_t arch, + ulong *rd_start, ulong *rd_end); + +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, + ulong *initrd_start, ulong *initrd_end); + +int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, + ulong bootmap_base); +int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base); +#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* USE_HOSTCC */ +/*******************************************************************/ +/* Legacy format specific code (prefixed with image_) */ +/*******************************************************************/ static inline uint32_t image_get_header_size (void) { return (sizeof (image_header_t)); @@ -227,7 +258,7 @@ static inline uint32_t image_get_header_size (void) #define image_get_hdr_l(f) \ static inline uint32_t image_get_##f(image_header_t *hdr) \ { \ - return image_to_cpu (hdr->ih_##f); \ + return uimage_to_cpu (hdr->ih_##f); \ } image_get_hdr_l (magic); image_get_hdr_l (hcrc); @@ -285,7 +316,7 @@ static inline ulong image_get_image_end (image_header_t *hdr) #define image_set_hdr_l(f) \ static inline void image_set_##f(image_header_t *hdr, uint32_t val) \ { \ - hdr->ih_##f = cpu_to_image (val); \ + hdr->ih_##f = cpu_to_uimage (val); \ } image_set_hdr_l (magic); image_set_hdr_l (hcrc); @@ -375,33 +406,10 @@ static inline int image_check_target_arch (image_header_t *hdr) return 1; } -const char* image_get_os_name (uint8_t os); -const char* image_get_arch_name (uint8_t arch); -const char* image_get_type_name (uint8_t type); -const char* image_get_comp_name (uint8_t comp); void image_print_contents (image_header_t *hdr); -#define IMAGE_FORMAT_INVALID 0x00 -#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */ -#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */ - -int gen_image_get_format (void *img_addr); -ulong gen_get_image (ulong img_addr); - -int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, uint8_t arch, - ulong *rd_start, ulong *rd_end); - -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) -int ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, - ulong *initrd_start, ulong *initrd_end); -int get_boot_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, - ulong bootmap_base); -int get_boot_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base); -#endif /* CONFIG_PPC || CONFIG_M68K */ - /*******************************************************************/ -/* New uImage format */ +/* New uImage format specific code (prefixed with fit_) */ /*******************************************************************/ #if defined(CONFIG_FIT) inline int fit_parse_conf (const char *spec, ulong addr_curr, @@ -422,9 +430,7 @@ inline int fit_parse_subimage (const char *spec, ulong addr_curr, #define fit_unsupported(msg) #define fit_unsupported_reset(msg) #endif /* CONFIG_FIT_VERBOSE */ - #endif /* CONFIG_FIT */ - #endif /* USE_HOSTCC */ #endif /* __IMAGE_H__ */ diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index 77d35fc..865e711 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -95,7 +95,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], printf ("Using machid 0x%x from environment\n", machid); } - get_ramdisk (cmdtp, flag, argc, argv, images, + boot_get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_ARM, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index 918e4cf..e8e537a 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -196,7 +196,7 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } theKernel = (void *)ep; - get_ramdisk (cmdtp, flag, argc, argv, images, + boot_get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_AVR32, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c index 89a423c..76bcf6c 100644 --- a/lib_i386/bootm.c +++ b/lib_i386/bootm.c @@ -40,7 +40,7 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong ep; image_header_t *hdr; - get_ramdisk (cmdtp, flag, argc, argv, images, + boot_get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_I386, &initrd_start, &initrd_end); if (images->legacy_hdr_valid) { diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index e12d1d4..fba7499 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -82,14 +82,14 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + gd->ram_size - sp)); /* allocate space and init command line */ - ret = get_boot_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); + ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); if (ret) { puts("ERROR with allocation of cmdline\n"); goto error; } /* allocate space for kernel copy of board info */ - ret = get_boot_kbd (lmb, &kbd, bootmap_base); + ret = boot_get_kbd (lmb, &kbd, bootmap_base); if (ret) { puts("ERROR with allocation of kernel bd\n"); goto error; @@ -111,14 +111,15 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - ret = get_ramdisk (cmdtp, flag, argc, argv, images, + ret = boot_get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_M68K, &rd_data_start, &rd_data_end); if (ret) goto error; rd_len = rd_data_end - rd_data_start; - ret = ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end); + ret = boot_ramdisk_high (lmb, rd_data_start, rd_len, + &initrd_start, &initrd_end); if (ret) goto error; diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c index 39869c1..b336a36 100644 --- a/lib_mips/bootm.c +++ b/lib_mips/bootm.c @@ -68,7 +68,7 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], } theKernel = (void (*)(int, char **, char **, int *))ep; - get_ramdisk (cmdtp, flag, argc, argv, images, + boot_get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_MIPS, &initrd_start, &initrd_end); show_boot_progress (15); diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 1afef46..8974ccd 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -41,9 +41,9 @@ #include static void fdt_error (const char *msg); -static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size); -static int fdt_relocate (struct lmb *lmb, ulong bootmap_base, +static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char **of_flat_tree, ulong *of_size); #endif @@ -122,7 +122,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ - ret = get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); + ret = boot_get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); if (ret) goto error; @@ -130,14 +130,14 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (!of_size) { /* allocate space and init command line */ - ret = get_boot_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); + ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); if (ret) { puts("ERROR with allocation of cmdline\n"); goto error; } /* allocate space for kernel copy of board info */ - ret = get_boot_kbd (lmb, &kbd, bootmap_base); + ret = boot_get_kbd (lmb, &kbd, bootmap_base); if (ret) { puts("ERROR with allocation of kernel bd\n"); goto error; @@ -160,7 +160,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - ret = get_ramdisk (cmdtp, flag, argc, argv, images, + ret = boot_get_ramdisk (cmdtp, flag, argc, argv, images, IH_ARCH_PPC, &rd_data_start, &rd_data_end); if (ret) @@ -169,7 +169,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], rd_len = rd_data_end - rd_data_start; #if defined(CONFIG_OF_LIBFDT) - ret = fdt_relocate (lmb, bootmap_base, + ret = boot_relocate_fdt (lmb, bootmap_base, cmdtp, flag, argc, argv, &of_flat_tree, &of_size); /* @@ -201,7 +201,7 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } #endif /* CONFIG_OF_LIBFDT */ - ret = ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end); + ret = boot_ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end); if (ret) goto error; @@ -354,7 +354,7 @@ static image_header_t *image_get_fdt (ulong fdt_addr) return fdt_hdr; } -static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], +static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size) { ulong fdt_addr; @@ -403,14 +403,14 @@ static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_addr); /* copy from dataflash if needed */ - fdt_addr = gen_get_image (fdt_addr); + fdt_addr = genimg_get_image (fdt_addr); /* * Check if there is an FDT image at the * address provided in the second bootm argument * check image type, for FIT images get a FIT node. */ - switch (gen_image_get_format ((void *)fdt_addr)) { + switch (genimg_get_format ((void *)fdt_addr)) { case IMAGE_FORMAT_LEGACY: debug ("* fdt: legacy format image\n"); @@ -527,7 +527,7 @@ error: return 1; } -static int fdt_relocate (struct lmb *lmb, ulong bootmap_base, +static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char **of_flat_tree, ulong *of_size) { diff --git a/tools/mkimage.c b/tools/mkimage.c index 8ced970..5119bc7 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -361,7 +361,7 @@ NXTARG: ; cmdname, file, strerror(errno)); exit (EXIT_FAILURE); } - size = cpu_to_image (sbuf.st_size); + size = cpu_to_uimage (sbuf.st_size); } else { size = 0; } @@ -604,7 +604,7 @@ print_header (image_header_t *hdr) pos = image_get_header_size () + ptrs * sizeof(long); printf ("Contents:\n"); for (i=0; len_ptr[i]; ++i) { - size = image_to_cpu (len_ptr[i]); + size = uimage_to_cpu (len_ptr[i]); printf (" Image %d: %8d Bytes = %4d kB = %d MB\n", i, size, size>>10, size>>20); -- cgit v0.10.2 From 570abb0ad120f6002bcaa3cf6f32bd4ca2e1b248 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Fri, 29 Feb 2008 15:59:59 +0100 Subject: [new uImage] Share common uImage code between mkimage and U-boot This patch adds the following common routines: 1) Dedicated mkimage print_header() is replaced with common image_print_contents() image_print_contents_noindent() 2) Common os/arch/type/comp fields name <--> id translation routines genimg_get_os_name() genimg_get_arch_name() genimg_get_type_name() genimg_get_comp_name() genimg_get_os_id() genimg_get_arch_id() genimg_get_type_id() genimg_get_comp_id() Signed-off-by: Marian Balakowicz diff --git a/common/image.c b/common/image.c index 99ed3b8..421a474 100644 --- a/common/image.c +++ b/common/image.c @@ -62,11 +62,95 @@ static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, ulong rd_addr, uint8_t arch, int verify); #else #include "mkimage.h" -#endif /* USE_HOSTCC*/ +#endif /* !USE_HOSTCC*/ #include +typedef struct table_entry { + int id; /* as defined in image.h */ + char *sname; /* short (input) name */ + char *lname; /* long (output) name */ +} table_entry_t; + +static table_entry_t uimage_arch[] = { + { IH_ARCH_INVALID, NULL, "Invalid ARCH", }, + { IH_ARCH_ALPHA, "alpha", "Alpha", }, + { IH_ARCH_ARM, "arm", "ARM", }, + { IH_ARCH_I386, "x86", "Intel x86", }, + { IH_ARCH_IA64, "ia64", "IA64", }, + { IH_ARCH_M68K, "m68k", "M68K", }, + { IH_ARCH_MICROBLAZE, "microblaze", "MicroBlaze", }, + { IH_ARCH_MIPS, "mips", "MIPS", }, + { IH_ARCH_MIPS64, "mips64", "MIPS 64 Bit", }, + { IH_ARCH_NIOS, "nios", "NIOS", }, + { IH_ARCH_NIOS2, "nios2", "NIOS II", }, + { IH_ARCH_PPC, "ppc", "PowerPC", }, + { IH_ARCH_S390, "s390", "IBM S390", }, + { IH_ARCH_SH, "sh", "SuperH", }, + { IH_ARCH_SPARC, "sparc", "SPARC", }, + { IH_ARCH_SPARC64, "sparc64", "SPARC 64 Bit", }, + { IH_ARCH_BLACKFIN, "blackfin", "Blackfin", }, + { IH_ARCH_AVR32, "avr32", "AVR32", }, + { -1, "", "", }, +}; + +static table_entry_t uimage_os[] = { + { IH_OS_INVALID, NULL, "Invalid OS", }, +#if defined(CONFIG_ARTOS) || defined(USE_HOSTCC) + { IH_OS_ARTOS, "artos", "ARTOS", }, +#endif + { IH_OS_LINUX, "linux", "Linux", }, +#if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC) + { IH_OS_LYNXOS, "lynxos", "LynxOS", }, +#endif + { IH_OS_NETBSD, "netbsd", "NetBSD", }, + { IH_OS_RTEMS, "rtems", "RTEMS", }, + { IH_OS_U_BOOT, "u-boot", "U-Boot", }, +#if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC) + { IH_OS_QNX, "qnx", "QNX", }, + { IH_OS_VXWORKS, "vxworks", "VxWorks", }, +#endif +#ifdef USE_HOSTCC + { IH_OS_4_4BSD, "4_4bsd", "4_4BSD", }, + { IH_OS_DELL, "dell", "Dell", }, + { IH_OS_ESIX, "esix", "Esix", }, + { IH_OS_FREEBSD, "freebsd", "FreeBSD", }, + { IH_OS_IRIX, "irix", "Irix", }, + { IH_OS_NCR, "ncr", "NCR", }, + { IH_OS_OPENBSD, "openbsd", "OpenBSD", }, + { IH_OS_PSOS, "psos", "pSOS", }, + { IH_OS_SCO, "sco", "SCO", }, + { IH_OS_SOLARIS, "solaris", "Solaris", }, + { IH_OS_SVR4, "svr4", "SVR4", }, +#endif + { -1, "", "", }, +}; + +static table_entry_t uimage_type[] = { + { IH_TYPE_INVALID, NULL, "Invalid Image", }, + { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, + { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, + { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, + { IH_TYPE_MULTI, "multi", "Multi-File Image", }, + { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, + { IH_TYPE_SCRIPT, "script", "Script", }, + { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, + { IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", }, + { -1, "", "", }, +}; + +static table_entry_t uimage_comp[] = { + { IH_COMP_NONE, "none", "uncompressed", }, + { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", }, + { IH_COMP_GZIP, "gzip", "gzip compressed", }, + { -1, "", "", }, +}; + unsigned long crc32 (unsigned long, const unsigned char *, unsigned int); +static void genimg_print_size (uint32_t size); +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) +static void genimg_print_time (time_t timestamp); +#endif /*****************************************************************************/ /* Legacy format routines */ @@ -122,6 +206,7 @@ int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz) return (dcrc == image_get_dcrc (hdr)); } +#endif /* !USE_HOSTCC */ /** * image_multi_count - get component (sub-image) count @@ -209,7 +294,6 @@ void image_multi_getimg (image_header_t *hdr, ulong idx, } } -#ifndef USE_HOSTCC static void image_print_type (image_header_t *hdr) { const char *os, *arch, *type, *comp; @@ -219,47 +303,59 @@ static void image_print_type (image_header_t *hdr) type = genimg_get_type_name (image_get_type (hdr)); comp = genimg_get_comp_name (image_get_comp (hdr)); - printf ("%s %s %s (%s)", arch, os, type, comp); + printf ("%s %s %s (%s)\n", arch, os, type, comp); } -void image_print_contents (image_header_t *hdr) +static void __image_print_contents (image_header_t *hdr, const char *p) { -#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)); - -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) - to_tm (timestamp, &tm); - 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); + printf ("%sImage Name: %.*s\n", p, IH_NMLEN, image_get_name (hdr)); +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) + printf ("%sCreated: ", p); + genimg_print_time ((time_t)image_get_time (hdr)); #endif - puts (" Image Type: "); + printf ("%sImage Type: ", p); image_print_type (hdr); + printf ("%sData Size: ", p); + genimg_print_size (image_get_data_size (hdr)); + printf ("%sLoad Address: %08x\n", p, image_get_load (hdr)); + printf ("%sEntry Point: %08x\n", p, image_get_ep (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", - image_get_load (hdr), image_get_ep (hdr)); - - if (image_check_type (hdr, IH_TYPE_MULTI)) { + if (image_check_type (hdr, IH_TYPE_MULTI) || + image_check_type (hdr, IH_TYPE_SCRIPT)) { int i; ulong data, len; ulong count = image_multi_count (hdr); - puts (" Contents:\n"); + printf ("%sContents:\n", p); for (i = 0; i < count; i++) { image_multi_getimg (hdr, i, &data, &len); - printf (" Image %d: %8ld Bytes = ", i, len); - print_size (len, "\n"); + + printf ("%s Image %d: ", p, i); + genimg_print_size (len); + + if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) { + /* + * the user may need to know offsets + * if planning to do something with + * multiple files + */ + printf ("%s Offset = 0x%08lx\n", p, data); + } } } } +inline void image_print_contents (image_header_t *hdr) +{ + __image_print_contents (hdr, " "); +} + +inline void image_print_contents_noindent (image_header_t *hdr) +{ + __image_print_contents (hdr, ""); +} + +#ifndef USE_HOSTCC /** * image_get_ramdisk - get and verify ramdisk image * @cmdtp: command table pointer @@ -329,10 +425,12 @@ static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, return rd_hdr; } +#endif /* !USE_HOSTCC */ /*****************************************************************************/ /* Shared dual-format routines */ /*****************************************************************************/ +#ifndef USE_HOSTCC int getenv_verify (void) { char *s = getenv ("verify"); @@ -386,94 +484,144 @@ void memmove_wd (void *to, void *from, size_t len, ulong chunksz) memmove (to, from, len); #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ } -#endif /* USE_HOSTCC */ +#endif /* !USE_HOSTCC */ -const char* genimg_get_os_name (uint8_t os) +static void genimg_print_size (uint32_t size) { - const char *name; - - switch (os) { - case IH_OS_INVALID: name = "Invalid OS"; break; - case IH_OS_NETBSD: name = "NetBSD"; break; - case IH_OS_LINUX: name = "Linux"; break; - case IH_OS_VXWORKS: name = "VxWorks"; break; - case IH_OS_QNX: name = "QNX"; break; - case IH_OS_U_BOOT: name = "U-Boot"; break; - case IH_OS_RTEMS: name = "RTEMS"; break; -#ifdef CONFIG_ARTOS - case IH_OS_ARTOS: name = "ARTOS"; break; +#ifndef USE_HOSTCC + printf ("%d Bytes = ", size); + print_size (size, "\n"); +#else + printf ("%d Bytes = %.2f kB = %.2f MB\n", + size, (double)size / 1.024e3, + (double)size / 1.048576e6); #endif -#ifdef CONFIG_LYNXKDI - case IH_OS_LYNXOS: name = "LynxOS"; break; +} + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) +static void genimg_print_time (time_t timestamp) +{ +#ifndef USE_HOSTCC + struct rtc_time tm; + + to_tm (timestamp, &tm); + printf ("%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); +#else + printf ("%s", ctime(×tamp)); #endif - default: name = "Unknown OS"; break; - } +} +#endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC */ - return name; -} - -const char* genimg_get_arch_name (uint8_t arch) -{ - const char *name; - - switch (arch) { - case IH_ARCH_INVALID: name = "Invalid Architecture"; break; - case IH_ARCH_ALPHA: name = "Alpha"; break; - case IH_ARCH_ARM: name = "ARM"; break; - case IH_ARCH_AVR32: name = "AVR32"; break; - case IH_ARCH_BLACKFIN: name = "Blackfin"; break; - case IH_ARCH_I386: name = "Intel x86"; break; - case IH_ARCH_IA64: name = "IA64"; break; - case IH_ARCH_M68K: name = "M68K"; break; - case IH_ARCH_MICROBLAZE:name = "Microblaze"; break; - case IH_ARCH_MIPS64: name = "MIPS 64 Bit"; break; - case IH_ARCH_MIPS: name = "MIPS"; break; - case IH_ARCH_NIOS2: name = "Nios-II"; break; - case IH_ARCH_NIOS: name = "Nios"; break; - case IH_ARCH_PPC: name = "PowerPC"; break; - case IH_ARCH_S390: name = "IBM S390"; break; - case IH_ARCH_SH: name = "SuperH"; break; - case IH_ARCH_SPARC64: name = "SPARC 64 Bit"; break; - case IH_ARCH_SPARC: name = "SPARC"; break; - default: name = "Unknown Architecture"; break; +/** + * get_table_entry_name - translate entry id to long name + * @table: pointer to a translation table for entries of a specific type + * @msg: message to be returned when translation fails + * @id: entry id to be translated + * + * get_table_entry_name() will go over translation table trying to find + * entry that matches given id. If matching entry is found, its long + * name is returned to the caller. + * + * returns: + * long entry name if translation succeeds + * msg otherwise + */ +static char *get_table_entry_name (table_entry_t *table, char *msg, int id) +{ + for (; table->id >= 0; ++table) { + if (table->id == id) + return (table->lname); } + return (msg); +} - return name; +const char *genimg_get_os_name (uint8_t os) +{ + return (get_table_entry_name (uimage_os, "Unknown OS", os)); } -const char* genimg_get_type_name (uint8_t type) +const char *genimg_get_arch_name (uint8_t arch) { - const char *name; + return (get_table_entry_name (uimage_arch, "Unknown Architecture", arch)); +} - switch (type) { - case IH_TYPE_INVALID: name = "Invalid Image"; break; - case IH_TYPE_STANDALONE:name = "Standalone Program"; break; - case IH_TYPE_KERNEL: name = "Kernel Image"; break; - case IH_TYPE_RAMDISK: name = "RAMDisk Image"; break; - case IH_TYPE_MULTI: name = "Multi-File Image"; break; - case IH_TYPE_FIRMWARE: name = "Firmware"; break; - case IH_TYPE_SCRIPT: name = "Script"; break; - case IH_TYPE_FLATDT: name = "Flat Device Tree"; break; - default: name = "Unknown Image"; break; - } +const char *genimg_get_type_name (uint8_t type) +{ + return (get_table_entry_name (uimage_type, "Unknown Image", type)); +} - return name; +const char *genimg_get_comp_name (uint8_t comp) +{ + return (get_table_entry_name (uimage_comp, "Unknown Compression", comp)); } -const char* genimg_get_comp_name (uint8_t comp) +/** + * get_table_entry_id - translate short entry name to id + * @table: pointer to a translation table for entries of a specific type + * @table_name: to be used in case of error + * @name: entry short name to be translated + * + * get_table_entry_id() will go over translation table trying to find + * entry that matches given short name. If matching entry is found, + * its id returned to the caller. + * + * returns: + * entry id if translation succeeds + * -1 otherwise + */ +static int get_table_entry_id (table_entry_t *table, + const char *table_name, const char *name) { - const char *name; + table_entry_t *t; +#ifdef USE_HOSTCC + int first = 1; - switch (comp) { - case IH_COMP_NONE: name = "uncompressed"; break; - case IH_COMP_GZIP: name = "gzip compressed"; break; - case IH_COMP_BZIP2: name = "bzip2 compressed"; break; - default: name = "unknown compression"; break; + for (t = table; t->id >= 0; ++t) { + if (t->sname && strcasecmp(t->sname, name) == 0) + return (t->id); } - return name; + fprintf (stderr, "\nInvalid %s Type - valid names are", table_name); + for (t = table; t->id >= 0; ++t) { + if (t->sname == NULL) + continue; + fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname); + first = 0; + } + fprintf (stderr, "\n"); +#else + for (t = table; t->id >= 0; ++t) { + if (t->sname && strcmp(t->sname, name) == 0) + return (t->id); + } + debug ("Invalid %s Type: %s\n", table_name, name); +#endif /* USE_HOSTCC */ + return (-1); +} + +int genimg_get_os_id (const char *name) +{ + return (get_table_entry_id (uimage_os, "OS", name)); +} + +int genimg_get_arch_id (const char *name) +{ + return (get_table_entry_id (uimage_arch, "CPU", name)); } +int genimg_get_type_id (const char *name) +{ + return (get_table_entry_id (uimage_type, "Image", name)); +} + +int genimg_get_comp_id (const char *name) +{ + return (get_table_entry_id (uimage_comp, "Compression", name)); +} + +#ifndef USE_HOSTCC /** * genimg_get_format - get image format type * @img_addr: image start address @@ -971,5 +1119,4 @@ inline int fit_parse_subimage (const char *spec, ulong addr_curr, } #endif /* CONFIG_FIT */ - -#endif /* USE_HOSTCC */ +#endif /* !USE_HOSTCC */ diff --git a/include/image.h b/include/image.h index b520691..ed79552 100644 --- a/include/image.h +++ b/include/image.h @@ -219,6 +219,15 @@ typedef struct bootm_headers { #define uimage_to_cpu(x) ntohl(x) #define cpu_to_uimage(x) htonl(x) +const char *genimg_get_os_name (uint8_t os); +const char *genimg_get_arch_name (uint8_t arch); +const char *genimg_get_type_name (uint8_t type); +const char *genimg_get_comp_name (uint8_t comp); +int genimg_get_os_id (const char *name); +int genimg_get_arch_id (const char *name); +int genimg_get_type_id (const char *name); +int genimg_get_comp_id (const char *name); + #ifndef USE_HOSTCC /* Image format types, returned by _get_format() routine */ #define IMAGE_FORMAT_INVALID 0x00 @@ -228,11 +237,6 @@ typedef struct bootm_headers { int genimg_get_format (void *img_addr); ulong genimg_get_image (ulong img_addr); -const char* genimg_get_os_name (uint8_t os); -const char* genimg_get_arch_name (uint8_t arch); -const char* genimg_get_type_name (uint8_t type); -const char* genimg_get_comp_name (uint8_t comp); - int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end); @@ -245,7 +249,7 @@ int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, ulong bootmap_base); int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base); #endif /* CONFIG_PPC || CONFIG_M68K */ -#endif /* USE_HOSTCC */ +#endif /* !USE_HOSTCC */ /*******************************************************************/ /* Legacy format specific code (prefixed with image_) */ @@ -373,6 +377,9 @@ ulong image_multi_count (image_header_t *hdr); void image_multi_getimg (image_header_t *hdr, ulong idx, ulong *data, ulong *len); +inline void image_print_contents (image_header_t *hdr); +inline void image_print_contents_noindent (image_header_t *hdr); + #ifndef USE_HOSTCC static inline int image_check_target_arch (image_header_t *hdr) { @@ -406,8 +413,6 @@ static inline int image_check_target_arch (image_header_t *hdr) return 1; } -void image_print_contents (image_header_t *hdr); - /*******************************************************************/ /* New uImage format specific code (prefixed with fit_) */ /*******************************************************************/ diff --git a/tools/mkimage.c b/tools/mkimage.c index 5119bc7..5cb2bc7 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -29,100 +29,13 @@ extern int errno; #define MAP_FAILED (-1) #endif -char *cmdname; - -extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len); - -typedef struct table_entry { - int val; /* as defined in image.h */ - char *sname; /* short (input) name */ - char *lname; /* long (output) name */ -} table_entry_t; - -table_entry_t arch_name[] = { - { IH_ARCH_INVALID, NULL, "Invalid CPU", }, - { IH_ARCH_ALPHA, "alpha", "Alpha", }, - { IH_ARCH_ARM, "arm", "ARM", }, - { IH_ARCH_I386, "x86", "Intel x86", }, - { IH_ARCH_IA64, "ia64", "IA64", }, - { IH_ARCH_M68K, "m68k", "MC68000", }, - { IH_ARCH_MICROBLAZE, "microblaze", "MicroBlaze", }, - { IH_ARCH_MIPS, "mips", "MIPS", }, - { IH_ARCH_MIPS64, "mips64", "MIPS 64 Bit", }, - { IH_ARCH_NIOS, "nios", "NIOS", }, - { IH_ARCH_NIOS2, "nios2", "NIOS II", }, - { IH_ARCH_PPC, "ppc", "PowerPC", }, - { IH_ARCH_S390, "s390", "IBM S390", }, - { IH_ARCH_SH, "sh", "SuperH", }, - { IH_ARCH_SPARC, "sparc", "SPARC", }, - { IH_ARCH_SPARC64, "sparc64", "SPARC 64 Bit", }, - { IH_ARCH_BLACKFIN, "blackfin", "Blackfin", }, - { IH_ARCH_AVR32, "avr32", "AVR32", }, - { -1, "", "", }, -}; - -table_entry_t os_name[] = { - { IH_OS_INVALID, NULL, "Invalid OS", }, - { IH_OS_4_4BSD, "4_4bsd", "4_4BSD", }, - { IH_OS_ARTOS, "artos", "ARTOS", }, - { IH_OS_DELL, "dell", "Dell", }, - { IH_OS_ESIX, "esix", "Esix", }, - { IH_OS_FREEBSD, "freebsd", "FreeBSD", }, - { IH_OS_IRIX, "irix", "Irix", }, - { IH_OS_LINUX, "linux", "Linux", }, - { IH_OS_LYNXOS, "lynxos", "LynxOS", }, - { IH_OS_NCR, "ncr", "NCR", }, - { IH_OS_NETBSD, "netbsd", "NetBSD", }, - { IH_OS_OPENBSD, "openbsd", "OpenBSD", }, - { IH_OS_PSOS, "psos", "pSOS", }, - { IH_OS_QNX, "qnx", "QNX", }, - { IH_OS_RTEMS, "rtems", "RTEMS", }, - { IH_OS_SCO, "sco", "SCO", }, - { IH_OS_SOLARIS, "solaris", "Solaris", }, - { IH_OS_SVR4, "svr4", "SVR4", }, - { IH_OS_U_BOOT, "u-boot", "U-Boot", }, - { IH_OS_VXWORKS, "vxworks", "VxWorks", }, - { -1, "", "", }, -}; - -table_entry_t type_name[] = { - { IH_TYPE_INVALID, NULL, "Invalid Image", }, - { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, - { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, - { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, - { IH_TYPE_MULTI, "multi", "Multi-File Image", }, - { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, - { IH_TYPE_SCRIPT, "script", "Script", }, - { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, - { IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", }, - { -1, "", "", }, -}; - -table_entry_t comp_name[] = { - { IH_COMP_NONE, "none", "uncompressed", }, - { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", }, - { IH_COMP_GZIP, "gzip", "gzip compressed", }, - { -1, "", "", }, -}; - -static void copy_file (int, const char *, int); -static void usage (void); -static void print_header (image_header_t *); -static void print_type (image_header_t *); -static char *put_table_entry (table_entry_t *, char *, int); -static char *put_arch (int); -static char *put_type (int); -static char *put_os (int); -static char *put_comp (int); -static int get_table_entry (table_entry_t *, char *, char *); -static int get_arch(char *); -static int get_comp(char *); -static int get_os (char *); -static int get_type(char *); - +extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len); +static void copy_file (int, const char *, int); +static void usage (void); char *datafile; char *imagefile; +char *cmdname; int dflag = 0; int eflag = 0; @@ -160,22 +73,22 @@ main (int argc, char **argv) break; case 'A': if ((--argc <= 0) || - (opt_arch = get_arch(*++argv)) < 0) + (opt_arch = genimg_get_arch_id (*++argv)) < 0) usage (); goto NXTARG; case 'C': if ((--argc <= 0) || - (opt_comp = get_comp(*++argv)) < 0) + (opt_comp = genimg_get_comp_id (*++argv)) < 0) usage (); goto NXTARG; case 'O': if ((--argc <= 0) || - (opt_os = get_os(*++argv)) < 0) + (opt_os = genimg_get_os_id (*++argv)) < 0) usage (); goto NXTARG; case 'T': if ((--argc <= 0) || - (opt_type = get_type(*++argv)) < 0) + (opt_type = genimg_get_type_id (*++argv)) < 0) usage (); goto NXTARG; @@ -323,7 +236,7 @@ NXTARG: ; } /* for multi-file images we need the data part, too */ - print_header ((image_header_t *)ptr); + image_print_contents_noindent ((image_header_t *)ptr); (void) munmap((void *)ptr, sbuf.st_size); (void) close (ifd); @@ -448,7 +361,7 @@ NXTARG: ; image_set_hcrc (hdr, checksum); - print_header (hdr); + image_print_contents_noindent (hdr); (void) munmap((void *)ptr, sbuf.st_size); @@ -570,140 +483,3 @@ usage () ); exit (EXIT_FAILURE); } - -static void -print_header (image_header_t *hdr) -{ - time_t timestamp; - uint32_t size; - - timestamp = (time_t)image_get_time (hdr); - size = image_get_data_size (hdr); - - printf ("Image Name: %.*s\n", IH_NMLEN, image_get_name (hdr)); - printf ("Created: %s", ctime(×tamp)); - printf ("Image Type: "); print_type(hdr); - printf ("Data Size: %d Bytes = %.2f kB = %.2f MB\n", - size, (double)size / 1.024e3, (double)size / 1.048576e6 ); - printf ("Load Address: 0x%08X\n", image_get_load (hdr)); - printf ("Entry Point: 0x%08X\n", image_get_ep (hdr)); - - if (image_check_type (hdr, IH_TYPE_MULTI) || - image_check_type (hdr, IH_TYPE_SCRIPT)) { - int i, ptrs; - uint32_t pos; - uint32_t *len_ptr = (uint32_t *) ( - (unsigned long)hdr + image_get_header_size () - ); - - /* determine number of images first (to calculate image offsets) */ - for (i=0; len_ptr[i]; ++i) /* null pointer terminates list */ - ; - ptrs = i; /* null pointer terminates list */ - - pos = image_get_header_size () + ptrs * sizeof(long); - printf ("Contents:\n"); - for (i=0; len_ptr[i]; ++i) { - size = uimage_to_cpu (len_ptr[i]); - - printf (" Image %d: %8d Bytes = %4d kB = %d MB\n", - i, size, size>>10, size>>20); - if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) { - /* - * the user may need to know offsets - * if planning to do something with - * multiple files - */ - printf (" Offset = %08X\n", pos); - } - /* copy_file() will pad the first files to even word align */ - size += 3; - size &= ~3; - pos += size; - } - } -} - - -static void -print_type (image_header_t *hdr) -{ - printf ("%s %s %s (%s)\n", - put_arch (image_get_arch (hdr)), - put_os (image_get_os (hdr)), - put_type (image_get_type (hdr)), - put_comp (image_get_comp (hdr)) - ); -} - -static char *put_arch (int arch) -{ - return (put_table_entry(arch_name, "Unknown Architecture", arch)); -} - -static char *put_os (int os) -{ - return (put_table_entry(os_name, "Unknown OS", os)); -} - -static char *put_type (int type) -{ - return (put_table_entry(type_name, "Unknown Image", type)); -} - -static char *put_comp (int comp) -{ - return (put_table_entry(comp_name, "Unknown Compression", comp)); -} - -static char *put_table_entry (table_entry_t *table, char *msg, int type) -{ - for (; table->val>=0; ++table) { - if (table->val == type) - return (table->lname); - } - return (msg); -} - -static int get_arch(char *name) -{ - return (get_table_entry(arch_name, "CPU", name)); -} - - -static int get_comp(char *name) -{ - return (get_table_entry(comp_name, "Compression", name)); -} - - -static int get_os (char *name) -{ - return (get_table_entry(os_name, "OS", name)); -} - - -static int get_type(char *name) -{ - return (get_table_entry(type_name, "Image", name)); -} - -static int get_table_entry (table_entry_t *table, char *msg, char *name) -{ - table_entry_t *t; - int first = 1; - - for (t=table; t->val>=0; ++t) { - if (t->sname && strcasecmp(t->sname, name)==0) - return (t->val); - } - fprintf (stderr, "\nInvalid %s Type - valid names are", msg); - for (t=table; t->val>=0; ++t) { - if (t->sname == NULL) - continue; - fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname); - first = 0; - } - fprintf (stderr, "\n"); - return (-1); -} -- cgit v0.10.2 From df6f1b895c997978f03afe04502ee76b7ba34ab9 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Fri, 29 Feb 2008 16:00:06 +0100 Subject: [new uImage] Fix component handling for legacy multi component images Use uint32_t when accessing size table in image_multi_count() and image_multi_getimg() for multi component images. Add missing uimage_to_cpu() endianness conversion. Signed-off-by: Marian Balakowicz diff --git a/common/image.c b/common/image.c index 421a474..3911b2f 100644 --- a/common/image.c +++ b/common/image.c @@ -224,11 +224,11 @@ int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz) ulong image_multi_count (image_header_t *hdr) { ulong i, count = 0; - ulong *size; + uint32_t *size; /* get start of the image payload, which in case of multi * component images that points to a table of component sizes */ - size = (ulong *)image_get_data (hdr); + size = (uint32_t *)image_get_data (hdr); /* count non empty slots */ for (i = 0; size[i]; ++i) @@ -258,7 +258,7 @@ void image_multi_getimg (image_header_t *hdr, ulong idx, ulong *data, ulong *len) { int i; - ulong *size; + uint32_t *size; ulong offset, tail, count, img_data; /* get number of component */ @@ -266,24 +266,24 @@ void image_multi_getimg (image_header_t *hdr, ulong idx, /* get start of the image payload, which in case of multi * component images that points to a table of component sizes */ - size = (ulong *)image_get_data (hdr); + size = (uint32_t *)image_get_data (hdr); /* get address of the proper component data start, which means * skipping sizes table (add 1 for last, null entry) */ - img_data = image_get_data (hdr) + (count + 1) * sizeof (ulong); + img_data = image_get_data (hdr) + (count + 1) * sizeof (uint32_t); if (idx < count) { - *len = size[idx]; + *len = uimage_to_cpu (size[idx]); offset = 0; tail = 0; /* go over all indices preceding requested component idx */ for (i = 0; i < idx; i++) { /* add up i-th component size */ - offset += size[i]; + offset += uimage_to_cpu (size[i]); /* add up alignment for i-th component */ - tail += (4 - size[i] % 4); + tail += (4 - uimage_to_cpu (size[i]) % 4); } /* calculate idx-th component data address */ -- cgit v0.10.2 From a6e530f00d31a8494a0422799b2b9a692a9c0eb9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Fri, 29 Feb 2008 16:00:23 +0100 Subject: [new uImage] Add sha1.o object to mkimage binary build Signed-off-by: Bartlomiej Sieka diff --git a/tools/Makefile b/tools/Makefile index cbfca6d..0cc4cc9 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -137,7 +137,7 @@ $(obj)img2srec$(SFX): $(obj)img2srec.o $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(STRIP) $@ -$(obj)mkimage$(SFX): $(obj)mkimage.o $(obj)crc32.o $(obj)image.o +$(obj)mkimage$(SFX): $(obj)mkimage.o $(obj)crc32.o $(obj)image.o $(obj)sha1.o $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(STRIP) $@ diff --git a/tools/mkimage.h b/tools/mkimage.h index 8b05bb1..a01977e 100644 --- a/tools/mkimage.h +++ b/tools/mkimage.h @@ -32,6 +32,7 @@ #include #include #include +#include #if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__) #include -- cgit v0.10.2 From 8cf30809a82902a471866d2f07725ce3b8a22291 Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Fri, 29 Feb 2008 16:00:24 +0100 Subject: [new uImage] Add libfdt support to mkimage Signed-off-by: Bartlomiej Sieka diff --git a/Makefile b/Makefile index bacea3e..adfef9b 100644 --- a/Makefile +++ b/Makefile @@ -2927,6 +2927,9 @@ clobber: clean @rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL) @rm -f $(obj)tools/crc32.c $(obj)tools/environment.c $(obj)tools/env/crc32.c @rm -f $(obj)tools/sha1.c $(obj)tools/image.c + @rm -f $(obj)tools/fdt.c $(obj)tools/fdt_ro.c $(obj)tools/fdt_rw.c + @rm -f $(obj)tools/fdt_strerror.c $(obj)tools/fdt_wip.c + @rm -f $(obj)tools/libfdt_internal.h @rm -f $(obj)tools/inca-swap-bytes $(obj)cpu/mpc824x/bedbug_603e.c @rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm @[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f diff --git a/include/libfdt_env.h b/include/libfdt_env.h index 78f7258..98c522a 100644 --- a/include/libfdt_env.h +++ b/include/libfdt_env.h @@ -24,7 +24,11 @@ #include #include #include +#ifdef USE_HOSTCC +#include +#else #include +#endif /* USE_HOSTCC */ extern struct fdt_header *fdt; /* Pointer to the working fdt */ diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 586a361..071470d 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -50,8 +50,12 @@ */ #include "libfdt_env.h" +#ifndef USE_HOSTCC #include #include +#else +#include "fdt_host.h" +#endif #include "libfdt_internal.h" diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 12a37d5..1ae3a55 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -50,8 +50,12 @@ */ #include "libfdt_env.h" +#ifndef USE_HOSTCC #include #include +#else +#include "fdt_host.h" +#endif #include "libfdt_internal.h" diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index 6673f8e..2fb81dd 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -50,8 +50,12 @@ */ #include "libfdt_env.h" +#ifndef USE_HOSTCC #include #include +#else +#include "fdt_host.h" +#endif #include "libfdt_internal.h" diff --git a/libfdt/fdt_strerror.c b/libfdt/fdt_strerror.c index f9d32ef..abf792e 100644 --- a/libfdt/fdt_strerror.c +++ b/libfdt/fdt_strerror.c @@ -50,8 +50,12 @@ */ #include "libfdt_env.h" +#ifndef USE_HOSTCC #include #include +#else +#include "fdt_host.h" +#endif #include "libfdt_internal.h" diff --git a/libfdt/fdt_wip.c b/libfdt/fdt_wip.c index 88e24b8..24e1724 100644 --- a/libfdt/fdt_wip.c +++ b/libfdt/fdt_wip.c @@ -50,8 +50,12 @@ */ #include "libfdt_env.h" +#ifndef USE_HOSTCC #include #include +#else +#include "fdt_host.h" +#endif #include "libfdt_internal.h" diff --git a/tools/.gitignore b/tools/.gitignore index c33679a..0ce2e77 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -7,3 +7,10 @@ /mkimage /sha1.c /ubsha1 +/image.c +/fdt.c +/fdt_ro.c +/fdt_rw.c +/fdt_strerror.c +/fdt_wip.c +/libfdt_internal.h diff --git a/tools/Makefile b/tools/Makefile index 0cc4cc9..aa4af18 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -37,6 +37,8 @@ endif #OBJ_FILES += mpc86x_clk.o #endif +LIBFDT_OBJ_FILES = fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o + LOGO_H = $(OBJTREE)/include/bmp_logo.h ifeq ($(LOGO_BMP),) @@ -120,6 +122,10 @@ CPPFLAGS = -idirafter $(SRCTREE)/include \ -idirafter $(OBJTREE)/include \ -DTEXT_BASE=$(TEXT_BASE) -DUSE_HOSTCC CFLAGS = $(HOST_CFLAGS) $(CPPFLAGS) -O + +# No -pedantic switch to avoid libfdt compilation warnings +FIT_CFLAGS = -Wall $(CPPFLAGS) -O + AFLAGS = -D__ASSEMBLY__ $(CPPFLAGS) CC = $(HOSTCC) STRIP = $(HOSTSTRIP) @@ -137,7 +143,7 @@ $(obj)img2srec$(SFX): $(obj)img2srec.o $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(STRIP) $@ -$(obj)mkimage$(SFX): $(obj)mkimage.o $(obj)crc32.o $(obj)image.o $(obj)sha1.o +$(obj)mkimage$(SFX): $(obj)mkimage.o $(obj)crc32.o $(obj)image.o $(obj)sha1.o $(LIBFDT_OBJ_FILES) $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(STRIP) $@ @@ -174,10 +180,10 @@ $(obj)sha1.o: $(obj)sha1.c $(CC) -g $(CFLAGS) -c -o $@ $< $(obj)image.o: $(obj)image.c - $(CC) -g $(CFLAGS) -c -o $@ $< + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< $(obj)mkimage.o: $(src)mkimage.c - $(CC) -g $(CFLAGS) -c -o $@ $< + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< $(obj)ncb.o: $(src)ncb.c $(CC) -g $(CFLAGS) -c -o $@ $< @@ -191,6 +197,21 @@ $(obj)inca-swap-bytes.o: $(src)inca-swap-bytes.c $(obj)mpc86x_clk.o: $(src)mpc86x_clk.c $(CC) -g $(CFLAGS) -c -o $@ $< +$(obj)fdt.o: $(obj)fdt.c + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< + +$(obj)fdt_ro.o: $(obj)fdt_ro.c + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< + +$(obj)fdt_rw.o: $(obj)fdt_rw.c + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< + +$(obj)fdt_strerror.o: $(obj)fdt_strerror.c + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< + +$(obj)fdt_wip.o: $(obj)fdt_wip.c + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< + subdirs: ifeq ($(TOOLSUBDIRS),) @: @@ -224,6 +245,30 @@ $(obj)image.c: @rm -f $(obj)image.c ln -s $(src)../common/image.c $(obj)image.c +$(obj)fdt.c: libfdt_internal.h + @rm -f $(obj)fdt.c + ln -s $(src)../libfdt/fdt.c $(obj)fdt.c + +$(obj)fdt_ro.c: libfdt_internal.h + @rm -f $(obj)fdt_ro.c + ln -s $(src)../libfdt/fdt_ro.c $(obj)fdt_ro.c + +$(obj)fdt_rw.c: libfdt_internal.h + @rm -f $(obj)fdt_rw.c + ln -s $(src)../libfdt/fdt_rw.c $(obj)fdt_rw.c + +$(obj)fdt_strerror.c: libfdt_internal.h + @rm -f $(obj)fdt_strerror.c + ln -s $(src)../libfdt/fdt_strerror.c $(obj)fdt_strerror.c + +$(obj)fdt_wip.c: libfdt_internal.h + @rm -f $(obj)fdt_wip.c + ln -s $(src)../libfdt/fdt_wip.c $(obj)fdt_wip.c + +$(obj)libfdt_internal.h: + @rm -f $(obj)libfdt_internal.h + ln -s $(src)../libfdt/libfdt_internal.h $(obj)libfdt_internal.h + $(LOGO_H): $(obj)bmp_logo $(LOGO_BMP) $(obj)./bmp_logo $(LOGO_BMP) >$@ diff --git a/tools/fdt_host.h b/tools/fdt_host.h new file mode 100644 index 0000000..085013e --- /dev/null +++ b/tools/fdt_host.h @@ -0,0 +1,28 @@ +/* + * (C) Copyright 2008 Semihalf + * + * 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 + */ + +#ifndef __FDT_HOST_H__ +#define __FDT_HOST_H__ + +/* Make sure to include u-boot version of libfdt include files */ +#include "../include/fdt.h" +#include "../include/libfdt.h" +#include "../include/fdt_support.h" + +#endif /* __FDT_HOST_H__ */ diff --git a/tools/mkimage.h b/tools/mkimage.h index a01977e..cdd52bc 100644 --- a/tools/mkimage.h +++ b/tools/mkimage.h @@ -33,6 +33,7 @@ #include #include #include +#include "fdt_host.h" #if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__) #include -- cgit v0.10.2 From d1cc52879c8966507dad9fb575481e6d3985e64e Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 12 Feb 2008 00:58:31 +1100 Subject: libfdt: Add and use a node iteration helper function. This patch adds an fdt_next_node() function which can be used to iterate through nodes of the tree while keeping track of depth. This function is used to simplify the iteration code in a lot of other functions, and is also exported for use by library users. Signed-off-by: David Gibson diff --git a/include/libfdt.h b/include/libfdt.h index 6c05236..3a64d0b 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -131,6 +131,12 @@ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); /**********************************************************************/ +/* Traversal functions */ +/**********************************************************************/ + +int fdt_next_node(const void *fdt, int offset, int *depth); + +/**********************************************************************/ /* General functions */ /**********************************************************************/ diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 071470d..660e2c1 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -133,6 +133,47 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset) return tag; } +int fdt_next_node(const void *fdt, int offset, int *depth) +{ + int nextoffset = 0; + uint32_t tag; + + if (offset >= 0) { + tag = fdt_next_tag(fdt, offset, &nextoffset); + if (tag != FDT_BEGIN_NODE) + return -FDT_ERR_BADOFFSET; + } + + do { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_PROP: + case FDT_NOP: + break; + + case FDT_BEGIN_NODE: + if (depth) + (*depth)++; + break; + + case FDT_END_NODE: + if (depth) + (*depth)--; + break; + + case FDT_END: + return -FDT_ERR_NOTFOUND; + + default: + return -FDT_ERR_BADSTRUCTURE; + } + } while (tag != FDT_BEGIN_NODE); + + return offset; +} + const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) { int len = strlen(s) + 1; diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 1ae3a55..031a15f 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -69,7 +69,7 @@ static int nodename_eq(const void *fdt, int offset, const char *s, int len) { - const char *p = fdt_offset_ptr(fdt, offset, len+1); + const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); if (! p) /* short match */ @@ -108,50 +108,24 @@ int fdt_num_mem_rsv(const void *fdt) return i; } -int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, +int fdt_subnode_offset_namelen(const void *fdt, int offset, const char *name, int namelen) { - int level = 0; - uint32_t tag; - int offset, nextoffset; + int depth; CHECK_HEADER(fdt); - tag = fdt_next_tag(fdt, parentoffset, &nextoffset); - if (tag != FDT_BEGIN_NODE) - return -FDT_ERR_BADOFFSET; - - do { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - - switch (tag) { - case FDT_END: - return -FDT_ERR_TRUNCATED; - - case FDT_BEGIN_NODE: - level++; - if (level != 1) - continue; - if (nodename_eq(fdt, offset+FDT_TAGSIZE, name, namelen)) - /* Found it! */ - return offset; - break; - - case FDT_END_NODE: - level--; - break; - - case FDT_PROP: - case FDT_NOP: - break; - - default: - return -FDT_ERR_BADSTRUCTURE; - } - } while (level >= 0); + for (depth = 0; + offset >= 0; + offset = fdt_next_node(fdt, offset, &depth)) { + if (depth < 0) + return -FDT_ERR_NOTFOUND; + else if ((depth == 1) + && nodename_eq(fdt, offset, name, namelen)) + return offset; + } - return -FDT_ERR_NOTFOUND; + return offset; /* error */ } int fdt_subnode_offset(const void *fdt, int parentoffset, @@ -311,76 +285,61 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) { - uint32_t tag; - int p = 0, overflow = 0; - int offset, nextoffset, namelen; + int pdepth = 0, p = 0; + int offset, depth, namelen; const char *name; CHECK_HEADER(fdt); - tag = fdt_next_tag(fdt, 0, &nextoffset); - if (tag != FDT_BEGIN_NODE) - return -FDT_ERR_BADSTRUCTURE; - if (buflen < 2) return -FDT_ERR_NOSPACE; - buf[0] = '/'; - p = 1; - while (nextoffset <= nodeoffset) { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - switch (tag) { - case FDT_END: - return -FDT_ERR_BADOFFSET; + for (offset = 0, depth = 0; + (offset >= 0) && (offset <= nodeoffset); + offset = fdt_next_node(fdt, offset, &depth)) { + if (pdepth < depth) + continue; /* overflowed buffer */ - case FDT_BEGIN_NODE: - name = fdt_get_name(fdt, offset, &namelen); - if (!name) - return namelen; - if (overflow || ((p + namelen + 1) > buflen)) { - overflow++; - break; - } + while (pdepth > depth) { + do { + p--; + } while (buf[p-1] != '/'); + pdepth--; + } + + name = fdt_get_name(fdt, offset, &namelen); + if (!name) + return namelen; + if ((p + namelen + 1) <= buflen) { memcpy(buf + p, name, namelen); p += namelen; buf[p++] = '/'; - break; - - case FDT_END_NODE: - if (overflow) { - overflow--; - break; - } - do { - p--; - } while (buf[p-1] != '/'); - break; + pdepth++; + } - case FDT_PROP: - case FDT_NOP: - break; + if (offset == nodeoffset) { + if (pdepth < (depth + 1)) + return -FDT_ERR_NOSPACE; - default: - return -FDT_ERR_BADSTRUCTURE; + if (p > 1) /* special case so that root path is "/", not "" */ + p--; + buf[p] = '\0'; + return p; } } - if (overflow) - return -FDT_ERR_NOSPACE; + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; - if (p > 1) /* special case so that root path is "/", not "" */ - p--; - buf[p] = '\0'; - return p; + return offset; /* error from fdt_next_node() */ } int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, int supernodedepth, int *nodedepth) { - int level = -1; - uint32_t tag; - int offset, nextoffset = 0; + int offset, depth; int supernodeoffset = -FDT_ERR_INTERNAL; CHECK_HEADER(fdt); @@ -388,38 +347,29 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, if (supernodedepth < 0) return -FDT_ERR_NOTFOUND; - do { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - switch (tag) { - case FDT_END: - return -FDT_ERR_BADOFFSET; - - case FDT_BEGIN_NODE: - level++; - if (level == supernodedepth) - supernodeoffset = offset; - break; - - case FDT_END_NODE: - level--; - break; + for (offset = 0, depth = 0; + (offset >= 0) && (offset <= nodeoffset); + offset = fdt_next_node(fdt, offset, &depth)) { + if (depth == supernodedepth) + supernodeoffset = offset; - case FDT_PROP: - case FDT_NOP: - break; + if (offset == nodeoffset) { + if (nodedepth) + *nodedepth = depth; - default: - return -FDT_ERR_BADSTRUCTURE; + if (supernodedepth > depth) + return -FDT_ERR_NOTFOUND; + else + return supernodeoffset; } - } while (offset < nodeoffset); + } - if (nodedepth) - *nodedepth = level; + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; - if (supernodedepth > level) - return -FDT_ERR_NOTFOUND; - return supernodeoffset; + return offset; /* error from fdt_next_node() */ } int fdt_node_depth(const void *fdt, int nodeoffset) @@ -447,51 +397,27 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, const char *propname, const void *propval, int proplen) { - uint32_t tag; - int offset, nextoffset; + int offset; const void *val; int len; CHECK_HEADER(fdt); - if (startoffset >= 0) { - tag = fdt_next_tag(fdt, startoffset, &nextoffset); - if (tag != FDT_BEGIN_NODE) - return -FDT_ERR_BADOFFSET; - } else { - nextoffset = 0; - } - /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_getprop(), then if that didn't * find what we want, we scan over them again making our way * to the next node. Still it's the easiest to implement * approach; performance can come later. */ - do { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - - switch (tag) { - case FDT_BEGIN_NODE: - val = fdt_getprop(fdt, offset, propname, &len); - if (val - && (len == proplen) - && (memcmp(val, propval, len) == 0)) - return offset; - break; - - case FDT_PROP: - case FDT_END: - case FDT_END_NODE: - case FDT_NOP: - break; - - default: - return -FDT_ERR_BADSTRUCTURE; - } - } while (tag != FDT_END); + for (offset = fdt_next_node(fdt, startoffset, NULL); + offset >= 0; + offset = fdt_next_node(fdt, offset, NULL)) { + val = fdt_getprop(fdt, offset, propname, &len); + if (val && (len == proplen) + && (memcmp(val, propval, len) == 0)) + return offset; + } - return -FDT_ERR_NOTFOUND; + return offset; /* error from fdt_next_node() */ } int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) @@ -557,31 +483,15 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, * that didn't find what we want, we scan over them again * making our way to the next node. Still it's the easiest to * implement approach; performance can come later. */ - do { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - - switch (tag) { - case FDT_BEGIN_NODE: - err = fdt_node_check_compatible(fdt, offset, - compatible); - if ((err < 0) - && (err != -FDT_ERR_NOTFOUND)) - return err; - else if (err == 0) - return offset; - break; - - case FDT_PROP: - case FDT_END: - case FDT_END_NODE: - case FDT_NOP: - break; - - default: - return -FDT_ERR_BADSTRUCTURE; - } - } while (tag != FDT_END); + for (offset = fdt_next_node(fdt, startoffset, NULL); + offset >= 0; + offset = fdt_next_node(fdt, offset, NULL)) { + err = fdt_node_check_compatible(fdt, offset, compatible); + if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) + return err; + else if (err == 0) + return offset; + } - return -FDT_ERR_NOTFOUND; + return offset; /* error from fdt_next_node() */ } -- cgit v0.10.2 From 05e07b1ea22844e946cfcf7d5e8a0199d18d2a95 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Fri, 29 Feb 2008 22:22:46 +0100 Subject: [new uImage] Fix FDT blob totalsize calculation in boot_relocate_fdt() Do not use global fdt blob pointer, calculate blob size from routine argument blob pointer. Signed-off-by: Marian Balakowicz diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 8974ccd..7977157 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -557,7 +557,7 @@ static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, if (fdt_blob >= (char *)CFG_BOOTMAPSZ) relocate = 1; - of_len = be32_to_cpu (fdt_totalsize (fdt)); + of_len = be32_to_cpu (fdt_totalsize (fdt_blob)); /* move flattend device tree if needed */ if (relocate) { -- cgit v0.10.2 From 5dfb52138688ccbf0146f62683fe6217b3ce1b05 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Fri, 29 Feb 2008 21:24:06 +0100 Subject: [new uImage] New uImage low-level API Add FDT-based functions for handling new format component images, configurations, node operations, property get/set, etc. fit_ - routines handling global new format uImage operations like get/set top level property, process all nodes, etc. fit_image_ - routines handling component images subnodes fit_conf_ - routines handling configurations node Signed-off-by: Bartlomiej Sieka Signed-off-by: Marian Balakowicz diff --git a/common/image.c b/common/image.c index 3911b2f..9278ea9 100644 --- a/common/image.c +++ b/common/image.c @@ -45,10 +45,13 @@ #include #endif +#include + #if defined(CONFIG_FIT) #include #include #include +#include #endif #ifdef CONFIG_CMD_BDI @@ -62,9 +65,9 @@ static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, ulong rd_addr, uint8_t arch, int verify); #else #include "mkimage.h" -#endif /* !USE_HOSTCC*/ - +#include #include +#endif /* !USE_HOSTCC*/ typedef struct table_entry { int id; /* as defined in image.h */ @@ -306,6 +309,18 @@ static void image_print_type (image_header_t *hdr) printf ("%s %s %s (%s)\n", arch, os, type, comp); } +/** + * __image_print_contents - prints out the contents of the legacy format image + * @hdr: pointer to the legacy format image header + * @p: pointer to prefix string + * + * __image_print_contents() formats a multi line legacy image contents description. + * The routine prints out all header fields followed by the size/offset data + * for MULTI/SCRIPT images. + * + * returns: + * no returned results + */ static void __image_print_contents (image_header_t *hdr, const char *p) { printf ("%sImage Name: %.*s\n", p, IH_NMLEN, image_get_name (hdr)); @@ -701,7 +716,7 @@ ulong genimg_get_image (ulong img_addr) break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - d_size = fdt_totalsize((void *)ram_addr) - h_size; + d_size = fit_get_size ((const void *)ram_addr) - h_size; debug (" FIT/FDT format image found at 0x%08lx, size 0x%08lx\n", ram_addr, d_size); break; @@ -1040,11 +1055,13 @@ int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base) return 0; } #endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* !USE_HOSTCC */ #if defined(CONFIG_FIT) /*****************************************************************************/ /* New uImage format routines */ /*****************************************************************************/ +#ifndef USE_HOSTCC static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr, ulong *addr, const char **name) { @@ -1117,6 +1134,1246 @@ inline int fit_parse_subimage (const char *spec, ulong addr_curr, { return fit_parse_spec (spec, ':', addr_curr, addr, image_name); } +#endif /* !USE_HOSTCC */ + +static void fit_get_debug (const void *fit, int noffset, + char *prop_name, int err) +{ + debug ("Can't get '%s' property from FIT 0x%08lx, " + "node: offset %d, name %s (%s)\n", + prop_name, (ulong)fit, noffset, + fit_get_name (fit, noffset, NULL), + fdt_strerror (err)); +} + +/** + * __fit_print_contents - prints out the contents of the FIT format image + * @fit: pointer to the FIT format image header + * @p: pointer to prefix string + * + * __fit_print_contents() formats a multi line FIT image contents description. + * The routine prints out FIT image properties (root node level) follwed by + * the details of each component image. + * + * returns: + * no returned results + */ +static void __fit_print_contents (const void *fit, const char *p) +{ + char *desc; + char *uname; + int images_noffset; + int confs_noffset; + int noffset; + int ndepth; + int count = 0; + int ret; +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) + time_t timestamp; +#endif + + /* Root node properties */ + ret = fit_get_desc (fit, 0, &desc); + printf ("%sFIT description: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("%s\n", desc); + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) + ret = fit_get_timestamp (fit, 0, ×tamp); + printf ("%sCreated: ", p); + if (ret) + printf ("unavailable\n"); + else + genimg_print_time (timestamp); +#endif + + /* Find images parent node offset */ + images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + printf ("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror (images_noffset)); + return; + } + + /* Process its subnodes, print out component images details */ + for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the images parent node, + * i.e. component image node. + */ + printf ("%s Image %u (%s)\n", p, count++, + fit_get_name(fit, noffset, NULL)); + + fit_image_print (fit, noffset, p); + } + } + + /* Find configurations parent node offset */ + confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH); + if (confs_noffset < 0) { + debug ("Can't get configurations parent node '%s' (%s)\n", + FIT_CONFS_PATH, fdt_strerror (confs_noffset)); + return; + } + + /* get default configuration unit name from default property */ + uname = (char *)fdt_getprop (fit, noffset, FIT_DEFAULT_PROP, NULL); + if (uname) + printf ("%s Default Configuration: '%s'\n", p, uname); + + /* Process its subnodes, print out configurations details */ + for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, confs_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the configurations parent node, + * i.e. configuration node. + */ + printf ("%s Configuration %u (%s)\n", p, count++, + fit_get_name(fit, noffset, NULL)); + + fit_conf_print (fit, noffset, p); + } + } +} + +inline void fit_print_contents (const void *fit) +{ + __fit_print_contents (fit, " "); +} + +inline void fit_print_contents_noindent (const void *fit) +{ + __fit_print_contents (fit, ""); +} + +/** + * fit_image_print - prints out the FIT component image details + * @fit: pointer to the FIT format image header + * @image_noffset: offset of the component image node + * @p: pointer to prefix string + * + * fit_image_print() lists all mandatory properies for the processed component + * image. If present, hash nodes are printed out as well. + * + * returns: + * no returned results + */ +void fit_image_print (const void *fit, int image_noffset, const char *p) +{ + char *desc; + uint8_t type, arch, os, comp; + size_t size; + ulong load, entry; + const void *data; + int noffset; + int ndepth; + int ret; + + /* Mandatory properties */ + ret = fit_get_desc (fit, image_noffset, &desc); + printf ("%s Description: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("%s\n", desc); + + fit_image_get_type (fit, image_noffset, &type); + printf ("%s Type: %s\n", p, genimg_get_type_name (type)); + + fit_image_get_comp (fit, image_noffset, &comp); + printf ("%s Compression: %s\n", p, genimg_get_comp_name (comp)); + + ret = fit_image_get_data (fit, image_noffset, &data, &size); + +#ifndef USE_HOSTCC + printf ("%s Data Start: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("0x%08lx\n", (ulong)data); +#endif + + printf ("%s Data Size: ", p); + if (ret) + printf ("unavailable\n"); + else + genimg_print_size (size); + + /* Remaining, type dependent properties */ + if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || + (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) || + (type == IH_TYPE_FLATDT)) { + fit_image_get_arch (fit, image_noffset, &arch); + printf ("%s Architecture: %s\n", p, genimg_get_arch_name (arch)); + } + + if (type == IH_TYPE_KERNEL) { + fit_image_get_os (fit, image_noffset, &os); + printf ("%s OS: %s\n", p, genimg_get_os_name (os)); + } + + if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) { + ret = fit_image_get_load (fit, image_noffset, &load); + printf ("%s Load Address: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("0x%08lx\n", load); + + fit_image_get_entry (fit, image_noffset, &entry); + printf ("%s Entry Point: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("0x%08lx\n", entry); + } + + /* Process all hash subnodes of the component image node */ + for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* Direct child node of the component image node */ + fit_image_print_hash (fit, noffset, p); + } + } +} + +/** + * fit_image_print_hash - prints out the hash node details + * @fit: pointer to the FIT format image header + * @noffset: offset of the hash node + * @p: pointer to prefix string + * + * fit_image_print_hash() lists properies for the processed hash node + * + * returns: + * no returned results + */ +void fit_image_print_hash (const void *fit, int noffset, const char *p) +{ + char *algo; + uint8_t *value; + int value_len; + int i, ret; + + /* + * Check subnode name, must be equal to "hash". + * Multiple hash nodes require unique unit node + * names, e.g. hash@1, hash@2, etc. + */ + if (strncmp (fit_get_name(fit, noffset, NULL), + FIT_HASH_NODENAME, + strlen(FIT_HASH_NODENAME)) != 0) + return; + + debug ("%s Hash node: '%s'\n", p, + fit_get_name (fit, noffset, NULL)); + + printf ("%s Hash algo: ", p); + if (fit_image_hash_get_algo (fit, noffset, &algo)) { + printf ("invalid/unsupported\n"); + return; + } + printf ("%s\n", algo); + + ret = fit_image_hash_get_value (fit, noffset, &value, + &value_len); + printf ("%s Hash value: ", p); + if (ret) { + printf ("unavailable\n"); + } else { + for (i = 0; i < value_len; i++) + printf ("%02x", value[i]); + printf ("\n"); + } + + debug ("%s Hash len: %d\n", p, value_len); +} + +/** + * fit_get_desc - get node description property + * @fit: pointer to the FIT format image header + * @noffset: node offset + * @desc: double pointer to the char, will hold pointer to the descrption + * + * fit_get_desc() reads description property from a given node, if + * description is found pointer to it is returened in third call argument. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_get_desc (const void *fit, int noffset, char **desc) +{ + int len; + + *desc = (char *)fdt_getprop (fit, noffset, FIT_DESC_PROP, &len); + if (*desc == NULL) { + fit_get_debug (fit, noffset, FIT_DESC_PROP, len); + return -1; + } + + return 0; +} + +/** + * fit_get_timestamp - get node timestamp property + * @fit: pointer to the FIT format image header + * @noffset: node offset + * @timestamp: pointer to the time_t, will hold read timestamp + * + * fit_get_timestamp() reads timestamp poperty from given node, if timestamp + * is found and has a correct size its value is retured in third call + * argument. + * + * returns: + * 0, on success + * -1, on property read failure + * -2, on wrong timestamp size + */ +int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp) +{ + int len; + const void *data; + + data = fdt_getprop (fit, noffset, FIT_TIMESTAMP_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_TIMESTAMP_PROP, len); + return -1; + } + if (len != sizeof (uint32_t)) { + debug ("FIT timestamp with incorrect size of (%u)\n", len); + return -2; + } + + *timestamp = uimage_to_cpu (*((uint32_t *)data)); + return 0; +} + +/** + * fit_image_get_node - get node offset for component image of a given unit name + * @fit: pointer to the FIT format image header + * @image_uname: component image node unit name + * + * fit_image_get_node() finds a component image (withing the '/images' + * node) of a provided unit name. If image is found its node offset is + * returned to the caller. + * + * returns: + * image node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_image_get_node (const void *fit, const char *image_uname) +{ + int noffset, images_noffset; + + images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + debug ("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror (images_noffset)); + return images_noffset; + } + + noffset = fdt_subnode_offset (fit, images_noffset, image_uname); + if (noffset < 0) { + debug ("Can't get node offset for image unit name: '%s' (%s)\n", + image_uname, fdt_strerror (noffset)); + } + + return noffset; +} + +/** + * fit_image_get_os - get os id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @os: pointer to the uint8_t, will hold os numeric id + * + * fit_image_get_os() finds os property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_os (const void *fit, int noffset, uint8_t *os) +{ + int len; + const void *data; + + /* Get OS name from property data */ + data = fdt_getprop (fit, noffset, FIT_OS_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_OS_PROP, len); + *os = -1; + return -1; + } + + /* Translate OS name to id */ + *os = genimg_get_os_id (data); + return 0; +} + +/** + * fit_image_get_arch - get arch id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @arch: pointer to the uint8_t, will hold arch numeric id + * + * fit_image_get_arch() finds arch property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch) +{ + int len; + const void *data; + + /* Get architecture name from property data */ + data = fdt_getprop (fit, noffset, FIT_ARCH_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_ARCH_PROP, len); + *arch = -1; + return -1; + } + + /* Translate architecture name to id */ + *arch = genimg_get_arch_id (data); + return 0; +} + +/** + * fit_image_get_type - get type id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @type: pointer to the uint8_t, will hold type numeric id + * + * fit_image_get_type() finds type property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_type (const void *fit, int noffset, uint8_t *type) +{ + int len; + const void *data; + + /* Get image type name from property data */ + data = fdt_getprop (fit, noffset, FIT_TYPE_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_TYPE_PROP, len); + *type = -1; + return -1; + } + + /* Translate image type name to id */ + *type = genimg_get_type_id (data); + return 0; +} + +/** + * fit_image_get_comp - get comp id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @comp: pointer to the uint8_t, will hold comp numeric id + * + * fit_image_get_comp() finds comp property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp) +{ + int len; + const void *data; + + /* Get compression name from property data */ + data = fdt_getprop (fit, noffset, FIT_COMP_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_COMP_PROP, len); + *comp = -1; + return -1; + } + + /* Translate compression name to id */ + *comp = genimg_get_comp_id (data); + return 0; +} + +/** + * fit_image_get_load - get load address property for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @load: pointer to the uint32_t, will hold load address + * + * fit_image_get_load() finds load address property in a given component image node. + * If the property is found, its value is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_load (const void *fit, int noffset, ulong *load) +{ + int len; + const uint32_t *data; + + data = fdt_getprop (fit, noffset, FIT_LOAD_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_LOAD_PROP, len); + return -1; + } + + *load = uimage_to_cpu (*data); + return 0; +} + +/** + * fit_image_get_entry - get entry point address property for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @entry: pointer to the uint32_t, will hold entry point address + * + * fit_image_get_entry() finds entry point address property in a given component image node. + * If the property is found, its value is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_entry (const void *fit, int noffset, ulong *entry) +{ + int len; + const uint32_t *data; + + data = fdt_getprop (fit, noffset, FIT_ENTRY_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_ENTRY_PROP, len); + return -1; + } + + *entry = uimage_to_cpu (*data); + return 0; +} + +/** + * fit_image_get_data - get data property and its size for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @data: double pointer to void, will hold data property's data address + * @size: pointer to size_t, will hold data property's data size + * + * fit_image_get_data() finds data property in a given component image node. + * If the property is found its data start address and size are returned to + * the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_data (const void *fit, int noffset, + const void **data, size_t *size) +{ + int len; + + *data = fdt_getprop (fit, noffset, FIT_DATA_PROP, &len); + if (*data == NULL) { + fit_get_debug (fit, noffset, FIT_DATA_PROP, len); + *size = 0; + return -1; + } + + *size = len; + return 0; +} + +/** + * fit_image_hash_get_algo - get hash algorithm name + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @algo: double pointer to char, will hold pointer to the algorithm name + * + * fit_image_hash_get_algo() finds hash algorithm property in a given hash node. + * If the property is found its data start address is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_hash_get_algo (const void *fit, int noffset, char **algo) +{ + int len; + + *algo = (char *)fdt_getprop (fit, noffset, FIT_ALGO_PROP, &len); + if (*algo == NULL) { + fit_get_debug (fit, noffset, FIT_ALGO_PROP, len); + return -1; + } + + return 0; +} + +/** + * fit_image_hash_get_value - get hash value and length + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @value: double pointer to uint8_t, will hold address of a hash value data + * @value_len: pointer to an int, will hold hash data length + * + * fit_image_hash_get_value() finds hash value property in a given hash node. + * If the property is found its data start address and size are returned to + * the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value, + int *value_len) +{ + int len; + + *value = (uint8_t *)fdt_getprop (fit, noffset, FIT_VALUE_PROP, &len); + if (*value == NULL) { + fit_get_debug (fit, noffset, FIT_VALUE_PROP, len); + *value_len = 0; + return -1; + } + + *value_len = len; + return 0; +} + +/** + * fit_set_timestamp - set node timestamp property + * @fit: pointer to the FIT format image header + * @noffset: node offset + * @timestamp: timestamp value to be set + * + * fit_set_timestamp() attempts to set timestamp property in the requested + * node and returns operation status to the caller. + * + * returns: + * 0, on success + * -1, on property read failure + */ +int fit_set_timestamp (void *fit, int noffset, time_t timestamp) +{ + uint32_t t; + int ret; + + t = cpu_to_uimage (timestamp); + ret = fdt_setprop (fit, noffset, FIT_TIMESTAMP_PROP, &t, + sizeof (uint32_t)); + if (ret) { + printf ("Can't set '%s' property for '%s' node (%s)\n", + FIT_TIMESTAMP_PROP, fit_get_name (fit, noffset, NULL), + fdt_strerror (ret)); + return -1; + } + + return 0; +} + +/** + * calculate_hash - calculate and return hash for provided input data + * @data: pointer to the input data + * @data_len: data length + * @algo: requested hash algorithm + * @value: pointer to the char, will hold hash value data (caller must + * allocate enough free space) + * value_len: length of the calculated hash + * + * calculate_hash() computes input data hash according to the requested algorithm. + * Resulting hash value is placed in caller provided 'value' buffer, length + * of the calculated hash is returned via value_len pointer argument. + * + * returns: + * 0, on success + * -1, when algo is unsupported + */ +static int calculate_hash (const void *data, int data_len, const char *algo, + uint8_t *value, int *value_len) +{ + if (strcmp (algo, "crc32") == 0 ) { + *((uint32_t *)value) = crc32 (0, data, data_len); + *((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value)); + *value_len = 4; + } else if (strcmp (algo, "sha1") == 0 ) { + sha1_csum ((unsigned char *) data, data_len, + (unsigned char *) value); + *value_len = 20; + } else if (strcmp (algo, "md5") == 0 ) { + printf ("MD5 not supported\n"); + *value_len = 0; + } else { + debug ("Unsupported hash alogrithm\n"); + return -1; + } + return 0; +} + +#ifdef USE_HOSTCC +/** + * fit_set_hashes - process FIT component image nodes and calculate hashes + * @fit: pointer to the FIT format image header + * + * fit_set_hashes() adds hash values for all component images in the FIT blob. + * Hashes are calculated for all component images which have hash subnodes + * with algorithm property set to one of the supported hash algorithms. + * + * returns + * 0, on success + * libfdt error code, on failure + */ +int fit_set_hashes (void *fit) +{ + int images_noffset; + int noffset; + int ndepth; + int ret; + + /* Find images parent node offset */ + images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + printf ("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror (images_noffset)); + return images_noffset; + } + + /* Process its subnodes, print out component images details */ + for (ndepth = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the images parent node, + * i.e. component image node. + */ + ret = fit_image_set_hashes (fit, noffset); + if (ret) + return ret; + } + } + + return 0; +} + +/** + * fit_image_set_hashes - calculate/set hashes for given component image node + * @fit: pointer to the FIT format image header + * @image_noffset: requested component image node + * + * fit_image_set_hashes() adds hash values for an component image node. All + * existing hash subnodes are checked, if algorithm property is set to one of + * the supported hash algorithms, hash value is computed and corresponding + * hash node property is set, for example: + * + * Input component image node structure: + * + * o image@1 (at image_noffset) + * | - data = [binary data] + * o hash@1 + * |- algo = "sha1" + * + * Output component image node structure: + * + * o image@1 (at image_noffset) + * | - data = [binary data] + * o hash@1 + * |- algo = "sha1" + * |- value = sha1(data) + * + * returns: + * 0 on sucess + * <0 on failure + */ +int fit_image_set_hashes (void *fit, int image_noffset) +{ + const void *data; + size_t size; + char *algo; + uint8_t value[FIT_MAX_HASH_LEN]; + int value_len; + int noffset; + int ndepth; + + /* Get image data and data length */ + if (fit_image_get_data (fit, image_noffset, &data, &size)) { + printf ("Can't get image data/size\n"); + return -1; + } + + /* Process all hash subnodes of the component image node */ + for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* Direct child node of the component image node */ + + /* + * Check subnode name, must be equal to "hash". + * Multiple hash nodes require unique unit node + * names, e.g. hash@1, hash@2, etc. + */ + if (strncmp (fit_get_name(fit, noffset, NULL), + FIT_HASH_NODENAME, + strlen(FIT_HASH_NODENAME)) != 0) { + /* Not a hash subnode, skip it */ + continue; + } + + if (fit_image_hash_get_algo (fit, noffset, &algo)) { + printf ("Can't get hash algo property for " + "'%s' hash node in '%s' image node\n", + fit_get_name (fit, noffset, NULL), + fit_get_name (fit, image_noffset, NULL)); + return -1; + } + + if (calculate_hash (data, size, algo, value, &value_len)) { + printf ("Unsupported hash algorithm (%s) for " + "'%s' hash node in '%s' image node\n", + algo, fit_get_name (fit, noffset, NULL), + fit_get_name (fit, image_noffset, NULL)); + return -1; + } + + if (fit_image_hash_set_value (fit, noffset, value, + value_len)) { + printf ("Can't set hash value for " + "'%s' hash node in '%s' image node\n", + fit_get_name (fit, noffset, NULL), + fit_get_name (fit, image_noffset, NULL)); + return -1; + } + } + } + + return 0; +} + +/** + * fit_image_hash_set_value - set hash value in requested has node + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @value: hash value to be set + * @value_len: hash value length + * + * fit_image_hash_set_value() attempts to set hash value in a node at offset + * given and returns operation status to the caller. + * + * returns + * 0, on success + * -1, on failure + */ +int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value, + int value_len) +{ + int ret; + + ret = fdt_setprop (fit, noffset, FIT_VALUE_PROP, value, value_len); + if (ret) { + printf ("Can't set hash '%s' property for '%s' node (%s)\n", + FIT_VALUE_PROP, fit_get_name (fit, noffset, NULL), + fdt_strerror (ret)); + return -1; + } + + return 0; +} +#endif /* USE_HOSTCC */ + +/** + * fit_image_check_hashes - verify data intergity + * @fit: pointer to the FIT format image header + * @image_noffset: component image node offset + * + * fit_image_check_hashes() goes over component image hash nodes, + * re-calculates each data hash and compares with the value stored in hash + * node. + * + * returns: + * 1, if all hashes are valid + * 0, otherwise (or on error) + */ +int fit_image_check_hashes (const void *fit, int image_noffset) +{ + const void *data; + size_t size; + char *algo; + uint8_t *fit_value; + int fit_value_len; + uint8_t value[FIT_MAX_HASH_LEN]; + int value_len; + int noffset; + int ndepth; + char *err_msg = ""; + + /* Get image data and data length */ + if (fit_image_get_data (fit, image_noffset, &data, &size)) { + printf ("Can't get image data/size\n"); + return 0; + } + + /* Process all hash subnodes of the component image node */ + for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* Direct child node of the component image node */ + + /* + * Check subnode name, must be equal to "hash". + * Multiple hash nodes require unique unit node + * names, e.g. hash@1, hash@2, etc. + */ + if (strncmp (fit_get_name(fit, noffset, NULL), + FIT_HASH_NODENAME, + strlen(FIT_HASH_NODENAME)) != 0) + continue; + + if (fit_image_hash_get_algo (fit, noffset, &algo)) { + err_msg = "Can't get hash algo property"; + goto error; + } + printf ("%s", algo); + + if (fit_image_hash_get_value (fit, noffset, &fit_value, + &fit_value_len)) { + err_msg = "Can't get hash value property"; + goto error; + } + + if (calculate_hash (data, size, algo, value, &value_len)) { + err_msg = "Unsupported hash algorithm"; + goto error; + } + + if (value_len != fit_value_len) { + err_msg = "Bad hash value len"; + goto error; + } else if (memcmp (value, fit_value, value_len) != 0) { + err_msg = "Bad hash value"; + goto error; + } + printf ("+ "); + } + } + + return 1; + +error: + printf ("%s for '%s' hash node in '%s' image node\n", + err_msg, fit_get_name (fit, noffset, NULL), + fit_get_name (fit, image_noffset, NULL)); + return 0; +} + +/** + * fit_image_check_os - check whether image node is of a given os type + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @os: requested image os + * + * fit_image_check_os() reads image os property and compares its numeric + * id with the requested os. Comparison result is returned to the caller. + * + * returns: + * 1 if image is of given os type + * 0 otherwise (or on error) + */ +int fit_image_check_os (const void *fit, int noffset, uint8_t os) +{ + uint8_t image_os; + + if (fit_image_get_os (fit, noffset, &image_os)) + return 0; + return (os == image_os); +} + +/** + * fit_image_check_arch - check whether image node is of a given arch + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @arch: requested imagearch + * + * fit_image_check_arch() reads image arch property and compares its numeric + * id with the requested arch. Comparison result is returned to the caller. + * + * returns: + * 1 if image is of given arch + * 0 otherwise (or on error) + */ +int fit_image_check_arch (const void *fit, int noffset, uint8_t arch) +{ + uint8_t image_arch; + + if (fit_image_get_arch (fit, noffset, &image_arch)) + return 0; + return (arch == image_arch); +} + +/** + * fit_image_check_type - check whether image node is of a given type + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @type: requested image type + * + * fit_image_check_type() reads image type property and compares its numeric + * id with the requested type. Comparison result is returned to the caller. + * + * returns: + * 1 if image is of given type + * 0 otherwise (or on error) + */ +int fit_image_check_type (const void *fit, int noffset, uint8_t type) +{ + uint8_t image_type; + + if (fit_image_get_type (fit, noffset, &image_type)) + return 0; + return (type == image_type); +} + +/** + * fit_image_check_comp - check whether image node uses given compression + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @comp: requested image compression type + * + * fit_image_check_comp() reads image compression property and compares its + * numeric id with the requested compression type. Comparison result is + * returned to the caller. + * + * returns: + * 1 if image uses requested compression + * 0 otherwise (or on error) + */ +int fit_image_check_comp (const void *fit, int noffset, uint8_t comp) +{ + uint8_t image_comp; + + if (fit_image_get_comp (fit, noffset, &image_comp)) + return 0; + return (comp == image_comp); +} + +/** + * fit_check_format - sanity check FIT image format + * @fit: pointer to the FIT format image header + * + * fit_check_format() runs a basic sanity FIT image verification. + * Routine checks for mandatory properties, nodes, etc. + * + * returns: + * 1, on success + * 0, on failure + */ +int fit_check_format (const void *fit) +{ + /* mandatory / node 'description' property */ + if (fdt_getprop (fit, 0, FIT_DESC_PROP, NULL) == NULL) { + debug ("Wrong FIT format: no description\n"); + return 0; + } + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) + /* mandatory / node 'timestamp' property */ + if (fdt_getprop (fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) { + debug ("Wrong FIT format: no description\n"); + return 0; + } +#endif + + /* mandatory subimages parent '/images' node */ + if (fdt_path_offset (fit, FIT_IMAGES_PATH) < 0) { + debug ("Wrong FIT format: no images parent node\n"); + return 0; + } + + return 1; +} + +/** + * fit_conf_get_node - get node offset for configuration of a given unit name + * @fit: pointer to the FIT format image header + * @conf_uname: configuration node unit name + * + * fit_conf_get_node() finds a configuration (withing the '/configurations' + * parant node) of a provided unit name. If configuration is found its node offset + * is returned to the caller. + * + * When NULL is provided in second argument fit_conf_get_node() will search + * for a default configuration node instead. Default configuration node unit name + * is retrived from FIT_DEFAULT_PROP property of the '/configurations' node. + * + * returns: + * configuration node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_node (const void *fit, const char *conf_uname) +{ + int noffset, confs_noffset; + int len; + + confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH); + if (confs_noffset < 0) { + debug ("Can't find configurations parent node '%s' (%s)\n", + FIT_CONFS_PATH, fdt_strerror (confs_noffset)); + return confs_noffset; + } + + if (conf_uname == NULL) { + /* get configuration unit name from the default property */ + debug ("No configuration specified, trying default...\n"); + conf_uname = (char *)fdt_getprop (fit, confs_noffset, FIT_DEFAULT_PROP, &len); + if (conf_uname == NULL) { + fit_get_debug (fit, confs_noffset, FIT_DEFAULT_PROP, len); + return len; + } + debug ("Found default configuration: '%s'\n", conf_uname); + } + + noffset = fdt_subnode_offset (fit, confs_noffset, conf_uname); + if (noffset < 0) { + debug ("Can't get node offset for configuration unit name: '%s' (%s)\n", + conf_uname, fdt_strerror (noffset)); + } + + return noffset; +} + +static int __fit_conf_get_prop_node (const void *fit, int noffset, + const char *prop_name) +{ + char *uname; + int len; + + /* get kernel image unit name from configuration kernel property */ + uname = (char *)fdt_getprop (fit, noffset, prop_name, &len); + if (uname == NULL) + return len; + + return fit_image_get_node (fit, uname); +} + +/** + * fit_conf_get_kernel_node - get kernel image node offset that corresponds to + * a given configuration + * @fit: pointer to the FIT format image header + * @noffset: configuration node offset + * + * fit_conf_get_kernel_node() retrives kernel image node unit name from + * configuration FIT_KERNEL_PROP property and translates it to the node + * offset. + * + * returns: + * image node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_kernel_node (const void *fit, int noffset) +{ + return __fit_conf_get_prop_node (fit, noffset, FIT_KERNEL_PROP); +} + +/** + * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to + * a given configuration + * @fit: pointer to the FIT format image header + * @noffset: configuration node offset + * + * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from + * configuration FIT_KERNEL_PROP property and translates it to the node + * offset. + * + * returns: + * image node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_ramdisk_node (const void *fit, int noffset) +{ + return __fit_conf_get_prop_node (fit, noffset, FIT_RAMDISK_PROP); +} + +/** + * fit_conf_get_fdt_node - get fdt image node offset that corresponds to + * a given configuration + * @fit: pointer to the FIT format image header + * @noffset: configuration node offset + * + * fit_conf_get_fdt_node() retrives fdt image node unit name from + * configuration FIT_KERNEL_PROP property and translates it to the node + * offset. + * + * returns: + * image node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_fdt_node (const void *fit, int noffset) +{ + return __fit_conf_get_prop_node (fit, noffset, FIT_FDT_PROP); +} +/** + * fit_conf_print - prints out the FIT configuration details + * @fit: pointer to the FIT format image header + * @conf_noffset: offset of the configuration node + * @p: pointer to prefix string + * + * fit_conf_print() lists all mandatory properies for the processed + * configuration node. + * + * returns: + * no returned results + */ +void fit_conf_print (const void *fit, int noffset, const char *p) +{ + char *desc; + char *uname; + int ret; + + /* Mandatory properties */ + ret = fit_get_desc (fit, noffset, &desc); + printf ("%s Description: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("%s\n", desc); + + uname = (char *)fdt_getprop (fit, noffset, FIT_KERNEL_PROP, NULL); + printf ("%s Kernel: ", p); + if (uname == NULL) + printf ("unavailable\n"); + else + printf ("%s\n", uname); + + /* Optional properties */ + uname = (char *)fdt_getprop (fit, noffset, FIT_RAMDISK_PROP, NULL); + if (uname) + printf ("%s Init Ramdisk: %s\n", p, uname); + + uname = (char *)fdt_getprop (fit, noffset, FIT_FDT_PROP, NULL); + if (uname) + printf ("%s FDT: %s\n", p, uname); +} #endif /* CONFIG_FIT */ -#endif /* !USE_HOSTCC */ diff --git a/include/image.h b/include/image.h index ed79552..704a3b4 100644 --- a/include/image.h +++ b/include/image.h @@ -40,6 +40,7 @@ #include #include #include +#endif /* USE_HOSTCC */ /* new uImage format support enabled by default */ #define CONFIG_FIT 1 @@ -51,7 +52,12 @@ #if defined(CONFIG_FIT) && !defined(CONFIG_OF_LIBFDT) #error "CONFIG_OF_LIBFDT not enabled, required by CONFIG_FIT!" #endif -#endif /* USE_HOSTCC */ + +#if defined(CONFIG_FIT) +#include +#include +#include +#endif /* * Operating System Codes @@ -412,16 +418,160 @@ static inline int image_check_target_arch (image_header_t *hdr) return 1; } +#endif /* USE_HOSTCC */ /*******************************************************************/ /* New uImage format specific code (prefixed with fit_) */ /*******************************************************************/ #if defined(CONFIG_FIT) + +#define FIT_IMAGES_PATH "/images" +#define FIT_CONFS_PATH "/configurations" + +/* hash node */ +#define FIT_HASH_NODENAME "hash" +#define FIT_ALGO_PROP "algo" +#define FIT_VALUE_PROP "value" + +/* image node */ +#define FIT_DATA_PROP "data" +#define FIT_TIMESTAMP_PROP "timestamp" +#define FIT_DESC_PROP "description" +#define FIT_ARCH_PROP "arch" +#define FIT_TYPE_PROP "type" +#define FIT_OS_PROP "os" +#define FIT_COMP_PROP "compression" +#define FIT_ENTRY_PROP "entry" +#define FIT_LOAD_PROP "load" + +/* configuration node */ +#define FIT_KERNEL_PROP "kernel" +#define FIT_RAMDISK_PROP "ramdisk" +#define FIT_FDT_PROP "fdt" +#define FIT_DEFAULT_PROP "default" + +#define FIT_MAX_HASH_LEN 20 /* max(crc32_len(4), sha1_len(20)) */ + +/* cmdline argument format parsing */ inline int fit_parse_conf (const char *spec, ulong addr_curr, ulong *addr, const char **conf_name); inline int fit_parse_subimage (const char *spec, ulong addr_curr, ulong *addr, const char **image_name); +inline void fit_print_contents (const void *fit); +inline void fit_print_contents_noindent (const void *fit); +void fit_image_print (const void *fit, int noffset, const char *p); +void fit_image_print_hash (const void *fit, int noffset, const char *p); + +/** + * fit_get_end - get FIT image size + * @fit: pointer to the FIT format image header + * + * returns: + * size of the FIT image (blob) in memory + */ +static inline ulong fit_get_size (const void *fit) +{ + return fdt_totalsize (fit); +} + +/** + * fit_get_end - get FIT image end + * @fit: pointer to the FIT format image header + * + * returns: + * end address of the FIT image (blob) in memory + */ +static inline ulong fit_get_end (const void *fit) +{ + return (ulong)fit + fdt_totalsize (fit); +} + +/** + * fit_get_name - get FIT node name + * @fit: pointer to the FIT format image header + * + * returns: + * NULL, on error + * pointer to node name, on success + */ +static inline const char *fit_get_name (const void *fit_hdr, + int noffset, int *len) +{ + return fdt_get_name (fit_hdr, noffset, len); +} + +int fit_get_desc (const void *fit, int noffset, char **desc); +int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp); + +int fit_image_get_node (const void *fit, const char *image_uname); +int fit_image_get_os (const void *fit, int noffset, uint8_t *os); +int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch); +int fit_image_get_type (const void *fit, int noffset, uint8_t *type); +int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp); +int fit_image_get_load (const void *fit, int noffset, ulong *load); +int fit_image_get_entry (const void *fit, int noffset, ulong *entry); +int fit_image_get_data (const void *fit, int noffset, + const void **data, size_t *size); + +int fit_image_hash_get_algo (const void *fit, int noffset, char **algo); +int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value, + int *value_len); + +int fit_set_timestamp (void *fit, int noffset, time_t timestamp); +int fit_set_hashes (void *fit); +int fit_image_set_hashes (void *fit, int image_noffset); +int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value, + int value_len); + +int fit_image_check_hashes (const void *fit, int noffset); +int fit_image_check_os (const void *fit, int noffset, uint8_t os); +int fit_image_check_arch (const void *fit, int noffset, uint8_t arch); +int fit_image_check_type (const void *fit, int noffset, uint8_t type); +int fit_image_check_comp (const void *fit, int noffset, uint8_t comp); +int fit_check_format (const void *fit); + +int fit_conf_get_node (const void *fit, const char *conf_uname); +int fit_conf_get_kernel_node (const void *fit, int noffset); +int fit_conf_get_ramdisk_node (const void *fit, int noffset); +int fit_conf_get_fdt_node (const void *fit, int noffset); + +void fit_conf_print (const void *fit, int noffset, const char *p); + +#ifndef USE_HOSTCC +static inline int fit_image_check_target_arch (const void *fdt, int node) +{ +#if defined(__ARM__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_ARM)) +#elif defined(__avr32__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_AVR32)) +#elif defined(__bfin__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_BLACKFIN)) +#elif defined(__I386__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_I386)) +#elif defined(__M68K__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_M68K)) +#elif defined(__microblaze__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_MICROBLAZE)) +#elif defined(__mips__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_MIPS)) +#elif defined(__nios__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS)) +#elif defined(__nios2__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS2)) +#elif defined(__PPC__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_PPC)) +#elif defined(__sh__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_SH)) +#else +# error Unknown CPU type +#endif + return 0; + + return 1; +} +#endif /* USE_HOSTCC */ + #ifdef CONFIG_FIT_VERBOSE #define fit_unsupported(msg) printf ("! %s:%d " \ "FIT images not supported for '%s'\n", \ @@ -436,6 +586,5 @@ inline int fit_parse_subimage (const char *spec, ulong addr_curr, #define fit_unsupported_reset(msg) #endif /* CONFIG_FIT_VERBOSE */ #endif /* CONFIG_FIT */ -#endif /* USE_HOSTCC */ #endif /* __IMAGE_H__ */ diff --git a/tools/mkimage.h b/tools/mkimage.h index cdd52bc..41cd156 100644 --- a/tools/mkimage.h +++ b/tools/mkimage.h @@ -35,6 +35,14 @@ #include #include "fdt_host.h" +#define MKIMAGE_DEBUG + +#ifdef MKIMAGE_DEBUG +#define debug(fmt,args...) printf (fmt ,##args) +#else +#define debug(fmt,args...) +#endif /* MKIMAGE_DEBUG */ + #if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__) #include #endif -- cgit v0.10.2 From eb6175edd6c120d8b89678243e5a2be362ee8e40 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Mon, 10 Mar 2008 17:53:49 +0100 Subject: [new uImage] Make node unit names const in struct bootm_headers Signed-off-by: Marian Balakowicz diff --git a/include/image.h b/include/image.h index 704a3b4..bbd481d 100644 --- a/include/image.h +++ b/include/image.h @@ -200,14 +200,14 @@ typedef struct bootm_headers { #if defined(CONFIG_FIT) void *fit_hdr_os; /* os FIT image header */ - char *fit_uname_os; /* os subimage node unit name */ + const char *fit_uname_os; /* os subimage node unit name */ void *fit_hdr_rd; /* init ramdisk FIT image header */ - char *fit_uname_rd; /* init ramdisk node unit name */ + const char *fit_uname_rd; /* init ramdisk node unit name */ #if defined(CONFIG_PPC) void *fit_hdr_fdt; /* FDT blob FIT image header */ - char *fit_uname_fdt; /* FDT blob node unit name */ + const char *fit_uname_fdt; /* FDT blob node unit name */ #endif int verify; /* getenv("verify")[0] != 'n' */ int autostart; /* getenv("autostart")[0] != 'n' */ -- cgit v0.10.2 From 9d25438fe7d70cf35a8a293ea5e392fefc672613 Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Tue, 11 Mar 2008 12:34:47 +0100 Subject: [new uImage] Add support for new uImage format to mkimage tool Support for the new uImage format (FIT) is added to mkimage tool. Commandline syntax is appropriately extended: mkimage [-D dtc_options] -f fit-image.its fit-image mkimage (together with dtc) takes fit-image.its and referenced therein binaries (like vmlinux.bin.gz) as inputs, and produces fit-image file -- the final image that can be transferred to the target (e.g., via tftp) and then booted using the bootm command in U-Boot. Signed-off-by: Bartlomiej Sieka diff --git a/include/image.h b/include/image.h index bbd481d..681c753 100644 --- a/include/image.h +++ b/include/image.h @@ -40,14 +40,21 @@ #include #include #include -#endif /* USE_HOSTCC */ -/* new uImage format support enabled by default */ +/* new uImage format support enabled on target + * To be moved to board configuration file */ #define CONFIG_FIT 1 #define CONFIG_OF_LIBFDT 1 +#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ + +#else -/* enable fit_format_error(), fit_format_warning() */ -#define CONFIG_FIT_VERBOSE 1 +/* new uImage format support enabled on host */ +#define CONFIG_FIT 1 +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ + +#endif /* USE_HOSTCC */ #if defined(CONFIG_FIT) && !defined(CONFIG_OF_LIBFDT) #error "CONFIG_OF_LIBFDT not enabled, required by CONFIG_FIT!" diff --git a/tools/mkimage.c b/tools/mkimage.c index 5cb2bc7..6e1ff2b 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -1,4 +1,6 @@ /* + * (C) Copyright 2008 Semihalf + * * (C) Copyright 2000-2004 * DENX Software Engineering * Wolfgang Denk, wd@denx.de @@ -32,6 +34,8 @@ extern int errno; extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len); static void copy_file (int, const char *, int); static void usage (void); +static void image_verify_header (char *, int); +static void fit_handle_file (void); char *datafile; char *imagefile; @@ -39,6 +43,7 @@ char *cmdname; int dflag = 0; int eflag = 0; +int fflag = 0; int lflag = 0; int vflag = 0; int xflag = 0; @@ -46,6 +51,7 @@ int opt_os = IH_OS_LINUX; int opt_arch = IH_ARCH_PPC; int opt_type = IH_TYPE_KERNEL; int opt_comp = IH_COMP_GZIP; +char *opt_dtc = MKIMAGE_DEFAULT_DTC_OPTIONS; image_header_t header; image_header_t *hdr = &header; @@ -53,7 +59,7 @@ image_header_t *hdr = &header; int main (int argc, char **argv) { - int ifd; + int ifd = -1; uint32_t checksum; uint32_t addr; uint32_t ep; @@ -81,6 +87,12 @@ main (int argc, char **argv) (opt_comp = genimg_get_comp_id (*++argv)) < 0) usage (); goto NXTARG; + case 'D': + if (--argc <= 0) + usage (); + opt_dtc = *++argv; + goto NXTARG; + case 'O': if ((--argc <= 0) || (opt_os = genimg_get_os_id (*++argv)) < 0) @@ -121,6 +133,12 @@ main (int argc, char **argv) } eflag = 1; goto NXTARG; + case 'f': + if (--argc <= 0) + usage (); + datafile = *++argv; + fflag = 1; + goto NXTARG; case 'n': if (--argc <= 0) usage (); @@ -139,7 +157,10 @@ main (int argc, char **argv) NXTARG: ; } - if ((argc != 1) || ((lflag ^ dflag) == 0)) + if ((argc != 1) || + (dflag && (fflag || lflag)) || + (fflag && (dflag || lflag)) || + (lflag && (dflag || fflag))) usage(); if (!eflag) { @@ -165,21 +186,22 @@ NXTARG: ; imagefile = *argv; - if (lflag) { - ifd = open(imagefile, O_RDONLY|O_BINARY); - } else { - ifd = open(imagefile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666); - } + if (!fflag){ + if (lflag) { + ifd = open (imagefile, O_RDONLY|O_BINARY); + } else { + ifd = open (imagefile, + O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666); + } - if (ifd < 0) { - fprintf (stderr, "%s: Can't open %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); + if (ifd < 0) { + fprintf (stderr, "%s: Can't open %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } } if (lflag) { - int len; - char *data; /* * list header information of existing image */ @@ -204,44 +226,24 @@ NXTARG: ; exit (EXIT_FAILURE); } - /* - * image_check_hcrc() creates copy of header so that - * we can blank out the checksum field for checking - - * this can't be done on the PROT_READ mapped data. - */ - hdr = (image_header_t *)ptr; - - if (!image_check_magic (hdr)) { - fprintf (stderr, - "%s: Bad Magic Number: \"%s\" is no valid image\n", - cmdname, imagefile); - exit (EXIT_FAILURE); - } - - if (!image_check_hcrc (hdr)) { - fprintf (stderr, - "%s: ERROR: \"%s\" has bad header checksum!\n", - cmdname, imagefile); - exit (EXIT_FAILURE); + if (fdt_check_header (ptr)) { + /* old-style image */ + image_verify_header ((char *)ptr, sbuf.st_size); + image_print_contents_noindent ((image_header_t *)ptr); + } else { + /* FIT image */ + fit_print_contents_noindent (ptr); } - data = (char *)image_get_data (hdr); - len = sbuf.st_size - image_get_header_size (); - - if (crc32(0, data, len) != image_get_dcrc (hdr)) { - fprintf (stderr, - "%s: ERROR: \"%s\" has corrupted data!\n", - cmdname, imagefile); - exit (EXIT_FAILURE); - } - - /* for multi-file images we need the data part, too */ - image_print_contents_noindent ((image_header_t *)ptr); - (void) munmap((void *)ptr, sbuf.st_size); (void) close (ifd); exit (EXIT_SUCCESS); + } else if (fflag) { + /* Flattened Image Tree (FIT) format handling */ + debug ("FIT format handling\n"); + fit_handle_file (); + exit (EXIT_SUCCESS); } /* @@ -467,11 +469,11 @@ void usage () { fprintf (stderr, "Usage: %s -l image\n" - " -l ==> list image header information\n" - " %s [-x] -A arch -O os -T type -C comp " - "-a addr -e ep -n name -d data_file[:data_file...] image\n", - cmdname, cmdname); - fprintf (stderr, " -A ==> set architecture to 'arch'\n" + " -l ==> list image header information\n", + cmdname); + fprintf (stderr, " %s [-x] -A arch -O os -T type -C comp " + "-a addr -e ep -n name -d data_file[:data_file...] image\n" + " -A ==> set architecture to 'arch'\n" " -O ==> set operating system to 'os'\n" " -T ==> set image type to 'type'\n" " -C ==> set compression type 'comp'\n" @@ -479,7 +481,158 @@ usage () " -e ==> set entry point to 'ep' (hex)\n" " -n ==> set image name to 'name'\n" " -d ==> use image data from 'datafile'\n" - " -x ==> set XIP (execute in place)\n" - ); + " -x ==> set XIP (execute in place)\n", + cmdname); + fprintf (stderr, " %s [-D dtc_options] -f fit-image.its fit-image\n", + cmdname); + exit (EXIT_FAILURE); } + +static void +image_verify_header (char *ptr, int image_size) +{ + int len; + char *data; + uint32_t checksum; + image_header_t header; + image_header_t *hdr = &header; + + /* + * create copy of header so that we can blank out the + * checksum field for checking - this can't be done + * on the PROT_READ mapped data. + */ + memcpy (hdr, ptr, sizeof(image_header_t)); + + if (ntohl(hdr->ih_magic) != IH_MAGIC) { + fprintf (stderr, + "%s: Bad Magic Number: \"%s\" is no valid image\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } + + data = (char *)hdr; + len = sizeof(image_header_t); + + checksum = ntohl(hdr->ih_hcrc); + hdr->ih_hcrc = htonl(0); /* clear for re-calculation */ + + if (crc32 (0, data, len) != checksum) { + fprintf (stderr, + "%s: ERROR: \"%s\" has bad header checksum!\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } + + data = ptr + sizeof(image_header_t); + len = image_size - sizeof(image_header_t) ; + + if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) { + fprintf (stderr, + "%s: ERROR: \"%s\" has corrupted data!\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } +} + +/** + * fit_handle_file - main FIT file processing function + * + * fit_handle_file() runs dtc to convert .its to .itb, includes + * binary data, updates timestamp property and calculates hashes. + * + * datafile - .its file + * imagefile - .itb file + * + * returns: + * only on success, otherwise calls exit (EXIT_FAILURE); + */ +static void fit_handle_file (void) +{ + char tmpfile[MKIMAGE_MAX_TMPFILE_LEN]; + char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN]; + int tfd; + struct stat sbuf; + unsigned char *ptr; + + /* call dtc to include binary properties into the tmp file */ + if (strlen (imagefile) + strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 > + sizeof (tmpfile)) { + fprintf (stderr, "%s: Image file name (%s) too long, " + "can't create tmpfile", + imagefile, cmdname); + exit (EXIT_FAILURE); + } + sprintf (tmpfile, "%s%s", imagefile, MKIMAGE_TMPFILE_SUFFIX); + + /* dtc -I dts -O -p 200 datafile > tmpfile */ + sprintf (cmd, "%s %s %s > %s", + MKIMAGE_DTC, opt_dtc, datafile, tmpfile); + debug ("Trying to execute \"%s\"\n", cmd); + if (system (cmd) == -1) { + fprintf (stderr, "%s: system(%s) failed: %s\n", + cmdname, cmd, strerror(errno)); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + + /* load FIT blob into memory */ + tfd = open (tmpfile, O_RDWR|O_BINARY); + + if (tfd < 0) { + fprintf (stderr, "%s: Can't open %s: %s\n", + cmdname, tmpfile, strerror(errno)); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + + if (fstat (tfd, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, tmpfile, strerror(errno)); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + + ptr = (unsigned char *)mmap (0, sbuf.st_size, + PROT_READ|PROT_WRITE, MAP_SHARED, tfd, 0); + if ((caddr_t)ptr == (caddr_t)-1) { + fprintf (stderr, "%s: Can't read %s: %s\n", + cmdname, tmpfile, strerror(errno)); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + + /* check if ptr has a valid blob */ + if (fdt_check_header (ptr)) { + fprintf (stderr, "%s: Invalid FIT blob\n", cmdname); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + + /* set hashes for images in the blob */ + if (fit_set_hashes (ptr)) { + fprintf (stderr, "%s Can't add hashes to FIT blob", cmdname); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + + /* add a timestamp at offset 0 i.e., root */ + if (fit_set_timestamp (ptr, 0, sbuf.st_mtime)) { + fprintf (stderr, "%s: Can't add image timestamp\n", cmdname); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + debug ("Added timestamp successfully\n"); + + munmap ((void *)ptr, sbuf.st_size); + close (tfd); + + if (rename (tmpfile, imagefile) == -1) { + fprintf (stderr, "%s: Can't rename %s to %s: %s\n", + cmdname, tmpfile, imagefile, strerror (errno)); + unlink (tmpfile); + unlink (imagefile); + exit (EXIT_FAILURE); + } +} diff --git a/tools/mkimage.h b/tools/mkimage.h index 41cd156..a2d5248 100644 --- a/tools/mkimage.h +++ b/tools/mkimage.h @@ -43,6 +43,12 @@ #define debug(fmt,args...) #endif /* MKIMAGE_DEBUG */ +#define MKIMAGE_TMPFILE_SUFFIX ".tmp" +#define MKIMAGE_MAX_TMPFILE_LEN 256 +#define MKIMAGE_DEFAULT_DTC_OPTIONS "-I dts -O dtb -p 500" +#define MKIMAGE_MAX_DTC_CMDLINE_LEN 512 +#define MKIMAGE_DTC "dtc" /* assume dtc is in $PATH */ + #if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__) #include #endif -- cgit v0.10.2 From e32fea6adb620ecf2bd70acf2dd37e53df9d1547 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 11 Mar 2008 12:35:20 +0100 Subject: [new uImage] Add new uImage format support for imls and iminfo commands imls and iminfo can now recognize nad print out contents of the new (FIT) format uImages. Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 10403aa..daee7bf 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -556,7 +556,13 @@ static int image_info (ulong addr) #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: puts (" FIT image found\n"); - fit_unsupported ("iminfo"); + + if (!fit_check_format (hdr)) { + puts ("Bad FIT image format!\n"); + return 1; + } + + fit_print_contents (hdr); return 0; #endif default: @@ -601,9 +607,6 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) switch (genimg_get_format (hdr)) { case IMAGE_FORMAT_LEGACY: - if (!image_check_magic (hdr)) - goto next_sector; - if (!image_check_hcrc (hdr)) goto next_sector; @@ -619,8 +622,11 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: + if (!fit_check_format (hdr)) + goto next_sector; + printf ("FIT Image at %08lX:\n", (ulong)hdr); - fit_unsupported ("imls"); + fit_print_contents (hdr); break; #endif default: -- cgit v0.10.2 From 6986a385671749ecb3f60cf99e9cbae8e47bb50e Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:01:05 +0100 Subject: [new uImage] Add new uImage format support for kernel booting New format uImages are recognized by the bootm command, validity of specified kernel component image is checked and its data section located and used for further processing (uncompress, load, etc.) Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index daee7bf..96d09e6 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -66,6 +66,11 @@ static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); static void fixup_silent_linux (void); #endif +static image_header_t *image_get_kernel (ulong img_addr, int verify); +#if defined(CONFIG_FIT) +static int fit_check_kernel (const void *fit, int os_noffset, int verify); +#endif + static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char *argv[], bootm_headers_t *images, ulong *os_data, ulong *os_len); extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); @@ -125,6 +130,9 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong image_start, image_end; ulong load_start, load_end; ulong mem_start, mem_size; +#if defined(CONFIG_FIT) + int os_noffset; +#endif struct lmb lmb; @@ -145,8 +153,10 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* get kernel image header, start address and length */ os_hdr = boot_get_kernel (cmdtp, flag, argc, argv, &images, &os_data, &os_len); - if (os_len == 0) + if (os_len == 0) { + puts ("ERROR: can't get kernel image!\n"); return 1; + } show_boot_progress (6); @@ -162,8 +172,37 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_unsupported ("bootm"); - return 1; + os_noffset = fit_image_get_node (images.fit_hdr_os, + images.fit_uname_os); + if (os_noffset < 0) { + printf ("Can't get image node for '%s'!\n", + images.fit_uname_os); + return 1; + } + + if (fit_image_get_type (images.fit_hdr_os, os_noffset, &type)) { + puts ("Can't get image type!\n"); + return 1; + } + + if (fit_image_get_comp (images.fit_hdr_os, os_noffset, &comp)) { + puts ("Can't get image compression!\n"); + return 1; + } + + if (fit_image_get_os (images.fit_hdr_os, os_noffset, &os)) { + puts ("Can't get image OS!\n"); + return 1; + } + + image_end = fit_get_end (images.fit_hdr_os); + + if (fit_image_get_load (images.fit_hdr_os, os_noffset, + &load_start)) { + puts ("Can't get image load address!\n"); + return 1; + } + break; #endif default: puts ("ERROR: unknown image format type!\n"); @@ -360,6 +399,47 @@ static image_header_t *image_get_kernel (ulong img_addr, int verify) } /** + * fit_check_kernel - verify FIT format kernel subimage + * @fit_hdr: pointer to the FIT image header + * os_noffset: kernel subimage node offset within FIT image + * @verify: data CRC verification flag + * + * fit_check_kernel() verifies integrity of the kernel subimage and from + * specified FIT image. + * + * returns: + * 1, on success + * 0, on failure + */ +#if defined (CONFIG_FIT) +static int fit_check_kernel (const void *fit, int os_noffset, int verify) +{ + fit_image_print (fit, os_noffset, " "); + + if (verify) { + puts (" Verifying Hash Integrity ... "); + if (!fit_image_check_hashes (fit, os_noffset)) { + puts ("Bad Data Hash\n"); + return 0; + } + puts ("OK\n"); + } + + if (!fit_image_check_target_arch (fit, os_noffset)) { + puts ("Unsupported Architecture\n"); + return 0; + } + + if (!fit_image_check_type (fit, os_noffset, IH_TYPE_KERNEL)) { + puts ("Not a kernel image\n"); + return 0; + } + + return 1; +} +#endif /* CONFIG_FIT */ + +/** * boot_get_kernel - find kernel image * @os_data: pointer to a ulong variable, will hold os data start address * @os_len: pointer to a ulong variable, will hold os data length @@ -380,6 +460,10 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] void *fit_hdr; const char *fit_uname_config = NULL; const char *fit_uname_kernel = NULL; + const void *data; + size_t len; + int conf_noffset; + int os_noffset; #endif /* find out kernel image address */ @@ -403,21 +487,22 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] } show_boot_progress (1); - printf ("## Booting kernel image at %08lx ...\n", img_addr); /* copy from dataflash if needed */ img_addr = genimg_get_image (img_addr); /* check image type, for FIT images get FIT kernel node */ + *os_data = *os_len = 0; switch (genimg_get_format ((void *)img_addr)) { case IMAGE_FORMAT_LEGACY: - - debug ("* kernel: legacy format image\n"); + printf ("## Booting kernel from Legacy Image at %08lx ...\n", + img_addr); hdr = image_get_kernel (img_addr, images->verify); if (!hdr) return NULL; show_boot_progress (5); + /* get os_data and os_len */ switch (image_get_type (hdr)) { case IH_TYPE_KERNEL: *os_data = image_get_data (hdr); @@ -438,17 +523,57 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: fit_hdr = (void *)img_addr; - debug ("* kernel: FIT format image\n"); - fit_unsupported ("kernel"); - return NULL; + printf ("## Booting kernel from FIT Image at %08lx ...\n", + img_addr); + + if (!fit_check_format (fit_hdr)) { + puts ("Bad FIT kernel image format!\n"); + return NULL; + } + + if (!fit_uname_kernel) { + /* + * no kernel image node unit name, try to get config + * node first. If config unit node name is NULL + * fit_conf_get_node() will try to find default config node + */ + conf_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); + if (conf_noffset < 0) + return NULL; + + os_noffset = fit_conf_get_kernel_node (fit_hdr, conf_noffset); + fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL); + } else { + /* get kernel component image node offset */ + os_noffset = fit_image_get_node (fit_hdr, fit_uname_kernel); + } + if (os_noffset < 0) + return NULL; + + printf (" Trying '%s' kernel subimage\n", fit_uname_kernel); + + if (!fit_check_kernel (fit_hdr, os_noffset, images->verify)) + return NULL; + + /* get kernel image data address and length */ + if (fit_image_get_data (fit_hdr, os_noffset, &data, &len)) { + puts ("Could not find kernel subimage data!\n"); + return NULL; + } + + *os_len = len; + *os_data = (ulong)data; + images->fit_hdr_os = fit_hdr; + images->fit_uname_os = fit_uname_kernel; + break; #endif default: printf ("Wrong Image Format for %s command\n", cmdtp->name); return NULL; } - debug (" kernel data at 0x%08lx, end = 0x%08lx\n", - *os_data, *os_data + *os_len); + debug (" kernel data at 0x%08lx, len = 0x%08lx (%d)\n", + *os_data, *os_len, *os_len); return (void *)img_addr; } @@ -466,6 +591,14 @@ U_BOOT_CMD( "\tuse a '-' for the second argument. If you do not pass a third\n" "\ta bd_info struct will be passed instead\n" #endif +#if defined(CONFIG_FIT) + "\t\nFor the new multi component uImage format (FIT) addresses\n" + "\tmust be extened to include component or configuration unit name:\n" + "\taddr: - direct component image specification\n" + "\taddr# - configuration specification\n" + "\tUse iminfo command to get the list of existing component\n" + "\timages and configurations.\n" +#endif ); /*******************************************************************/ -- cgit v0.10.2 From c87796483bc7c2900470dc747c367f602577608d Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:12:37 +0100 Subject: [new uImage] Add new uImage format support for ramdisk handling This patch updates boot_get_ramdisk() routine adding format verification and handling for new (FIT) uImages. Signed-off-by: Marian Balakowicz diff --git a/common/image.c b/common/image.c index 9278ea9..3b15853 100644 --- a/common/image.c +++ b/common/image.c @@ -47,11 +47,17 @@ #include -#if defined(CONFIG_FIT) +#if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT) #include #include #include +#endif + +#if defined(CONFIG_FIT) #include + +static int fit_check_ramdisk (const void *fit, int os_noffset, + uint8_t arch, int verify); #endif #ifdef CONFIG_CMD_BDI @@ -774,8 +780,15 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], const char *fit_uname_config = NULL; const char *fit_uname_ramdisk = NULL; ulong default_addr; + int rd_noffset; + int conf_noffset; + const void *data; + size_t size; #endif + *rd_start = 0; + *rd_end = 0; + /* * Look for a '-' which indicates to ignore the * ramdisk argument @@ -812,8 +825,6 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } /* copy from dataflash if needed */ - printf ("## Loading init Ramdisk Image at %08lx ...\n", - rd_addr); rd_addr = genimg_get_image (rd_addr); /* @@ -823,17 +834,14 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], */ switch (genimg_get_format ((void *)rd_addr)) { case IMAGE_FORMAT_LEGACY: - - debug ("* ramdisk: legacy format image\n"); + printf ("## Loading init Ramdisk from Legacy " + "Image at %08lx ...\n", rd_addr); rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv, rd_addr, arch, images->verify); - if (rd_hdr == NULL) { - *rd_start = 0; - *rd_end = 0; + if (rd_hdr == NULL) return 1; - } rd_data = image_get_data (rd_hdr); rd_len = image_get_data_size (rd_hdr); @@ -842,14 +850,60 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: fit_hdr = (void *)rd_addr; - debug ("* ramdisk: FIT format image\n"); - fit_unsupported_reset ("ramdisk"); - return 1; + printf ("## Loading init Ramdisk from FIT " + "Image at %08lx ...\n", rd_addr); + + if (!fit_check_format (fit_hdr)) { + puts ("Bad FIT ramdisk image format!\n"); + return 0; + } + + if (!fit_uname_ramdisk) { + /* + * no ramdisk image node unit name, try to get config + * node first. If config unit node name is NULL + * fit_conf_get_node() will try to find default config node + */ + conf_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); + if (conf_noffset < 0) + return 0; + + rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, conf_noffset); + fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL); + } else { + /* get ramdisk component image node offset */ + rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk); + } + if (rd_noffset < 0) + return 0; + + printf (" Trying '%s' ramdisk subimage\n", fit_uname_ramdisk); + + if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify)) + return 0; + + /* get ramdisk image data address and length */ + if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) { + puts ("Could not find ramdisk subimage data!\n"); + return 0; + } + + rd_data = (ulong)data; + rd_len = size; + + if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) { + puts ("Can't get ramdisk subimage load address!\n"); + return 0; + } + + images->fit_hdr_rd = fit_hdr; + images->fit_uname_rd = fit_uname_ramdisk; + break; #endif default: printf ("Wrong Image Format for %s command\n", cmdtp->name); - rd_data = rd_len = 0; + rd_data = rd_len = rd_load = 0; } #if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO) @@ -870,7 +924,7 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], */ show_boot_progress (13); printf ("## Loading init Ramdisk from multi component " - "Image at %08lx ...\n", + "Legacy Image at %08lx ...\n", (ulong)images->legacy_hdr_os); image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len); @@ -884,8 +938,6 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (!rd_data) { debug ("## No init Ramdisk\n"); - *rd_start = 0; - *rd_end = 0; } else { *rd_start = rd_data; *rd_end = rd_data + rd_len; @@ -2376,4 +2428,44 @@ void fit_conf_print (const void *fit, int noffset, const char *p) if (uname) printf ("%s FDT: %s\n", p, uname); } + +/** + * fit_check_ramdisk - verify FIT format ramdisk subimage + * @fit_hdr: pointer to the FIT ramdisk header + * @rd_noffset: ramdisk subimage node offset within FIT image + * @arch: requested ramdisk image architecture type + * @verify: data CRC verification flag + * + * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from + * specified FIT image. + * + * returns: + * 1, on success + * 0, on failure + */ +#ifndef USE_HOSTCC +static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify) +{ + fit_image_print (fit, rd_noffset, " "); + + if (verify) { + puts (" Verifying Hash Integrity ... "); + if (!fit_image_check_hashes (fit, rd_noffset)) { + puts ("Bad Data Hash\n"); + return 0; + } + puts ("OK\n"); + } + + if (!fit_image_check_os (fit, rd_noffset, IH_OS_LINUX) || + !fit_image_check_arch (fit, rd_noffset, arch) || + !fit_image_check_type (fit, rd_noffset, IH_TYPE_RAMDISK)) { + printf ("No Linux %s Ramdisk Image\n", + genimg_get_arch_name(arch)); + return 0; + } + + return 1; +} +#endif /* USE_HOSTCC */ #endif /* CONFIG_FIT */ -- cgit v0.10.2 From d985c8498c4e47095820da97aa722381d39172c5 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:14:38 +0100 Subject: [new uImage] Remove unnecessary arguments passed to ramdisk routines boot_get_ramdisk() and image_get_ramdisk() do not need all cmdtp, flag, argc and argv arguments. Simplify routines definition. Signed-off-by: Marian Balakowicz diff --git a/common/image.c b/common/image.c index 3b15853..6458fb1 100644 --- a/common/image.c +++ b/common/image.c @@ -66,9 +66,8 @@ extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); DECLARE_GLOBAL_DATA_PTR; -static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong rd_addr, uint8_t arch, int verify); +static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch, + int verify); #else #include "mkimage.h" #include @@ -379,10 +378,6 @@ inline void image_print_contents_noindent (image_header_t *hdr) #ifndef USE_HOSTCC /** * image_get_ramdisk - get and verify ramdisk image - * @cmdtp: command table pointer - * @flag: command flag - * @argc: command argument count - * @argv: command argument list * @rd_addr: ramdisk image start address * @arch: expected ramdisk architecture * @verify: checksum verification flag @@ -399,9 +394,8 @@ inline void image_print_contents_noindent (image_header_t *hdr) * pointer to a ramdisk image header, if image was found and valid * otherwise, return NULL */ -static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong rd_addr, uint8_t arch, int verify) +static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch, + int verify) { image_header_t *rd_hdr; @@ -748,8 +742,6 @@ ulong genimg_get_image (ulong img_addr) /** * boot_get_ramdisk - main ramdisk handling routine - * @cmdtp: command table pointer - * @flag: command flag * @argc: command argument count * @argv: command argument list * @images: pointer to the bootm images structure @@ -763,14 +755,15 @@ ulong genimg_get_image (ulong img_addr) * - commandline provided address of decicated ramdisk image. * * returns: + * 0, if ramdisk image was found and valid, or skiped * rd_start and rd_end are set to ramdisk start/end addresses if * ramdisk image is found and valid + * + * 1, if ramdisk image is found but corrupted * rd_start and rd_end are set to 0 if no ramdisk exists - * return 1 if ramdisk image is found but corrupted */ -int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, uint8_t arch, - ulong *rd_start, ulong *rd_end) +int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, + uint8_t arch, ulong *rd_start, ulong *rd_end) { ulong rd_addr, rd_load; ulong rd_data, rd_len; @@ -837,8 +830,8 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], printf ("## Loading init Ramdisk from Legacy " "Image at %08lx ...\n", rd_addr); - rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv, - rd_addr, arch, images->verify); + rd_hdr = image_get_ramdisk (rd_addr, arch, + images->verify); if (rd_hdr == NULL) return 1; @@ -901,8 +894,7 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], break; #endif default: - printf ("Wrong Image Format for %s command\n", - cmdtp->name); + puts ("Wrong Ramdisk Image Format\n"); rd_data = rd_len = rd_load = 0; } diff --git a/include/image.h b/include/image.h index 681c753..6fca6f4 100644 --- a/include/image.h +++ b/include/image.h @@ -250,9 +250,8 @@ int genimg_get_comp_id (const char *name); int genimg_get_format (void *img_addr); ulong genimg_get_image (ulong img_addr); -int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, uint8_t arch, - ulong *rd_start, ulong *rd_end); +int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, + uint8_t arch, ulong *rd_start, ulong *rd_end); #if defined(CONFIG_PPC) || defined(CONFIG_M68K) int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index 865e711..08eef0b 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -95,8 +95,10 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], printf ("Using machid 0x%x from environment\n", machid); } - boot_get_ramdisk (cmdtp, flag, argc, argv, images, - IH_ARCH_ARM, &initrd_start, &initrd_end); + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_ARM, + &initrd_start, &initrd_end); + if (ret) + do_reset (cmdtp, flag, argc, argv); show_boot_progress (15); diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index e8e537a..c9a0190 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -196,8 +196,10 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } theKernel = (void *)ep; - boot_get_ramdisk (cmdtp, flag, argc, argv, images, - IH_ARCH_AVR32, &initrd_start, &initrd_end); + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_AVR32, + &initrd_start, &initrd_end); + if (ret) + do_reset (cmdtp, flag, argc, argv); show_boot_progress (15); diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c index 76bcf6c..b4a52fa 100644 --- a/lib_i386/bootm.c +++ b/lib_i386/bootm.c @@ -39,9 +39,12 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong initrd_start, initrd_end; ulong ep; image_header_t *hdr; + int ret; - boot_get_ramdisk (cmdtp, flag, argc, argv, images, - IH_ARCH_I386, &initrd_start, &initrd_end); + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_I386, + &initrd_start, &initrd_end); + if (ret) + do_reset (cmdtp, flag, argc, argv); if (images->legacy_hdr_valid) { hdr = images->legacy_hdr_os; diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index fba7499..f185bea 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -111,9 +111,8 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - ret = boot_get_ramdisk (cmdtp, flag, argc, argv, images, - IH_ARCH_M68K, &rd_data_start, &rd_data_end); - + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_M68K, + &rd_data_start, &rd_data_end); if (ret) goto error; diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c index b336a36..5e7a460 100644 --- a/lib_mips/bootm.c +++ b/lib_mips/bootm.c @@ -53,6 +53,7 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], void (*theKernel) (int, char **, char **, int *); char *commandline = getenv ("bootargs"); char env_buf[12]; + int ret; /* find kernel entry point */ if (images->legacy_hdr_valid) { @@ -68,8 +69,10 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], } theKernel = (void (*)(int, char **, char **, int *))ep; - boot_get_ramdisk (cmdtp, flag, argc, argv, images, - IH_ARCH_MIPS, &initrd_start, &initrd_end); + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_MIPS, + &initrd_start, &initrd_end); + if (ret) + do_reset (cmdtp, flag, argc, argv); show_boot_progress (15); diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 7977157..ac06b26 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -160,9 +160,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; /* find ramdisk */ - ret = boot_get_ramdisk (cmdtp, flag, argc, argv, images, - IH_ARCH_PPC, &rd_data_start, &rd_data_end); - + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_PPC, + &rd_data_start, &rd_data_end); if (ret) goto error; -- cgit v0.10.2 From a44a269a905f924b420020506a4d7d7eedcc0eaf Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:14:57 +0100 Subject: [new uImage] Re-enable interrupts for non automatic booting Re-enable interrupts if we return from do_bootm_ and 'autostart' environment variable is not set to 'yes'. Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 96d09e6..aca54b5 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -342,8 +342,12 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress (-9); #ifdef DEBUG puts ("\n## Control returned to monitor - resetting...\n"); - do_reset (cmdtp, flag, argc, argv); + if (images.autostart) + do_reset (cmdtp, flag, argc, argv); #endif + if (!images.autostart && iflag) + enable_interrupts(); + return 1; } -- cgit v0.10.2 From bc8ed486b125452ba3bd8344f052f437329150c5 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:32:53 +0100 Subject: [new uImage] ppc: Add new uImage format support to FDT handling routines Support for new (FIT) format uImages is added to powerpc specific boot_get_fdt() routine which now recognizes, sanity checks FIT image and is able to access data sections of the requested component image. Signed-off-by: Marian Balakowicz diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index ac06b26..60bc04b 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -254,20 +254,24 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * r6: NULL * r7: NULL */ + debug (" Booting using OF flat tree...\n"); (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); /* does not return */ - } + } else #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 */ + { + /* + * 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 + */ + debug (" Booting using board info...\n"); + (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); + /* does not return */ + } return ; error: @@ -353,6 +357,47 @@ static image_header_t *image_get_fdt (ulong fdt_addr) return fdt_hdr; } +/** + * fit_check_fdt - verify FIT format FDT subimage + * @fit_hdr: pointer to the FIT header + * fdt_noffset: FDT subimage node offset within FIT image + * @verify: data CRC verification flag + * + * fit_check_fdt() verifies integrity of the FDT subimage and from + * specified FIT image. + * + * returns: + * 1, on success + * 0, on failure + */ +#if defined(CONFIG_FIT) +static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) +{ + fit_image_print (fit, fdt_noffset, " "); + + if (verify) { + puts (" Verifying Hash Integrity ... "); + if (!fit_image_check_hashes (fit, fdt_noffset)) { + fdt_error ("Bad Data Hash"); + return 0; + } + puts ("OK\n"); + } + + if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) { + fdt_error ("Not a FDT image"); + return 0; + } + + if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) { + fdt_error ("FDT image is compressed"); + return 0; + } + + return 1; +} +#endif /* CONFIG_FIT */ + static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size) { @@ -366,8 +411,15 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], const char *fit_uname_config = NULL; const char *fit_uname_fdt = NULL; ulong default_addr; + int conf_noffset; + int fdt_noffset; + const void *data; + size_t size; #endif + *of_flat_tree = NULL; + *of_size = 0; + if (argc > 3) { #if defined(CONFIG_FIT) /* @@ -398,7 +450,7 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_addr); } - debug ("## Checking for 'FDT'/'FDT image' at %08lx\n", + debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n", fdt_addr); /* copy from dataflash if needed */ @@ -411,10 +463,8 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], */ switch (genimg_get_format ((void *)fdt_addr)) { case IMAGE_FORMAT_LEGACY: - debug ("* fdt: legacy format image\n"); - /* verify fdt_addr points to a valid image header */ - printf ("## Flattened Device Tree Legacy Image at %08lx\n", + printf ("## Flattened Device Tree from Legacy Image at %08lx\n", fdt_addr); fdt_hdr = image_get_fdt (fdt_addr); if (!fdt_hdr) @@ -434,11 +484,15 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_error ("fdt overwritten"); goto error; } - memmove ((void *)image_get_load (fdt_hdr), + + debug (" Loading FDT from 0x%08lx to 0x%08lx\n", + image_get_data (fdt_hdr), load_start); + + memmove ((void *)load_start, (void *)image_get_data (fdt_hdr), image_get_data_size (fdt_hdr)); - fdt_blob = (char *)image_get_load (fdt_hdr); + fdt_blob = (char *)load_start; break; case IMAGE_FORMAT_FIT: /* @@ -448,14 +502,90 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], */ #if defined(CONFIG_FIT) /* check FDT blob vs FIT blob */ - if (0) { /* FIXME: call FIT format verification */ + if (fit_check_format ((const void *)fdt_addr)) { /* * FIT image */ fit_hdr = (void *)fdt_addr; - debug ("* fdt: FIT format image\n"); - fit_unsupported_reset ("PPC fdt"); - goto error; + printf ("## Flattened Device Tree from FIT Image at %08lx\n", + fdt_addr); + + if (!fit_uname_fdt) { + /* + * no FDT blob image node unit name, + * try to get config node first. If + * config unit node name is NULL + * fit_conf_get_node() will try to + * find default config node + */ + conf_noffset = fit_conf_get_node (fit_hdr, + fit_uname_config); + if (conf_noffset < 0) + goto error; + + fdt_noffset = fit_conf_get_fdt_node (fit_hdr, + conf_noffset); + fit_uname_fdt = fit_get_name (fit_hdr, + fdt_noffset, NULL); + } else { + /* get FDT component image node offset */ + fdt_noffset = fit_image_get_node (fit_hdr, + fit_uname_fdt); + } + if (fdt_noffset < 0) + goto error; + + printf (" Trying '%s' FDT blob subimage\n", + fit_uname_fdt); + + if (!fit_check_fdt (fit_hdr, fdt_noffset, + images->verify)) + goto error; + + /* get ramdisk image data address and length */ + if (fit_image_get_data (fit_hdr, fdt_noffset, + &data, &size)) { + fdt_error ("Could not find FDT subimage data"); + goto error; + } + + /* verift that image data is a proper FDT blob */ + if (fdt_check_header ((char *)data) != 0) { + fdt_error ("Subimage data is not a FTD"); + goto error; + } + + /* + * move image data to the load address, + * make sure we don't overwrite initial image + */ + image_start = (ulong)fit_hdr; + image_end = fit_get_end (fit_hdr); + + if (fit_image_get_load (fit_hdr, fdt_noffset, + &load_start) == 0) { + load_end = load_start + size; + + if ((load_start < image_end) && + (load_end > image_start)) { + fdt_error ("FDT overwritten"); + goto error; + } + + printf (" Loading FDT from 0x%08lx to 0x%08lx\n", + (ulong)data, load_start); + + memmove ((void *)load_start, + (void *)data, size); + + fdt_blob = (char *)load_start; + } else { + fdt_blob = (char *)data; + } + + images->fit_hdr_fdt = fit_hdr; + images->fit_uname_fdt = fit_uname_fdt; + break; } else #endif { @@ -509,8 +639,6 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } } else { debug ("## No Flattened Device Tree\n"); - *of_flat_tree = NULL; - *of_size = 0; return 0; } -- cgit v0.10.2 From 3dfe110149311425919e6d6a14b561b4207498f1 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:32:59 +0100 Subject: [new uImage] Add node offsets for FIT images listed in struct bootm_headers This patch adds new node offset fields to struct bootm_headers and updates bootm_headers processing code to make use of them. Saved node offsets allow to avoid repeating fit_image_get_node() calls. Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index aca54b5..11c476e 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -130,9 +130,6 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong image_start, image_end; ulong load_start, load_end; ulong mem_start, mem_size; -#if defined(CONFIG_FIT) - int os_noffset; -#endif struct lmb lmb; @@ -172,32 +169,27 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - os_noffset = fit_image_get_node (images.fit_hdr_os, - images.fit_uname_os); - if (os_noffset < 0) { - printf ("Can't get image node for '%s'!\n", - images.fit_uname_os); - return 1; - } - - if (fit_image_get_type (images.fit_hdr_os, os_noffset, &type)) { + if (fit_image_get_type (images.fit_hdr_os, + images.fit_noffset_os, &type)) { puts ("Can't get image type!\n"); return 1; } - if (fit_image_get_comp (images.fit_hdr_os, os_noffset, &comp)) { + if (fit_image_get_comp (images.fit_hdr_os, + images.fit_noffset_os, &comp)) { puts ("Can't get image compression!\n"); return 1; } - if (fit_image_get_os (images.fit_hdr_os, os_noffset, &os)) { + if (fit_image_get_os (images.fit_hdr_os, + images.fit_noffset_os, &os)) { puts ("Can't get image OS!\n"); return 1; } image_end = fit_get_end (images.fit_hdr_os); - if (fit_image_get_load (images.fit_hdr_os, os_noffset, + if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os, &load_start)) { puts ("Can't get image load address!\n"); return 1; @@ -569,6 +561,7 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] *os_data = (ulong)data; images->fit_hdr_os = fit_hdr; images->fit_uname_os = fit_uname_kernel; + images->fit_noffset_os = os_noffset; break; #endif default: diff --git a/common/image.c b/common/image.c index 6458fb1..e838f65 100644 --- a/common/image.c +++ b/common/image.c @@ -891,6 +891,7 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, images->fit_hdr_rd = fit_hdr; images->fit_uname_rd = fit_uname_ramdisk; + images->fit_noffset_rd = rd_noffset; break; #endif default: diff --git a/include/image.h b/include/image.h index 6fca6f4..51c0c89 100644 --- a/include/image.h +++ b/include/image.h @@ -208,13 +208,16 @@ typedef struct bootm_headers { #if defined(CONFIG_FIT) void *fit_hdr_os; /* os FIT image header */ const char *fit_uname_os; /* os subimage node unit name */ + int fit_noffset_os; /* os subimage node offset */ void *fit_hdr_rd; /* init ramdisk FIT image header */ - const char *fit_uname_rd; /* init ramdisk node unit name */ + const char *fit_uname_rd; /* init ramdisk subimage node unit name */ + int fit_noffset_rd; /* init ramdisk subimage node offset */ #if defined(CONFIG_PPC) void *fit_hdr_fdt; /* FDT blob FIT image header */ - const char *fit_uname_fdt; /* FDT blob node unit name */ + const char *fit_uname_fdt; /* FDT blob subimage node unit name */ + int fit_noffset_fdt;/* FDT blob subimage node offset */ #endif int verify; /* getenv("verify")[0] != 'n' */ int autostart; /* getenv("autostart")[0] != 'n' */ diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 60bc04b..4d8ef35 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -585,6 +585,7 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], images->fit_hdr_fdt = fit_hdr; images->fit_uname_fdt = fit_uname_fdt; + images->fit_noffset_fdt = fdt_noffset; break; } else #endif -- cgit v0.10.2 From cd7c596e9f561dbbc17b717277438aee78cde14f Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:33:00 +0100 Subject: [new uImage] Add new uImage format support to arch specific do_bootm_linux() routines This patch updates architecture specific implementations of do_bootm_linux() adding new uImage format handling for operations like get kernel entry point address, get kernel image data start address. Signed-off-by: Marian Balakowicz diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index 08eef0b..c5e8cb3 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -70,6 +70,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], char *s; int machid = bd->bi_arch_number; void (*theKernel)(int zero, int arch, uint params); + int ret; #ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); @@ -80,12 +81,16 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ep = image_get_ep (images->legacy_hdr_os); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { - fit_unsupported_reset ("ARM linux bootm"); - do_reset (cmdtp, flag, argc, argv); + ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } #endif } else { puts ("Could not find kernel entry point!\n"); - do_reset (cmdtp, flag, argc, argv); + goto error; } theKernel = (void (*)(int, int, uint))ep; @@ -98,7 +103,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_ARM, &initrd_start, &initrd_end); if (ret) - do_reset (cmdtp, flag, argc, argv); + goto error; show_boot_progress (15); @@ -151,6 +156,13 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], cleanup_before_linux (); theKernel (0, machid, bd->bi_boot_params); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index c9a0190..b1c651a 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -181,25 +181,30 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], void (*theKernel)(int magic, void *tagtable); struct tag *params, *params_start; char *commandline = getenv("bootargs"); + int ret; /* find kernel entry point */ if (images->legacy_hdr_valid) { ep = image_get_ep (images->legacy_hdr_os); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { - fit_unsupported_reset ("AVR32 linux bootm"); - do_reset (cmdtp, flag, argc, argv); + ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } #endif } else { puts ("Could not find kernel entry point!\n"); - do_reset (cmdtp, flag, argc, argv); + goto error; } theKernel = (void *)ep; ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_AVR32, &initrd_start, &initrd_end); if (ret) - do_reset (cmdtp, flag, argc, argv); + goto error; show_boot_progress (15); @@ -225,4 +230,11 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], prepare_to_boot(); theKernel(ATAG_MAGIC, params_start); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } diff --git a/lib_blackfin/bootm.c b/lib_blackfin/bootm.c index 33979a9..1ea80f4 100644 --- a/lib_blackfin/bootm.c +++ b/lib_blackfin/bootm.c @@ -65,12 +65,16 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], ep = image_get_ep (images->legacy_hdr_os); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { - fit_unsupported_reset ("AVR32 linux bootm"); - do_reset (cmdtp, flag, argc, argv); + int ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } #endif } else { puts ("Could not find kernel entry point!\n"); - do_reset (cmdtp, flag, argc, argv); + goto error; } appl = (int (*)(char *))ep; @@ -85,6 +89,13 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], dcache_disable(); } (*appl) (cmdline); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } char *make_command_line(void) diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c index b4a52fa..107ebaa 100644 --- a/lib_i386/bootm.c +++ b/lib_i386/bootm.c @@ -40,11 +40,15 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong ep; image_header_t *hdr; int ret; +#if defined(CONFIG_FIT) + const void *data; + size_t len; +#endif ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_I386, &initrd_start, &initrd_end); if (ret) - do_reset (cmdtp, flag, argc, argv); + goto error; if (images->legacy_hdr_valid) { hdr = images->legacy_hdr_os; @@ -58,12 +62,18 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], } #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { - fit_unsupported_reset ("I386 linux bootm"); - do_reset (cmdtp, flag, argc, argv); + ret = fit_image_get_data (images->fit_hdr_os, + images->fit_noffset_os, &data, &len); + if (ret) { + puts ("Can't get image data/size!\n"); + goto error; + } + os_data = (ulong)data; + os_len = (ulong)len; #endif } else { puts ("Could not find kernel image!\n"); - do_reset (cmdtp, flag, argc, argv); + goto error; } base_ptr = load_zimage ((void*)os_data, os_len, @@ -71,7 +81,7 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (NULL == base_ptr) { printf ("## Kernel loading failed ...\n"); - do_reset(cmdtp, flag, argc, argv); + goto error; } @@ -87,5 +97,11 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], printf("\nStarting kernel ...\n\n"); boot_zimage(base_ptr); + /* does not return */ + return; +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index f185bea..6f49c31 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -35,8 +35,6 @@ DECLARE_GLOBAL_DATA_PTR; -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - #define PHYSADDR(x) x #define LINUX_MAX_ENVS 256 @@ -101,12 +99,16 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, ep = image_get_ep (images->legacy_hdr_os); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { - fit_unsupported_reset ("M68K linux bootm"); - do_reset (cmdtp, flag, argc, argv); + ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } #endif } else { puts ("Could not find kernel entry point!\n"); - do_reset (cmdtp, flag, argc, argv); + goto error; } kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; diff --git a/lib_microblaze/bootm.c b/lib_microblaze/bootm.c index 99c4533..fab4a54 100644 --- a/lib_microblaze/bootm.c +++ b/lib_microblaze/bootm.c @@ -47,12 +47,16 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], ep = image_get_ep (images->legacy_hdr_os); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { - fit_unsupported_reset ("MICROBLAZE linux bootm"); - do_reset (cmdtp, flag, argc, argv); + int ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } #endif } else { puts ("Could not find kernel entry point!\n"); - do_reset (cmdtp, flag, argc, argv); + goto error; } theKernel = (void (*)(char *))ep; @@ -67,4 +71,11 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], return ; theKernel (commandline); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c index 5e7a460..e4c139e 100644 --- a/lib_mips/bootm.c +++ b/lib_mips/bootm.c @@ -60,19 +60,23 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], ep = image_get_ep (images->legacy_hdr_os); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { - fit_unsupported_reset ("MIPS linux bootm"); - do_reset (cmdtp, flag, argc, argv); + ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } #endif } else { puts ("Could not find kernel entry point!\n"); - do_reset (cmdtp, flag, argc, argv); + goto error; } theKernel = (void (*)(int, char **, char **, int *))ep; ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_MIPS, &initrd_start, &initrd_end); if (ret) - do_reset (cmdtp, flag, argc, argv); + goto error; show_boot_progress (15); @@ -116,6 +120,13 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], printf ("\nStarting kernel ...\n\n"); theKernel (linux_argc, linux_argv, linux_env, 0); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } static void linux_params_init (ulong start, char *line) diff --git a/lib_nios2/bootm.c b/lib_nios2/bootm.c index 4b940cb..0c89e96 100644 --- a/lib_nios2/bootm.c +++ b/lib_nios2/bootm.c @@ -37,12 +37,16 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ep = image_get_ep (images->legacy_hdr_os); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { - fit_unsupported_reset ("NIOS2 linux bootm"); - do_reset (cmdtp, flag, argc, argv); + int ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } #endif } else { puts ("Could not find kernel entry point!\n"); - do_reset (cmdtp, flag, argc, argv); + goto error; } void (*kernel)(void) = (void (*)(void))ep; @@ -53,4 +57,11 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * needs to be called ;-) */ kernel (); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 4d8ef35..86e104c 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -150,8 +150,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ep = image_get_ep (images->legacy_hdr_os); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { - fit_unsupported_reset ("PPC linux bootm"); - goto error; + ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } #endif } else { puts ("Could not find kernel entry point!\n"); diff --git a/lib_sh/bootm.c b/lib_sh/bootm.c index 8055841..49462c8 100644 --- a/lib_sh/bootm.c +++ b/lib_sh/bootm.c @@ -70,12 +70,16 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ep = image_get_ep (images->legacy_hdr_os); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { - fit_unsupported_reset ("SH linux bootm"); - do_reset (cmdtp, flag, argc, argv); + int ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } #endif } else { puts ("Could not find kernel entry point!\n"); - do_reset (cmdtp, flag, argc, argv); + goto error; } void (*kernel) (void) = (void (*)(void))ep; @@ -87,4 +91,11 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], strcpy(COMMAND_LINE, bootargs); kernel(); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } -- cgit v0.10.2 From 424c4abdd175d2c470510df8ce0e32d3f463ec16 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:33:00 +0100 Subject: [new uImage] Add new uImage format support to autoscript routine autoscript() routine is updated to accept second argument, which is only used for FIT images and provides a FIT subimage unit name. autoscript() routine callers must now pass two arguments. For non-interactive use (like in cmd_load.c, cmd_net.c), new environment variable 'autoscript_uname' is introduced and used as a FIT subimage unit name source. autoscript command accepts extended syntax of the addr argument: addr: Signed-off-by: Marian Balakowicz diff --git a/board/pn62/cmd_pn62.c b/board/pn62/cmd_pn62.c index ffa20cd..3f53e4b 100644 --- a/board/pn62/cmd_pn62.c +++ b/board/pn62/cmd_pn62.c @@ -157,8 +157,15 @@ int do_loadpci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *s; if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) { - printf("Running autoscript at addr 0x%08lX ...\n", load_addr); - rcode = autoscript (bd, load_addr); + printf ("Running autoscript at addr 0x%08lX", load_addr); + + s = getenv ("autoscript_uname"); + if (s) + printf (":%s ...\n", s); + else + puts (" ...\n"); + + rcode = autoscript (load_addr, s); } } #endif diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c index 60ffc7d..5163d57 100644 --- a/common/cmd_autoscript.c +++ b/common/cmd_autoscript.c @@ -50,14 +50,20 @@ #if defined(CONFIG_AUTOSCRIPT) || defined(CONFIG_CMD_AUTOSCRIPT) int -autoscript (ulong addr) +autoscript (ulong addr, const char *fit_uname) { - ulong len; - image_header_t *hdr; - ulong *data; - char *cmd; - int rcode = 0; - int verify; + ulong len; + image_header_t *hdr; + ulong *data; + char *cmd; + int rcode = 0; + int verify; +#if defined(CONFIG_FIT) + const void* fit_hdr; + int noffset; + const void *fit_data; + size_t fit_len; +#endif verify = getenv_verify (); @@ -97,8 +103,46 @@ autoscript (ulong addr) break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_unsupported ("autoscript"); - return 1; + if (fit_uname == NULL) { + puts ("No FIT subimage unit name\n"); + return 1; + } + + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("Bad FIT image format\n"); + return 1; + } + + /* get script component image node offset */ + noffset = fit_image_get_node (fit_hdr, fit_uname); + if (noffset < 0) { + printf ("Can't find '%s' FIT subimage\n", fit_uname); + return 1; + } + + if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) { + puts ("Not a image image\n"); + return 1; + } + + /* verify integrity */ + if (verify) { + if (!fit_image_check_hashes (fit_hdr, noffset)) { + puts ("Bad Data Hash\n"); + return 1; + } + } + + /* get script subimage data address and length */ + if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) { + puts ("Could not find script subimage data\n"); + return 1; + } + + data = (ulong *)fit_data; + len = (ulong)fit_len; + break; #endif default: puts ("Wrong image format for autoscript\n"); @@ -160,25 +204,35 @@ do_autoscript (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong addr; int rcode; + const char *fit_uname = NULL; + /* Find script image */ if (argc < 2) { addr = CFG_LOAD_ADDR; + debug ("* autoscr: default load address = 0x%08lx\n", addr); +#if defined(CONFIG_FIT) + } else if (fit_parse_subimage (argv[1], load_addr, &addr, &fit_uname)) { + debug ("* autoscr: subimage '%s' from FIT image at 0x%08lx\n", + fit_uname, addr); +#endif } else { - addr = simple_strtoul (argv[1],0,16); + addr = simple_strtoul(argv[1], NULL, 16); + debug ("* autoscr: cmdline image address = 0x%08lx\n", addr); } - printf ("## Executing script at %08lx\n",addr); - rcode = autoscript (addr); + printf ("## Executing script at %08lx\n", addr); + rcode = autoscript (addr, fit_uname); return rcode; } -#if defined(CONFIG_CMD_AUTOSCRIPT) U_BOOT_CMD( autoscr, 2, 0, do_autoscript, "autoscr - run script from memory\n", "[addr] - run script starting at addr" " - A valid autoscr header must be present\n" -); +#if defined(CONFIG_FIT) + "For FIT format uImage addr must include subimage\n" + "unit name in the form of addr:\n" #endif - +); #endif diff --git a/common/cmd_load.c b/common/cmd_load.c index 204c3eb..1b75a7b 100644 --- a/common/cmd_load.c +++ b/common/cmd_load.c @@ -521,8 +521,15 @@ int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *s; if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) { - printf("Running autoscript at addr 0x%08lX ...\n", load_addr); - rcode = autoscript (load_addr); + printf ("Running autoscript at addr 0x%08lX", load_addr); + + s = getenv ("autoscript_uname"); + if (s) + printf (":%s ...\n", s); + else + puts (" ...\n"); + + rcode = autoscript (load_addr, s); } } #endif diff --git a/common/cmd_net.c b/common/cmd_net.c index dbf6b86..79e910c 100644 --- a/common/cmd_net.c +++ b/common/cmd_net.c @@ -220,9 +220,16 @@ netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[]) #ifdef CONFIG_AUTOSCRIPT if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) { - printf("Running autoscript at addr 0x%08lX ...\n", load_addr); + printf ("Running autoscript at addr 0x%08lX", load_addr); + + s = getenv ("autoscript_uname"); + if (s) + printf (":%s ...\n", s); + else + puts (" ...\n"); + show_boot_progress (83); - rcode = autoscript (load_addr); + rcode = autoscript (load_addr, s); } #endif if (rcode < 0) diff --git a/include/common.h b/include/common.h index 3f05b5e..3351e2c 100644 --- a/include/common.h +++ b/include/common.h @@ -222,7 +222,7 @@ int mac_read_from_eeprom(void); void flash_perror (int); /* common/cmd_autoscript.c */ -int autoscript (ulong addr); +int autoscript (ulong addr, const char *fit_uname); extern ulong load_addr; /* Default Load Address */ -- cgit v0.10.2 From 1b7897f28d49a80d78d760ec6f6f11dc0f914338 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:33:00 +0100 Subject: [new uImage] Add new uImage format support to imgextract command Signed-off-by: Marian Balakowicz diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index 360b05e..77f68c4 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -37,12 +37,21 @@ int do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - ulong addr = load_addr, dest = 0; - ulong data, len; - ulong *len_ptr; - int i, verify, part = 0; - char pbuf[10], *s; - image_header_t *hdr; + ulong addr = load_addr; + ulong dest = 0; + ulong data, len, count; + int i, verify; + int part = 0; + char pbuf[10]; + char *s; + image_header_t *hdr; +#if defined(CONFIG_FIT) + const char *uname; + const void* fit_hdr; + int noffset; + const void *fit_data; + size_t fit_len; +#endif verify = getenv_verify (); @@ -51,16 +60,20 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } if (argc > 2) { part = simple_strtoul(argv[2], NULL, 16); +#if defined(CONFIG_FIT) + uname = argv[2]; +#endif } if (argc > 3) { dest = simple_strtoul(argv[3], NULL, 16); } - switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: - printf("## Copying from legacy image at %08lx ...\n", addr); + printf("## Copying part %d from legacy image " + "at %08lx ...\n", part, addr); + hdr = (image_header_t *)addr; if (!image_check_magic (hdr)) { printf("Bad Magic Number\n"); @@ -71,9 +84,9 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) printf("Bad Header Checksum\n"); return 1; } - #ifdef DEBUG +#ifdef DEBUG image_print_contents (hdr); - #endif +#endif if (!image_check_type (hdr, IH_TYPE_MULTI)) { printf("Wrong Image Type for %s command\n", @@ -96,31 +109,60 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) printf("OK\n"); } - data = image_get_data (hdr); - len_ptr = (ulong *) data; - - data += 4; /* terminator */ - for (i = 0; len_ptr[i]; ++i) { - data += 4; - if (argc > 2 && part > i) { - u_long tail; - len = uimage_to_cpu (len_ptr[i]); - tail = len % 4; - data += len; - if (tail) { - data += 4 - tail; - } - } - } - if (argc > 2 && part >= i) { + count = image_multi_count (hdr); + if (part >= count) { printf("Bad Image Part\n"); return 1; } - len = uimage_to_cpu (len_ptr[part]); + + image_multi_getimg (hdr, part, &data, &len); + break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_unsupported ("imxtract"); - return 1; + if (uname == NULL) { + puts ("No FIT subimage unit name\n"); + return 1; + } + + printf("## Copying '%s' subimage from FIT image " + "at %08lx ...\n", uname, addr); + + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("Bad FIT image format\n"); + return 1; + } + + /* get subimage node offset */ + noffset = fit_image_get_node (fit_hdr, fit_uname); + if (noffset < 0) { + printf ("Can't find '%s' FIT subimage\n", uname); + return 1; + } + + if (fit_image_check_comp (fit_hdr, noffset, IH_COMP_NONE)) { + printf("Wrong Compression Type for %s command\n", + cmdtp->name); + return 1; + } + + /* verify integrity */ + if (verify) { + if (!fit_image_check_hashes (fit_hdr, noffset)) { + puts ("Bad Data Hash\n"); + return 1; + } + } + + /* get subimage data address and length */ + if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) { + puts ("Could not find script subimage data\n"); + return 1; + } + + data = (ulong *)fit_data; + len = (ulong)fit_len; + break; #endif default: puts ("Invalid image type for imxtract\n"); @@ -142,6 +184,11 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD(imxtract, 4, 1, do_imgextract, "imxtract- extract a part of a multi-image\n", "addr part [dest]\n" - " - extract from image at and copy to \n"); + " - extract from legacy image at and copy to \n" +#if defined(CONFIG_FIT) + "addr uname [dest]\n" + " - extract subimage from FIT image at and copy to \n" +#endif +); #endif -- cgit v0.10.2 From 09475f7527460e426c0e0628fc5b8f3754fbaa23 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:33:01 +0100 Subject: [new uImage] Add new uImage format handling to other bootm related commands Updated commands: docboot - cmd_doc.c fdcboot - cmd_fdc.c diskboot - cmd_ide.c nboot - cmd_nand.c scsiboot - cmd_scsi.c usbboot - cmd_usb.c Signed-off-by: Marian Balakowicz diff --git a/common/cmd_doc.c b/common/cmd_doc.c index 293b1aa..bf2f0a9 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -205,6 +205,9 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong offset = 0; image_header_t *hdr; int rcode = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif show_boot_progress (34); switch (argc) { @@ -265,29 +268,30 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; - if (image_check_magic (hdr)) { + image_print_contents (hdr); - image_print_contents (hdr); - - cnt = image_get_image_size (hdr); - cnt -= SECTORSIZE; - } else { - puts ("\n** Bad Magic Number **\n"); - show_boot_progress (-39); - return 1; - } + cnt = image_get_image_size (hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_unsupported ("docboot"); - return 1; + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("** Bad FIT image format\n"); + return 1; + } + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; #endif default: + show_boot_progress (-39); puts ("** Unknown image type\n"); return 1; } show_boot_progress (39); + cnt -= SECTORSIZE; if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt, NULL, (u_char *)(addr+SECTORSIZE))) { printf ("** Read error on %d\n", dev); @@ -296,6 +300,12 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (40); +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ load_addr = addr; diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index 80301b9..bf28370 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -788,6 +788,9 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int i,nrofblk; char *ep; int rcode = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif switch (argc) { case 1: @@ -839,18 +842,21 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf ("Bad Magic Number\n"); - return 1; - } image_print_contents (hdr); imsize = image_get_image_size (hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_unsupported ("fdcboot"); - return 1; + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("** Bad FIT image format\n"); + return 1; + } + puts ("Fit image detected...\n"); + + imsize = fit_get_size (fit_hdr); + break; #endif default: puts ("** Unknown image type\n"); @@ -872,9 +878,16 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf("OK %ld Bytes loaded.\n",imsize); flush_cache (addr, imsize); - /* Loading ok, update default load address */ +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + + /* Loading ok, update default load address */ load_addr = addr; + /* Check if we should attempt an auto-start */ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { char *local_args[2]; diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 79b7dfb..6a67dd6 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -370,6 +370,9 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) disk_partition_t info; image_header_t *hdr; int rcode = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif show_boot_progress (41); switch (argc) { @@ -450,11 +453,6 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf("\n** Bad Magic Number **\n"); - show_boot_progress (-49); - return 1; - } show_boot_progress (49); if (!image_check_hcrc (hdr)) { @@ -470,10 +468,18 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_unsupported ("diskboot"); - return 1; + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("** Bad FIT image format\n"); + return 1; + } + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; #endif default: + show_boot_progress (-49); puts ("** Unknown image type\n"); return 1; } @@ -490,6 +496,11 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (51); +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif /* Loading ok, update default load address */ diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 86959dc..9a168ea 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -484,6 +484,9 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, ulong cnt; image_header_t *hdr; int jffs2 = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif s = strchr(cmd, '.'); if (s != NULL && @@ -516,24 +519,25 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf("\n** Bad Magic Number 0x%x **\n", - image_get_magic (hdr)); - show_boot_progress (-57); - return 1; - } show_boot_progress (57); - image_print_contents (hdr); cnt = image_get_image_size (hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_unsupported ("nand_load_image"); - return 1; + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("** Bad FIT image format\n"); + return 1; + } + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; #endif default: + show_boot_progress (-57); puts ("** Unknown image type\n"); return 1; } @@ -557,6 +561,12 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, } show_boot_progress (58); +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ load_addr = addr; @@ -939,6 +949,10 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong offset = 0; image_header_t *hdr; int rcode = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif + show_boot_progress (52); switch (argc) { case 1: @@ -997,26 +1011,25 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; + image_print_contents (hdr); - if (image_check_magic (hdr)) { - - image_print_contents (hdr); - - cnt = image_get_image_size (hdr); - cnt -= SECTORSIZE; - } else { - printf ("\n** Bad Magic Number 0x%x **\n", - image_get_magic (hdr)); - show_boot_progress (-57); - return 1; - } + cnt = image_get_image_size (hdr); + cnt -= SECTORSIZE; break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_unsupported ("nboot"); - return 1; + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("** Bad FIT image format\n"); + return 1; + } + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; #endif default: + show_boot_progress (-57); puts ("** Unknown image type\n"); return 1; } @@ -1031,6 +1044,12 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (58); +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ load_addr = addr; diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 7868805..f49531e 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -211,6 +211,9 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) disk_partition_t info; image_header_t *hdr; int rcode = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif switch (argc) { case 1: @@ -277,11 +280,6 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf("\n** Bad Magic Number **\n"); - return 1; - } - if (!image_check_hcrc (hdr)) { puts ("\n** Bad Header Checksum **\n"); return 1; @@ -292,8 +290,15 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_unsupported ("scsi"); - return 1; + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("** Bad FIT image format\n"); + return 1; + } + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; #endif default: puts ("** Unknown image type\n"); @@ -309,6 +314,13 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf ("** Read error on %d:%d\n", dev, part); return 1; } + +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ load_addr = addr; diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 8ee7d27..bf56c6a 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -315,7 +315,9 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) disk_partition_t info; image_header_t *hdr; block_dev_desc_t *stor_dev; - +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif switch (argc) { case 1: @@ -390,11 +392,6 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; - if (!image_check_magic (hdr)) { - printf("\n** Bad Magic Number **\n"); - return 1; - } - if (!image_check_hcrc (hdr)) { puts ("\n** Bad Header Checksum **\n"); return 1; @@ -406,8 +403,15 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_unsupported ("usbboot"); - return 1; + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("** Bad FIT image format\n"); + return 1; + } + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; #endif default: puts ("** Unknown image type\n"); @@ -423,6 +427,13 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf ("\n** Read error on %d:%d\n", dev, part); return 1; } + +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ load_addr = addr; -- cgit v0.10.2 From c28c4d193dbfb20b2dd3a5447640fd6de7fd0720 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:33:01 +0100 Subject: [new uImage] Add new uImage fromat support to fpga command Signed-off-by: Marian Balakowicz diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index 0bb82f6..9141dcc 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -164,6 +164,10 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) char *devstr = getenv ("fpga"); char *datastr = getenv ("fpgadata"); int rc = FPGA_FAIL; +#if defined (CONFIG_FIT) + const char *fit_uname = NULL; + ulong fit_addr; +#endif if (devstr) dev = (int) simple_strtoul (devstr, NULL, 16); @@ -173,9 +177,22 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) switch (argc) { case 5: /* fpga */ data_size = simple_strtoul (argv[4], NULL, 16); + case 4: /* fpga */ - fpga_data = (void *) simple_strtoul (argv[3], NULL, 16); +#if defined(CONFIG_FIT) + if (fit_parse_subimage (argv[3], (ulong)fpga_data, + &fit_addr, &fit_uname)) { + fpga_data = (void *)fit_addr; + debug ("* fpga: subimage '%s' from FIT image at 0x%08lx\n", + fit_uname, fit_addr); + } else +#endif + { + fpga_data = (void *) simple_strtoul (argv[3], NULL, 16); + debug ("* fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data); + } PRINTF ("%s: fpga_data = 0x%x\n", __FUNCTION__, (uint) fpga_data); + case 3: /* fpga */ dev = (int) simple_strtoul (argv[2], NULL, 16); PRINTF ("%s: device = %d\n", __FUNCTION__, dev); @@ -183,14 +200,29 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if ((argc == 3) && (dev > fpga_count ())) { /* must be buffer ptr */ PRINTF ("%s: Assuming buffer pointer in arg 3\n", __FUNCTION__); - fpga_data = (void *) dev; + +#if defined(CONFIG_FIT) + if (fit_parse_subimage (argv[2], (ulong)fpga_data, + &fit_addr, &fit_uname)) { + fpga_data = (void *)fit_addr; + debug ("* fpga: subimage '%s' from FIT image at 0x%08lx\n", + fit_uname, fit_addr); + } else +#endif + { + fpga_data = (void *) dev; + debug ("* fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data); + } + PRINTF ("%s: fpga_data = 0x%x\n", __FUNCTION__, (uint) fpga_data); dev = FPGA_INVALID_DEVICE; /* reset device num */ } + case 2: /* fpga */ op = (int) fpga_get_op (argv[1]); break; + default: PRINTF ("%s: Too many or too few args (%d)\n", __FUNCTION__, argc); @@ -222,10 +254,6 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) image_header_t *hdr = (image_header_t *)fpga_data; ulong data; - if (!image_check_magic (hdr)) { - puts ("Bad Magic Number\n"); - return 1; - } data = (ulong)image_get_data (hdr); data_size = image_get_data_size (hdr); rc = fpga_load (dev, (void *)data, data_size); @@ -233,8 +261,42 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: - fit_unsupported ("fpga"); - rc = FPGA_FAIL; + { + const void *fit_hdr = (const void *)fpga_data; + int noffset; + void *fit_data; + + if (fit_uname == NULL) { + puts ("No FIT subimage unit name\n"); + return 1; + } + + if (!fit_check_format (fit_hdr)) { + puts ("Bad FIT image format\n"); + return 1; + } + + /* get fpga component image node offset */ + noffset = fit_image_get_node (fit_hdr, fit_uname); + if (noffset < 0) { + printf ("Can't find '%s' FIT subimage\n", fit_uname); + return 1; + } + + /* verify integrity */ + if (!fit_image_check_hashes (fit_hdr, noffset)) { + puts ("Bad Data Hash\n"); + return 1; + } + + /* get fpga subimage data address and length */ + if (fit_image_get_data (fit_hdr, noffset, &fit_data, &data_size)) { + puts ("Could not find fpga subimage data\n"); + return 1; + } + + rc = fpga_load (dev, fit_data, data_size); + } break; #endif default: @@ -295,4 +357,9 @@ U_BOOT_CMD (fpga, 6, 1, do_fpga, "\tload\tLoad device from memory buffer\n" "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n" "\tloadmk\tLoad device generated with mkimage\n" - "\tdump\tLoad device to memory buffer\n"); + "\tdump\tLoad device to memory buffer\n" +#if defined(CONFIG_FIT) + "\tFor loadmk operating on FIT format uImage address must include\n" + "\tsubimage unit name in the form of addr:\n" +#endif +); -- cgit v0.10.2 From 1372cce2b9040fb640e5032b84e3a033a22d6ff0 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:33:01 +0100 Subject: [new uImage] Use show_boot_progress() for new uImage format This patch allocates a set of show_boot_progress() IDs for new uImage format and adds show_boot_progress() calls in new uImage format handling code. Signed-off-by: Marian Balakowicz diff --git a/README b/README index 491397a..183246e 100644 --- a/README +++ b/README @@ -1659,6 +1659,8 @@ The following options need to be configured: example, some LED's) on your board. At the moment, the following checkpoints are implemented: +Legacy uImage format: + Arg Where When 1 common/cmd_bootm.c before attempting to boot an image -1 common/cmd_bootm.c Image header has bad magic number @@ -1669,25 +1671,26 @@ The following options need to be configured: 4 common/cmd_bootm.c Image data has correct checksum -4 common/cmd_bootm.c Image is for unsupported architecture 5 common/cmd_bootm.c Architecture check OK - -5 common/cmd_bootm.c Wrong Image Type (not kernel, multi, standalone) + -5 common/cmd_bootm.c Wrong Image Type (not kernel, multi) 6 common/cmd_bootm.c Image Type check OK -6 common/cmd_bootm.c gunzip uncompression error -7 common/cmd_bootm.c Unimplemented compression type 7 common/cmd_bootm.c Uncompression OK - -8 common/cmd_bootm.c Wrong Image Type (not kernel, multi, standalone) - 8 common/cmd_bootm.c Image Type check OK + 8 common/cmd_bootm.c No uncompress/copy overwrite error -9 common/cmd_bootm.c Unsupported OS (not Linux, BSD, VxWorks, QNX) - 9 common/cmd_bootm.c Start initial ramdisk verification - -10 common/cmd_bootm.c Ramdisk header has bad magic number - -11 common/cmd_bootm.c Ramdisk header has bad checksum - 10 common/cmd_bootm.c Ramdisk header is OK - -12 common/cmd_bootm.c Ramdisk data has bad checksum - 11 common/cmd_bootm.c Ramdisk data has correct checksum - 12 common/cmd_bootm.c Ramdisk verification complete, start loading - -13 common/cmd_bootm.c Wrong Image Type (not PPC Linux Ramdisk) - 13 common/cmd_bootm.c Start multifile image verification - 14 common/cmd_bootm.c No initial ramdisk, no multifile, continue. - 15 common/cmd_bootm.c All preparation done, transferring control to OS + + 9 common/image.c Start initial ramdisk verification + -10 common/image.c Ramdisk header has bad magic number + -11 common/image.c Ramdisk header has bad checksum + 10 common/image.c Ramdisk header is OK + -12 common/image.c Ramdisk data has bad checksum + 11 common/image.c Ramdisk data has correct checksum + 12 common/image.c Ramdisk verification complete, start loading + -13 common/image.c Wrong Image Type (not PPC Linux Ramdisk) + 13 common/image.c Start multifile image verification + 14 common/image.c No initial ramdisk, no multifile, continue. + + 15 lib_/bootm.c All preparation done, transferring control to OS -30 lib_ppc/board.c Fatal error, hang the system -31 post/post.c POST test failed, detected by post_output_backlog() @@ -1757,6 +1760,58 @@ The following options need to be configured: -83 common/cmd_net.c some error in automatic boot or autoscript 84 common/cmd_net.c end without errors +FIT uImage format: + + Arg Where When + 100 common/cmd_bootm.c Kernel FIT Image has correct format + -100 common/cmd_bootm.c Kernel FIT Image has incorrect format + 101 common/cmd_bootm.c No Kernel subimage unit name, using configuration + -101 common/cmd_bootm.c Can't get configuration for kernel subimage + 102 common/cmd_bootm.c Kernel unit name specified + -103 common/cmd_bootm.c Can't get kernel subimage node offset + 104 common/cmd_bootm.c Got kernel subimage node offset + -104 common/cmd_bootm.c Kernel subimage hash verification failed + 105 common/cmd_bootm.c Kernel subimage hash verification OK + -105 common/cmd_bootm.c Kernel subimage is for unsupported architecture + 106 common/cmd_bootm.c Architecture check OK + -106 common/cmd_bootm.c Kernel subimage has wrong typea + 107 common/cmd_bootm.c Kernel subimge type OK + -107 common/cmd_bootm.c Can't get kernel subimage data/size + 108 common/cmd_bootm.c Got kernel subimage data/size + -108 common/cmd_bootm.c Wrong image type (not legacy, FIT) + -109 common/cmd_bootm.c Can't get kernel subimage type + -110 common/cmd_bootm.c Can't get kernel subimage comp + -111 common/cmd_bootm.c Can't get kernel subimage os + -112 common/cmd_bootm.c Can't get kernel subimage load address + -113 common/cmd_bootm.c Image uncompress/copy overwrite error + + 120 common/image.c Start initial ramdisk verification + -120 common/image.c Ramdisk FIT image has incorrect format + 121 common/image.c Ramdisk FIT image has correct format + 122 common/image.c No Ramdisk subimage unit name, using configuration + -122 common/image.c Can't get configuration for ramdisk subimage + 123 common/image.c Ramdisk unit name specified + -124 common/image.c Can't get ramdisk subimage node offset + 125 common/image.c Got ramdisk subimage node offset + -125 common/image.c Ramdisk subimage hash verification failed + 126 common/image.c Ramdisk subimage hash verification OK + -126 common/image.c Ramdisk subimage for unsupported architecture + 127 common/image.c Architecture check OK + -127 common/image.c Can't get ramdisk subimage data/size + 128 common/image.c Got ramdisk subimage data/size + 129 common/image.c Can't get ramdisk load address + -129 common/image.c Got ramdisk load address + + -130 common/cmd_doc.c Icorrect FIT image format + 131 common/cmd_doc.c FIT image format OK + + -140 common/cmd_ide.c Icorrect FIT image format + 141 common/cmd_ide.c FIT image format OK + + -150 common/cmd_nand.c Icorrect FIT image format + 151 common/cmd_nand.c FIT image format OK + + Modem Support: -------------- diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 11c476e..6591e61 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -155,8 +155,6 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - show_boot_progress (6); - /* get image parameters */ switch (genimg_get_format (os_hdr)) { case IMAGE_FORMAT_LEGACY: @@ -172,18 +170,21 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (fit_image_get_type (images.fit_hdr_os, images.fit_noffset_os, &type)) { puts ("Can't get image type!\n"); + show_boot_progress (-109); return 1; } if (fit_image_get_comp (images.fit_hdr_os, images.fit_noffset_os, &comp)) { puts ("Can't get image compression!\n"); + show_boot_progress (-110); return 1; } if (fit_image_get_os (images.fit_hdr_os, images.fit_noffset_os, &os)) { puts ("Can't get image OS!\n"); + show_boot_progress (-111); return 1; } @@ -192,6 +193,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os, &load_start)) { puts ("Can't get image load address!\n"); + show_boot_progress (-112); return 1; } break; @@ -284,6 +286,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) debug ("load_start = 0x%lx, load_end = 0x%lx\n", load_start, load_end); puts ("ERROR: image overwritten - must RESET the board to recover.\n"); + show_boot_progress (-113); do_reset (cmdtp, flag, argc, argv); } @@ -416,21 +419,27 @@ static int fit_check_kernel (const void *fit, int os_noffset, int verify) puts (" Verifying Hash Integrity ... "); if (!fit_image_check_hashes (fit, os_noffset)) { puts ("Bad Data Hash\n"); + show_boot_progress (-104); return 0; } puts ("OK\n"); } + show_boot_progress (105); if (!fit_image_check_target_arch (fit, os_noffset)) { puts ("Unsupported Architecture\n"); + show_boot_progress (-105); return 0; } + show_boot_progress (106); if (!fit_image_check_type (fit, os_noffset, IH_TYPE_KERNEL)) { puts ("Not a kernel image\n"); + show_boot_progress (-106); return 0; } + show_boot_progress (107); return 1; } #endif /* CONFIG_FIT */ @@ -515,6 +524,7 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] images->legacy_hdr_os = hdr; images->legacy_hdr_valid = 1; + show_boot_progress (6); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: @@ -524,8 +534,10 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] if (!fit_check_format (fit_hdr)) { puts ("Bad FIT kernel image format!\n"); + show_boot_progress (-100); return NULL; } + show_boot_progress (100); if (!fit_uname_kernel) { /* @@ -533,29 +545,38 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] * node first. If config unit node name is NULL * fit_conf_get_node() will try to find default config node */ + show_boot_progress (101); conf_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); - if (conf_noffset < 0) + if (conf_noffset < 0) { + show_boot_progress (-101); return NULL; + } os_noffset = fit_conf_get_kernel_node (fit_hdr, conf_noffset); fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL); } else { /* get kernel component image node offset */ + show_boot_progress (102); os_noffset = fit_image_get_node (fit_hdr, fit_uname_kernel); } - if (os_noffset < 0) + if (os_noffset < 0) { + show_boot_progress (-103); return NULL; + } printf (" Trying '%s' kernel subimage\n", fit_uname_kernel); + show_boot_progress (104); if (!fit_check_kernel (fit_hdr, os_noffset, images->verify)) return NULL; /* get kernel image data address and length */ if (fit_image_get_data (fit_hdr, os_noffset, &data, &len)) { puts ("Could not find kernel subimage data!\n"); + show_boot_progress (-107); return NULL; } + show_boot_progress (108); *os_len = len; *os_data = (ulong)data; @@ -566,6 +587,7 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] #endif default: printf ("Wrong Image Format for %s command\n", cmdtp->name); + show_boot_progress (-108); return NULL; } diff --git a/common/cmd_doc.c b/common/cmd_doc.c index bf2f0a9..83aba37 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -276,9 +276,11 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) case IMAGE_FORMAT_FIT: fit_hdr = (const void *)addr; if (!fit_check_format (fit_hdr)) { + show_boot_progress (-130); puts ("** Bad FIT image format\n"); return 1; } + show_boot_progress (131); puts ("Fit image detected...\n"); cnt = fit_get_size (fit_hdr); diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 6a67dd6..8ace970 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -470,9 +470,11 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) case IMAGE_FORMAT_FIT: fit_hdr = (const void *)addr; if (!fit_check_format (fit_hdr)) { + show_boot_progress (-140); puts ("** Bad FIT image format\n"); return 1; } + show_boot_progress (141); puts ("Fit image detected...\n"); cnt = fit_get_size (fit_hdr); diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 9a168ea..7b1f830 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -528,9 +528,11 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, case IMAGE_FORMAT_FIT: fit_hdr = (const void *)addr; if (!fit_check_format (fit_hdr)) { + show_boot_progress (-150); puts ("** Bad FIT image format\n"); return 1; } + show_boot_progress (151); puts ("Fit image detected...\n"); cnt = fit_get_size (fit_hdr); @@ -1020,9 +1022,11 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) case IMAGE_FORMAT_FIT: fit_hdr = (const void *)addr; if (!fit_check_format (fit_hdr)) { + show_boot_progress (-150); puts ("** Bad FIT image format\n"); return 1; } + show_boot_progress (151); puts ("Fit image detected...\n"); cnt = fit_get_size (fit_hdr); diff --git a/common/image.c b/common/image.c index e838f65..f29614b 100644 --- a/common/image.c +++ b/common/image.c @@ -397,10 +397,7 @@ inline void image_print_contents_noindent (image_header_t *hdr) static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch, int verify) { - image_header_t *rd_hdr; - - show_boot_progress (9); - rd_hdr = (image_header_t *)rd_addr; + image_header_t *rd_hdr = (image_header_t *)rd_addr; if (!image_check_magic (rd_hdr)) { puts ("Bad Magic Number\n"); @@ -830,6 +827,7 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, printf ("## Loading init Ramdisk from Legacy " "Image at %08lx ...\n", rd_addr); + show_boot_progress (9); rd_hdr = image_get_ramdisk (rd_addr, arch, images->verify); @@ -846,10 +844,13 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, printf ("## Loading init Ramdisk from FIT " "Image at %08lx ...\n", rd_addr); + show_boot_progress (120); if (!fit_check_format (fit_hdr)) { puts ("Bad FIT ramdisk image format!\n"); + show_boot_progress (-120); return 0; } + show_boot_progress (121); if (!fit_uname_ramdisk) { /* @@ -857,37 +858,48 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, * node first. If config unit node name is NULL * fit_conf_get_node() will try to find default config node */ + show_boot_progress (122); conf_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); - if (conf_noffset < 0) + if (conf_noffset < 0) { + show_boot_progress (-122); return 0; + } rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, conf_noffset); fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL); } else { /* get ramdisk component image node offset */ + show_boot_progress (123); rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk); } - if (rd_noffset < 0) + if (rd_noffset < 0) { + show_boot_progress (-124); return 0; + } printf (" Trying '%s' ramdisk subimage\n", fit_uname_ramdisk); + show_boot_progress (125); if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify)) return 0; /* get ramdisk image data address and length */ if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) { puts ("Could not find ramdisk subimage data!\n"); + show_boot_progress (-127); return 0; } + show_boot_progress (128); rd_data = (ulong)data; rd_len = size; if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) { puts ("Can't get ramdisk subimage load address!\n"); + show_boot_progress (-129); return 0; } + show_boot_progress (129); images->fit_hdr_rd = fit_hdr; images->fit_uname_rd = fit_uname_ramdisk; @@ -2445,19 +2457,23 @@ static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int puts (" Verifying Hash Integrity ... "); if (!fit_image_check_hashes (fit, rd_noffset)) { puts ("Bad Data Hash\n"); + show_boot_progress (-125); return 0; } puts ("OK\n"); } + show_boot_progress (126); if (!fit_image_check_os (fit, rd_noffset, IH_OS_LINUX) || !fit_image_check_arch (fit, rd_noffset, arch) || !fit_image_check_type (fit, rd_noffset, IH_TYPE_RAMDISK)) { printf ("No Linux %s Ramdisk Image\n", genimg_get_arch_name(arch)); + show_boot_progress (-126); return 0; } + show_boot_progress (127); return 1; } #endif /* USE_HOSTCC */ -- cgit v0.10.2 From 2682ce8a4225f23d72bb7fed069e928dd39d34ae Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:33:01 +0100 Subject: [new uImage] More verbose kernel image uncompress error message Signed-off-by: Marian Balakowicz diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 6591e61..e95c5dd 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -243,7 +243,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf (" Uncompressing %s ... ", type_name); if (gunzip ((void *)load_start, unc_len, (uchar *)os_data, &os_len) != 0) { - puts ("GUNZIP ERROR - must RESET board to recover\n"); + puts ("GUNZIP: uncompress or overwrite error " + "- must RESET board to recover\n"); show_boot_progress (-6); do_reset (cmdtp, flag, argc, argv); } @@ -262,7 +263,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) &unc_len, (char *)os_data, os_len, CFG_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { - printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i); + printf ("BUNZIP2: uncompress or overwrite error %d " + "- must RESET board to recover\n", i); show_boot_progress (-6); do_reset (cmdtp, flag, argc, argv); } -- cgit v0.10.2 From f773bea8e11f4a11c388dcee956b2444203e6b65 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:35:46 +0100 Subject: [new uImage] Add proper ramdisk/FDT handling when FIT configuration is used Save FIT configuration provied in the first bootm argument and use it when to get ramdisk/FDT subimages when second and third (ramdisk/FDT) arguments are not specified. Signed-off-by: Marian Balakowicz diff --git a/README b/README index 183246e..0ed47f0 100644 --- a/README +++ b/README @@ -1769,6 +1769,7 @@ FIT uImage format: -101 common/cmd_bootm.c Can't get configuration for kernel subimage 102 common/cmd_bootm.c Kernel unit name specified -103 common/cmd_bootm.c Can't get kernel subimage node offset + 103 common/cmd_bootm.c Found configuration node 104 common/cmd_bootm.c Got kernel subimage node offset -104 common/cmd_bootm.c Kernel subimage hash verification failed 105 common/cmd_bootm.c Kernel subimage hash verification OK diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index e95c5dd..2f232e7 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -469,7 +469,7 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] const char *fit_uname_kernel = NULL; const void *data; size_t len; - int conf_noffset; + int cfg_noffset; int os_noffset; #endif @@ -548,13 +548,19 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] * fit_conf_get_node() will try to find default config node */ show_boot_progress (101); - conf_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); - if (conf_noffset < 0) { + cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); + if (cfg_noffset < 0) { show_boot_progress (-101); return NULL; } + /* save configuration uname provided in the first + * bootm argument + */ + images->fit_uname_cfg = fdt_get_name (fit_hdr, cfg_noffset, NULL); + printf (" Using '%s' configuration\n", images->fit_uname_cfg); + show_boot_progress (103); - os_noffset = fit_conf_get_kernel_node (fit_hdr, conf_noffset); + os_noffset = fit_conf_get_kernel_node (fit_hdr, cfg_noffset); fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL); } else { /* get kernel component image node offset */ diff --git a/common/image.c b/common/image.c index f29614b..bb57d6d 100644 --- a/common/image.c +++ b/common/image.c @@ -738,6 +738,26 @@ ulong genimg_get_image (ulong img_addr) } /** + * fit_has_config - check if there is a valid FIT configuration + * @images: pointer to the bootm command headers structure + * + * fit_has_config() checks if there is a FIT configuration in use + * (if FTI support is present). + * + * returns: + * 0, no FIT support or no configuration found + * 1, configuration found + */ +int genimg_has_config (bootm_headers_t *images) +{ +#if defined(CONFIG_FIT) + if (images->fit_uname_cfg) + return 1; +#endif + return 0; +} + +/** * boot_get_ramdisk - main ramdisk handling routine * @argc: command argument count * @argv: command argument list @@ -771,7 +791,7 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, const char *fit_uname_ramdisk = NULL; ulong default_addr; int rd_noffset; - int conf_noffset; + int cfg_noffset; const void *data; size_t size; #endif @@ -786,33 +806,63 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, if ((argc >= 3) && (strcmp(argv[2], "-") == 0)) { debug ("## Skipping init Ramdisk\n"); rd_len = rd_data = 0; - } else if (argc >= 3) { + } else if (argc >= 3 || genimg_has_config (images)) { #if defined(CONFIG_FIT) - /* - * If the init ramdisk comes from the FIT image and the FIT image - * address is omitted in the command line argument, try to use - * os FIT image address or default load address. - */ - if (images->fit_uname_os) - default_addr = (ulong)images->fit_hdr_os; - else - default_addr = load_addr; - - if (fit_parse_conf (argv[2], default_addr, - &rd_addr, &fit_uname_config)) { - debug ("* ramdisk: config '%s' from image at 0x%08lx\n", - fit_uname_config, rd_addr); - } else if (fit_parse_subimage (argv[2], default_addr, - &rd_addr, &fit_uname_ramdisk)) { - debug ("* ramdisk: subimage '%s' from image at 0x%08lx\n", - fit_uname_ramdisk, rd_addr); - } else + if (argc >= 3) { + /* + * If the init ramdisk comes from the FIT image and + * the FIT image address is omitted in the command + * line argument, try to use os FIT image address or + * default load address. + */ + if (images->fit_uname_os) + default_addr = (ulong)images->fit_hdr_os; + else + default_addr = load_addr; + + if (fit_parse_conf (argv[2], default_addr, + &rd_addr, &fit_uname_config)) { + debug ("* ramdisk: config '%s' from image at 0x%08lx\n", + fit_uname_config, rd_addr); + } else if (fit_parse_subimage (argv[2], default_addr, + &rd_addr, &fit_uname_ramdisk)) { + debug ("* ramdisk: subimage '%s' from image at 0x%08lx\n", + fit_uname_ramdisk, rd_addr); + } else #endif - { - rd_addr = simple_strtoul(argv[2], NULL, 16); - debug ("* ramdisk: cmdline image address = 0x%08lx\n", - rd_addr); + { + rd_addr = simple_strtoul(argv[2], NULL, 16); + debug ("* ramdisk: cmdline image address = 0x%08lx\n", + rd_addr); + } +#if defined(CONFIG_FIT) + } else { + /* use FIT configuration provided in first bootm + * command argument + */ + rd_addr = (ulong)images->fit_hdr_os; + fit_uname_config = images->fit_uname_cfg; + debug ("* ramdisk: using config '%s' from image at 0x%08lx\n", + fit_uname_config, rd_addr); + + /* + * Check whether configuration has ramdisk defined, + * if not, don't try to use it, quit silently. + */ + fit_hdr = (void *)rd_addr; + cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); + if (cfg_noffset < 0) { + debug ("* ramdisk: no such config\n"); + return 0; + } + + rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset); + if (rd_noffset < 0) { + debug ("* ramdisk: no ramdisk in config\n"); + return 0; + } } +#endif /* copy from dataflash if needed */ rd_addr = genimg_get_image (rd_addr); @@ -859,13 +909,16 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, * fit_conf_get_node() will try to find default config node */ show_boot_progress (122); - conf_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); - if (conf_noffset < 0) { + cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); + if (cfg_noffset < 0) { + puts ("Could not find configuration node\n"); show_boot_progress (-122); return 0; } + fit_uname_config = fdt_get_name (fit_hdr, cfg_noffset, NULL); + printf (" Using '%s' configuration\n", fit_uname_config); - rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, conf_noffset); + rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset); fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL); } else { /* get ramdisk component image node offset */ @@ -873,6 +926,7 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk); } if (rd_noffset < 0) { + puts ("Could not find subimage node\n"); show_boot_progress (-124); return 0; } @@ -2394,7 +2448,7 @@ int fit_conf_get_fdt_node (const void *fit, int noffset) /** * fit_conf_print - prints out the FIT configuration details * @fit: pointer to the FIT format image header - * @conf_noffset: offset of the configuration node + * @noffset: offset of the configuration node * @p: pointer to prefix string * * fit_conf_print() lists all mandatory properies for the processed diff --git a/include/image.h b/include/image.h index 51c0c89..0109560 100644 --- a/include/image.h +++ b/include/image.h @@ -206,6 +206,8 @@ typedef struct bootm_headers { ulong legacy_hdr_valid; #if defined(CONFIG_FIT) + const char *fit_uname_cfg; /* configuration node unit name */ + void *fit_hdr_os; /* os FIT image header */ const char *fit_uname_os; /* os subimage node unit name */ int fit_noffset_os; /* os subimage node offset */ @@ -251,6 +253,7 @@ int genimg_get_comp_id (const char *name); #define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */ int genimg_get_format (void *img_addr); +int genimg_has_config (bootm_headers_t *images); ulong genimg_get_image (ulong img_addr); int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 86e104c..8cdace2 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -415,7 +415,7 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], const char *fit_uname_config = NULL; const char *fit_uname_fdt = NULL; ulong default_addr; - int conf_noffset; + int cfg_noffset; int fdt_noffset; const void *data; size_t size; @@ -424,35 +424,67 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], *of_flat_tree = NULL; *of_size = 0; - if (argc > 3) { + if (argc > 3 || genimg_has_config (images)) { #if defined(CONFIG_FIT) - /* - * If the FDT blob comes from the FIT image and the FIT image - * address is omitted in the command line argument, try to use - * ramdisk or os FIT image address or default load address. - */ - if (images->fit_uname_rd) - default_addr = (ulong)images->fit_hdr_rd; - else if (images->fit_uname_os) - default_addr = (ulong)images->fit_hdr_os; - else - default_addr = load_addr; - - if (fit_parse_conf (argv[3], default_addr, - &fdt_addr, &fit_uname_config)) { - debug ("* fdt: config '%s' from image at 0x%08lx\n", - fit_uname_config, fdt_addr); - } else if (fit_parse_subimage (argv[3], default_addr, - &fdt_addr, &fit_uname_fdt)) { - debug ("* fdt: subimage '%s' from image at 0x%08lx\n", - fit_uname_fdt, fdt_addr); - } else + if (argc > 3) { + /* + * If the FDT blob comes from the FIT image and the + * FIT image address is omitted in the command line + * argument, try to use ramdisk or os FIT image + * address or default load address. + */ + if (images->fit_uname_rd) + default_addr = (ulong)images->fit_hdr_rd; + else if (images->fit_uname_os) + default_addr = (ulong)images->fit_hdr_os; + else + default_addr = load_addr; + + if (fit_parse_conf (argv[3], default_addr, + &fdt_addr, &fit_uname_config)) { + debug ("* fdt: config '%s' from image at 0x%08lx\n", + fit_uname_config, fdt_addr); + } else if (fit_parse_subimage (argv[3], default_addr, + &fdt_addr, &fit_uname_fdt)) { + debug ("* fdt: subimage '%s' from image at 0x%08lx\n", + fit_uname_fdt, fdt_addr); + } else #endif - { - fdt_addr = simple_strtoul(argv[3], NULL, 16); - debug ("* fdt: cmdline image address = 0x%08lx\n", - fdt_addr); + { + fdt_addr = simple_strtoul(argv[3], NULL, 16); + debug ("* fdt: cmdline image address = 0x%08lx\n", + fdt_addr); + } +#if defined(CONFIG_FIT) + } else { + /* use FIT configuration provided in first bootm + * command argument + */ + fdt_addr = (ulong)images->fit_hdr_os; + fit_uname_config = images->fit_uname_cfg; + debug ("* fdt: using config '%s' from image at 0x%08lx\n", + fit_uname_config, fdt_addr); + + /* + * Check whether configuration has FDT blob defined, + * if not quit silently. + */ + fit_hdr = (void *)fdt_addr; + cfg_noffset = fit_conf_get_node (fit_hdr, + fit_uname_config); + if (cfg_noffset < 0) { + debug ("* fdt: no such config\n"); + return 0; + } + + fdt_noffset = fit_conf_get_fdt_node (fit_hdr, + cfg_noffset); + if (fdt_noffset < 0) { + debug ("* fdt: no fdt in config\n"); + return 0; + } } +#endif debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n", fdt_addr); @@ -522,13 +554,21 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * fit_conf_get_node() will try to * find default config node */ - conf_noffset = fit_conf_get_node (fit_hdr, + cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); - if (conf_noffset < 0) + + if (cfg_noffset < 0) { + fdt_error ("Could not find configuration node\n"); goto error; + } + + fit_uname_config = fdt_get_name (fit_hdr, + cfg_noffset, NULL); + printf (" Using '%s' configuration\n", + fit_uname_config); fdt_noffset = fit_conf_get_fdt_node (fit_hdr, - conf_noffset); + cfg_noffset); fit_uname_fdt = fit_get_name (fit_hdr, fdt_noffset, NULL); } else { @@ -536,8 +576,10 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], fdt_noffset = fit_image_get_node (fit_hdr, fit_uname_fdt); } - if (fdt_noffset < 0) + if (fdt_noffset < 0) { + fdt_error ("Could not find subimage node\n"); goto error; + } printf (" Trying '%s' FDT blob subimage\n", fit_uname_fdt); -- cgit v0.10.2 From 1d1cb4270edc6a99276834064069717f9782c491 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:35:51 +0100 Subject: [new uImage] Fix build problems on trab board Signed-off-by: Marian Balakowicz diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c index fa08bff..5311e12 100644 --- a/board/trab/auto_update.c +++ b/board/trab/auto_update.c @@ -224,7 +224,7 @@ au_check_cksum_valid(int idx, long nbytes) return -1; } /* check the data CRC */ - if (!image_check_dcrc (hdr)) { + if (!image_check_dcrc (hdr)) { printf ("Image %s bad data checksum\n", aufile[idx]); return -1; @@ -284,7 +284,7 @@ au_check_header_valid(int idx, long nbytes) return -1; } if ((idx == IDX_APP) && !image_check_type (hdr, IH_TYPE_RAMDISK) - && !image_check_type (hdr, FILESYSTEM)) { + && !image_check_type (hdr, IH_TYPE_FILESYSTEM)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } -- cgit v0.10.2 From 1ec73761d2e247078f4520a265d463e8b73391a2 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 10:35:52 +0100 Subject: [new uImage] Fix definition of common bootm_headers_t fields verify, autostart and lmb fields are used regardless of CONFIG_FIT setting, move their definitions to common section. Signed-off-by: Marian Balakowicz diff --git a/include/image.h b/include/image.h index 0109560..fbd8c30 100644 --- a/include/image.h +++ b/include/image.h @@ -221,10 +221,11 @@ typedef struct bootm_headers { const char *fit_uname_fdt; /* FDT blob subimage node unit name */ int fit_noffset_fdt;/* FDT blob subimage node offset */ #endif +#endif + int verify; /* getenv("verify")[0] != 'n' */ int autostart; /* getenv("autostart")[0] != 'n' */ struct lmb *lmb; /* for memory mgmt */ -#endif } bootm_headers_t; /* -- cgit v0.10.2 From 3310c549a73a949430bfda90876df7552a1dab0c Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 12:13:13 +0100 Subject: [new uImage] Add new uImage format documentation and examples Create doc/uImage.FIT documentation directory with the following files: - command_syntax_extensions.txt : extended command syntax description - howto.txt : short usage howto - source_file_format.txt : internal new uImage format description Add example image source files: - kernel.its - kernel_fdt.its - multi.its Update README appropriately. Signed-off-by: Marian Balakowicz Signed-off-by: Bartlomiej Sieka diff --git a/README b/README index 0ed47f0..26bd0cf 100644 --- a/README +++ b/README @@ -2684,6 +2684,14 @@ Some configuration options can be set using Environment Variables: configuration from the BOOTP server, but not try to load any image using TFTP + autoscript - if set to "yes" commands like "loadb", "loady", + "bootp", "tftpb", "rarpboot" and "nfs" will attempt + to automatically run script images (by internally + calling "autoscript"). + + autoscript_uname - if script image is in a format (FIT) this + variable is used to get script subimage unit name. + autostart - if set to "yes", an image loaded using the "bootp", "rarpboot", "tftpboot" or "diskboot" commands will be automatically started (by internally calling @@ -2898,10 +2906,24 @@ o If neither SROM nor the environment contain a MAC address, an error Image Formats: ============== -The "boot" commands of this monitor operate on "image" files which -can be basicly anything, preceeded by a special header; see the -definitions in include/image.h for details; basicly, the header -defines the following image properties: +U-Boot is capable of booting (and performing other auxiliary operations on) +images in two formats: + +New uImage format (FIT) +----------------------- + +Flexible and powerful format based on Flattened Image Tree -- FIT (similar +to Flattened Device Tree). It allows the use of images with multiple +components (several kernels, ramdisks, etc.), with contents protected by +SHA1, MD5 or CRC32. More details are found in the doc/uImage.FIT directory. + + +Old uImage format +----------------- + +Old image format is based on binary files which can be basically anything, +preceded by a special header; see the definitions in include/image.h for +details; basically, the header defines the following image properties: * Target Operating System (Provisions for OpenBSD, NetBSD, FreeBSD, 4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, diff --git a/doc/uImage.FIT/command_syntax_extensions.txt b/doc/uImage.FIT/command_syntax_extensions.txt new file mode 100644 index 0000000..b8b50ff --- /dev/null +++ b/doc/uImage.FIT/command_syntax_extensions.txt @@ -0,0 +1,191 @@ +Command syntax extensions for the new uImage format +=================================================== + +Author: Bartlomiej Sieka + +With the introduction of the new uImage format, bootm command (and other +commands as well) have to understand new syntax of the arguments. This is +necessary in order to specify objects contained in the new uImage, on which +bootm has to operate. This note attempts to first summarize bootm usage +scenarios, and then introduces new argument syntax. + + +bootm usage scenarios +--------------------- + +Below is a summary of bootm usage scenarios, focused on booting a PowerPC +Linux kernel. The purpose of the following list is to document a complete list +of supported bootm usages. + +Note: U-Boot supports two methods of booting a PowerPC Linux kernel: old way, +i.e., without passing the Flattened Device Tree (FDT), and new way, where the +kernel is passed a pointer to the FDT. The boot method is indicated for each +scenario. + + +1. bootm boot image at the current address, equivalent to 2,3,8 + +Old uImage: +2. bootm /* single image at */ +3. bootm /* multi-image at */ +4. bootm - /* multi-image at */ +5. bootm /* single image at */ +6. bootm /* single image at */ +7. bootm - /* single image at */ + +New uImage: +8. bootm +9. bootm []: +10. bootm []# +11. bootm []: []: +12. bootm []: []: []: +13. bootm []: []: +14. bootm []: - []: +15. bootm []: - + + +Ad. 1. This is equivalent to cases 2,3,8, depending on the type of image at +the current image address. +- boot method: see cases 2,3,8 + +Ad. 2. Boot kernel image located at . +- boot method: non-FDT + +Ad. 3. First and second components of the image at are assumed to be a +kernel and a ramdisk, respectively. The kernel is booted with initrd loaded +with the ramdisk from the image. +- boot method: depends on the number of components at , and on whether + U-Boot is compiled with OF support: + + | 2 components | 3 components | + | (kernel, initrd) | (kernel, initrd, fdt) | +--------------------------------------------------------------------- +#ifdef CONFIG_OF_* | non-FDT | FDT | +#ifndef CONFIG_OF_* | non-FDT | non-FDT | + +Ad. 4. Similar to case 3, but the kernel is booted without initrd. Second +component of the multi-image is irrelevant (it can be a dummy, 1-byte file). +- boot method: see case 3 + +Ad. 5. Boot kernel image located at with initrd loaded with ramdisk +from the image at . +- boot method: non-FDT + +Ad. 6. is the address of a kernel image, is the address of a +ramdisk image, and is the address of a FDT binary blob. Kernel is +booted with initrd loaded with ramdisk from the image at . +- boot method: FDT + +Ad. 7. is the address of a kernel image and is the address of +a FDT binary blob. Kernel is booted without initrd. +- boot method: FDT + +Ad. 8. Image at is assumed to contain a default configuration, which +is booted. +- boot method: FDT or non-FDT, depending on whether the default configuration + defines FDT + +Ad. 9. Similar to case 2: boot kernel stored in from the image at +address . +- boot method: non-FDT + +Ad. 10. Boot configuration from the image at . +- boot method: FDT or non-FDT, depending on whether the configuration given + defines FDT + +Ad. 11. Equivalent to case 5: boot kernel stored in from the image +at with initrd loaded with ramdisk from the image at +. +- boot method: non-FDT + +Ad. 12. Equivalent to case 6: boot kernel stored in from the image +at with initrd loaded with ramdisk from the image at +, and pass FDT blob from the image at . +- boot method: FDT + +Ad. 13. Similar to case 12, the difference being that is the address +of FDT binary blob that is to be passed to the kernel. +- boot method: FDT + +Ad. 14. Equivalent to case 7: boot kernel stored in from the image +at , without initrd, and pass FDT blob from the image at +. +- boot method: FDT + +Ad. 15. Similar to case 14, the difference being that is the address +of the FDT binary blob that is to be passed to the kernel. +- boot method: FDT + + +New uImage argument syntax +-------------------------- + +New uImage support introduces two new forms for bootm arguments, with the +following syntax: + +- new uImage sub-image specification +: + +- new uImage configuration specification +# + + +Examples: + +- boot kernel "kernel@1" stored in a new uImage located at 200000: +bootm 200000:kernel@1 + +- boot configuration "cfg@1" from a new uImage located at 200000: +bootm 200000#cfg@1 + +- boot "kernel@1" from a new uImage at 200000 with initrd "ramdisk@2" found in + some other new uImage stored at address 800000: +bootm 200000:kernel@1 800000:ramdisk@2 + +- boot "kernel@2" from a new uImage at 200000, with initrd "ramdisk@1" and FDT + "fdt@1", both stored in some other new uImage located at 800000: +bootm 200000:kernel@1 800000:ramdisk@1 800000:fdt@1 + +- boot kernel "kernel@2" with initrd "ramdisk@2", both stored in a new uImage + at address 200000, with a raw FDT blob stored at address 600000: +bootm 200000:kernel@2 200000:ramdisk@2 600000 + +- boot kernel "kernel@2" from new uImage at 200000 with FDT "fdt@1" from the + same new uImage: +bootm 200000:kernel@2 - 200000:fdt@1 + + +Note on current image address +----------------------------- + +When bootm is called without arguments, the image at current image address is +booted. The current image address is the address set most recently by a load +command, etc, and is by default equal to CFG_LOAD_ADDR. For example, consider +the following commands: + +tftp 200000 /tftpboot/kernel +bootm +Last command is equivalent to: +bootm 200000 + +In case of the new uImage argument syntax, the address portion of any argument +can be omitted. If is omitted, then it is assumed that image at + should be used. Similarly, when is omitted, is is assumed that +image at should be used. If is omitted, it is assumed that the +current image address is to be used. For example, consider the following +commands: + +tftp 200000 /tftpboot/uImage +bootm :kernel@1 +Last command is equivalent to: +bootm 200000:kernel@1 + +tftp 200000 /tftpboot/uImage +bootm 400000:kernel@1 :ramdisk@1 +Last command is equivalent to: +bootm 400000:kernel@1 400000:ramdisk@1 + +tftp 200000 /tftpboot/uImage +bootm :kernel@1 400000:ramdisk@1 :fdt@1 +Last command is equivalent to: +bootm 200000:kernel@1 400000:ramdisk@1 400000:fdt@1 diff --git a/doc/uImage.FIT/howto.txt b/doc/uImage.FIT/howto.txt new file mode 100644 index 0000000..35ab97d --- /dev/null +++ b/doc/uImage.FIT/howto.txt @@ -0,0 +1,296 @@ +How to use images in the new image format +========================================= + +Author: Bartlomiej Sieka + + +Overview +-------- + +The new uImage format allows more flexibility in handling images of various +types (kernel, ramdisk, etc.), it also enhances integrity protection of images +with sha1 and md5 checksums. + +Two auxiliary tools are needed on the development host system in order to +create an uImage in the new format: mkimage and dtc, although only one +(mkimage) is invoked directly. dtc is called from within mkimage and operates +behind the scenes, but needs to be present in the $PATH nevertheless. It is +important that the dtc used has support for binary includes -- refer to +www.jdl.com for its latest version. mkimage (together with dtc) takes as input +an image source file, which describes the contents of the image and defines +its various properties used during booting. By convention, image source file +has the ".its" extension, also, the details of its format are given in +doc/source_file_format.txt. The actual data that is to be included in the +uImage (kernel, ramdisk, etc.) is specified in the image source file in the +form of paths to appropriate data files. The outcome of the image creation +process is a binary file (by convention with the ".itb" extension) that +contains all the referenced data (kernel, ramdisk, etc.) and other information +needed by U-Boot to handle the uImage properly. The uImage file is then +transferred to the target (e.g., via tftp) and booted using the bootm command. + +To summarize the prerequisites needed for new uImage creation: +- mkimage +- dtc (with support for binary includes) +- image source file (*.its) +- image data file(s) + + +Here's a graphical overview of the image creation and booting process: + +image source file mkimage + dtc transfer to target + + ---------------> image file --------------------> bootm +image data files(s) + + +Example 1 -- old-style (non-FDT) kernel booting +----------------------------------------------- + +Consider a simple scenario, where a PPC Linux kernel built from sources on the +development host is to be booted old-style (non-FDT) by U-Boot on an embedded +target. Assume that the outcome of the build is vmlinux.bin.gz, a file which +contains a gzip-compressed PPC Linux kernel (the only data file in this case). +The uImage can be produced using the image source file examples/kernel.its +(note that kernel.its assumes that vmlinux.bin.gz is in the current working +directory; if desired, an alternative path can be specified in the kernel.its +file). Here's how to create the image and inspect its contents: + +[on the host system] +$ mkimage -f kernel.its kernel.itb +DTC: dts->dtb on file "kernel.its" +$ +$ mkimage -l kernel.itb +FIT description: Simple image with single Linux kernel +Created: Tue Mar 11 17:26:15 2008 + Image 0 (kernel@1) + Description: Vanilla Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Size: 943347 Bytes = 921.24 kB = 0.90 MB + Architecture: PowerPC + OS: Linux + Load Address: 0x00000000 + Entry Point: 0x00000000 + Hash algo: crc32 + Hash value: 2ae2bb40 + Hash algo: sha1 + Hash value: 3c200f34e2c226ddc789240cca0c59fc54a67cf4 + Default Configuration: 'config@1' + Configuration 0 (config@1) + Description: Boot Linux kernel + Kernel: kernel@1 + + +The resulting image file kernel.itb can be now transferred to the target, +inspected and booted (note that first three U-Boot commands below are shown +for completeness -- they are part of the standard booting procedure and not +specific to the new image format). + +[on the target system] +=> print nfsargs +nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath} +=> print addip +addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off panic=1 +=> run nfsargs addip +=> tftp 900000 /path/to/tftp/location/kernel.itb +Using FEC ETHERNET device +TFTP from server 192.168.1.1; our IP address is 192.168.160.5 +Filename '/path/to/tftp/location/kernel.itb'. +Load address: 0x900000 +Loading: ################################################################# +done +Bytes transferred = 944464 (e6950 hex) +=> iminfo + +## Checking Image at 00900000 ... + FIT image found + FIT description: Simple image with single Linux kernel + Created: 2008-03-11 16:26:15 UTC + Image 0 (kernel@1) + Description: Vanilla Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Start: 0x009000e0 + Data Size: 943347 Bytes = 921.2 kB + Architecture: PowerPC + OS: Linux + Load Address: 0x00000000 + Entry Point: 0x00000000 + Hash algo: crc32 + Hash value: 2ae2bb40 + Hash algo: sha1 + Hash value: 3c200f34e2c226ddc789240cca0c59fc54a67cf4 + Default Configuration: 'config@1' + Configuration 0 (config@1) + Description: Boot Linux kernel + Kernel: kernel@1 + +=> bootm +## Booting kernel from FIT Image at 00900000 ... + Using 'config@1' configuration + Trying 'kernel@1' kernel subimage + Description: Vanilla Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Start: 0x009000e0 + Data Size: 943347 Bytes = 921.2 kB + Architecture: PowerPC + OS: Linux + Load Address: 0x00000000 + Entry Point: 0x00000000 + Hash algo: crc32 + Hash value: 2ae2bb40 + Hash algo: sha1 + Hash value: 3c200f34e2c226ddc789240cca0c59fc54a67cf4 + Verifying Hash Integrity ... crc32+ sha1+ OK + Uncompressing Kernel Image ... OK +Memory BAT mapping: BAT2=256Mb, BAT3=0Mb, residual: 0Mb +Linux version 2.4.25 (m8@hekate) (gcc version 4.0.0 (DENX ELDK 4.0 4.0.0)) #2 czw lip 5 17:56:18 CEST 2007 +On node 0 totalpages: 65536 +zone(0): 65536 pages. +zone(1): 0 pages. +zone(2): 0 pages. +Kernel command line: root=/dev/nfs rw nfsroot=192.168.1.1:/opt/eldk-4.1/ppc_6xx ip=192.168.160.5:192.168.1.1::255.255.0.0:lite5200b:eth0:off panic=1 +Calibrating delay loop... 307.20 BogoMIPS + + +Example 2 -- new-style (FDT) kernel booting +------------------------------------------- + +Consider another simple scenario, where a PPC Linux kernel is to be booted +new-style, i.e., with a FDT blob. In this case there are two prerequisite data +files: vmlinux.bin.gz (Linux kernel) and target.dtb (FDT blob). The uImage can +be produced using image source file examples/kernel_fdt.its like this (note +again, that both prerequisite data files are assumed to be present in the +current working directory -- image source file kernel_fdt.its can be modified +to take the files from some other location if needed): + +[on the host system] +$ mkimage -f kernel_fdt.its kernel_fdt.itb +DTC: dts->dtb on file "kernel_fdt.its" +$ +$ mkimage -l kernel_fdt.itb +FIT description: Simple image with single Linux kernel and FDT blob +Created: Tue Mar 11 16:29:22 2008 + Image 0 (kernel@1) + Description: Vanilla Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Size: 1092037 Bytes = 1066.44 kB = 1.04 MB + Architecture: PowerPC + OS: Linux + Load Address: 0x00000000 + Entry Point: 0x00000000 + Hash algo: crc32 + Hash value: 2c0cc807 + Hash algo: sha1 + Hash value: 264b59935470e42c418744f83935d44cdf59a3bb + Image 1 (fdt@1) + Description: Flattened Device Tree blob + Type: Flat Device Tree + Compression: uncompressed + Data Size: 16384 Bytes = 16.00 kB = 0.02 MB + Architecture: PowerPC + Hash algo: crc32 + Hash value: 0d655d71 + Hash algo: sha1 + Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def + Default Configuration: 'conf@1' + Configuration 0 (conf@1) + Description: Boot Linux kernel with FDT blob + Kernel: kernel@1 + FDT: fdt@1 + + +The resulting image file kernel_fdt.itb can be now transferred to the target, +inspected and booted: + +[on the target system] +=> tftp 900000 /path/to/tftp/location/kernel_fdt.itb +Using FEC ETHERNET device +TFTP from server 192.168.1.1; our IP address is 192.168.160.5 +Filename '/path/to/tftp/location/kernel_fdt.itb'. +Load address: 0x900000 +Loading: ################################################################# + ########### +done +Bytes transferred = 1109776 (10ef10 hex) +=> iminfo + +## Checking Image at 00900000 ... + FIT image found + FIT description: Simple image with single Linux kernel and FDT blob + Created: 2008-03-11 15:29:22 UTC + Image 0 (kernel@1) + Description: Vanilla Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Start: 0x009000ec + Data Size: 1092037 Bytes = 1 MB + Architecture: PowerPC + OS: Linux + Load Address: 0x00000000 + Entry Point: 0x00000000 + Hash algo: crc32 + Hash value: 2c0cc807 + Hash algo: sha1 + Hash value: 264b59935470e42c418744f83935d44cdf59a3bb + Image 1 (fdt@1) + Description: Flattened Device Tree blob + Type: Flat Device Tree + Compression: uncompressed + Data Start: 0x00a0abdc + Data Size: 16384 Bytes = 16 kB + Architecture: PowerPC + Hash algo: crc32 + Hash value: 0d655d71 + Hash algo: sha1 + Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def + Default Configuration: 'conf@1' + Configuration 0 (conf@1) + Description: Boot Linux kernel with FDT blob + Kernel: kernel@1 + FDT: fdt@1 +=> bootm +## Booting kernel from FIT Image at 00900000 ... + Using 'conf@1' configuration + Trying 'kernel@1' kernel subimage + Description: Vanilla Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Start: 0x009000ec + Data Size: 1092037 Bytes = 1 MB + Architecture: PowerPC + OS: Linux + Load Address: 0x00000000 + Entry Point: 0x00000000 + Hash algo: crc32 + Hash value: 2c0cc807 + Hash algo: sha1 + Hash value: 264b59935470e42c418744f83935d44cdf59a3bb + Verifying Hash Integrity ... crc32+ sha1+ OK + Uncompressing Kernel Image ... OK +## Flattened Device Tree from FIT Image at 00900000 + Using 'conf@1' configuration + Trying 'fdt@1' FDT blob subimage + Description: Flattened Device Tree blob + Type: Flat Device Tree + Compression: uncompressed + Data Start: 0x00a0abdc + Data Size: 16384 Bytes = 16 kB + Architecture: PowerPC + Hash algo: crc32 + Hash value: 0d655d71 + Hash algo: sha1 + Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def + Verifying Hash Integrity ... crc32+ sha1+ OK + Booting using the fdt blob at 0xa0abdc + Loading Device Tree to 007fc000, end 007fffff ... OK +[ 0.000000] Using lite5200 machine description +[ 0.000000] Linux version 2.6.24-rc6-gaebecdfc (m8@hekate) (gcc version 4.0.0 (DENX ELDK 4.1 4.0.0)) #1 Sat Jan 12 15:38:48 CET 2008 + + +Example 3 -- advanced booting +----------------------------- + +Refer to examples/multi.its for an image source file that allows more +sophisticated booting scenarios (multiple kernels, ramdisks and fdt blobs). diff --git a/doc/uImage.FIT/kernel.its b/doc/uImage.FIT/kernel.its new file mode 100644 index 0000000..d1a5939 --- /dev/null +++ b/doc/uImage.FIT/kernel.its @@ -0,0 +1,34 @@ +/* + * Simple U-boot uImage source file containing a single kernel + */ +/ { + description = "Simple image with single Linux kernel"; + #address-cells = <1>; + + images { + kernel@1 { + description = "Vanilla Linux kernel"; + data = /incbin/("./vmlinux.bin.gz"); + type = "kernel"; + arch = "ppc"; + os = "linux"; + compression = "gzip"; + load = <00000000>; + entry = <00000000>; + hash@1 { + algo = "crc32"; + }; + hash@2 { + algo = "sha1"; + }; + }; + }; + + configurations { + default = "config@1"; + config@1 { + description = "Boot Linux kernel"; + kernel = "kernel@1"; + }; + }; +}; diff --git a/doc/uImage.FIT/kernel_fdt.its b/doc/uImage.FIT/kernel_fdt.its new file mode 100644 index 0000000..fd6dee2 --- /dev/null +++ b/doc/uImage.FIT/kernel_fdt.its @@ -0,0 +1,48 @@ +/* + * Simple U-boot uImage source file containing a single kernel and FDT blob + */ +/ { + description = "Simple image with single Linux kernel and FDT blob"; + #address-cells = <1>; + + images { + kernel@1 { + description = "Vanilla Linux kernel"; + data = /incbin/("./vmlinux.bin.gz"); + type = "kernel"; + arch = "ppc"; + os = "linux"; + compression = "gzip"; + load = <00000000>; + entry = <00000000>; + hash@1 { + algo = "crc32"; + }; + hash@2 { + algo = "sha1"; + }; + }; + fdt@1 { + description = "Flattened Device Tree blob"; + data = /incbin/("./target.dtb"); + type = "flat_dt"; + arch = "ppc"; + compression = "none"; + hash@1 { + algo = "crc32"; + }; + hash@2 { + algo = "sha1"; + }; + }; + }; + + configurations { + default = "conf@1"; + conf@1 { + description = "Boot Linux kernel with FDT blob"; + kernel = "kernel@1"; + fdt = "fdt@1"; + }; + }; +}; diff --git a/doc/uImage.FIT/multi.its b/doc/uImage.FIT/multi.its new file mode 100644 index 0000000..b992962 --- /dev/null +++ b/doc/uImage.FIT/multi.its @@ -0,0 +1,124 @@ +/* + * U-boot uImage source file with multiple kernels, ramdisks and FDT blobs + */ +/ { + description = "Various kernels, ramdisks and FDT blobs"; + #address-cells = <1>; + + images { + kernel@1 { + description = "vanilla-2.6.23"; + data = /incbin/("./vmlinux.bin.gz"); + type = "kernel"; + arch = "ppc"; + os = "linux"; + compression = "gzip"; + load = <00000000>; + entry = <00000000>; + hash@1 { + algo = "md5"; + }; + hash@2 { + algo = "sha1"; + }; + }; + + kernel@2 { + description = "2.6.23-denx"; + data = /incbin/("./2.6.23-denx.bin.gz"); + type = "kernel"; + arch = "ppc"; + os = "linux"; + compression = "gzip"; + load = <00000000>; + entry = <00000000>; + hash@1 { + algo = "sha1"; + }; + }; + + kernel@3 { + description = "2.4.25-denx"; + data = /incbin/("./2.4.25-denx.bin.gz"); + type = "kernel"; + arch = "ppc"; + os = "linux"; + compression = "gzip"; + load = <00000000>; + entry = <00000000>; + hash@1 { + algo = "md5"; + }; + }; + + ramdisk@1 { + description = "eldk-4.2-ramdisk"; + data = /incbin/("./eldk-4.2-ramdisk"); + type = "ramdisk"; + arch = "ppc"; + compression = "gzip"; + hash@1 { + algo = "sha1"; + }; + }; + + ramdisk@2 { + description = "eldk-3.1-ramdisk"; + data = /incbin/("./eldk-3.1-ramdisk"); + type = "ramdisk"; + arch = "ppc"; + compression = "gzip"; + hash@1 { + algo = "crc32"; + }; + }; + + fdt@1 { + description = "tqm5200-fdt"; + data = /incbin/("./tqm5200.dtb"); + type = "flat_dt"; + arch = "ppc"; + compression = "none"; + hash@1 { + algo = "crc32"; + }; + }; + + fdt@2 { + description = "tqm5200s-fdt"; + data = /incbin/("./tqm5200s.dtb"); + type = "flat_dt"; + arch = "ppc"; + compression = "none"; + load = <00700000>; + hash@1 { + algo = "sha1"; + }; + }; + + }; + + configurations { + default = "config@1"; + + config@1 { + description = "tqm5200 vanilla-2.6.23 configuration"; + kernel = "kernel@1"; + ramdisk = "ramdisk@1"; + fdt = "fdt@1"; + }; + + config@2 { + description = "tqm5200s denx-2.6.23 configuration"; + kernel = "kernel@2"; + ramdisk = "ramdisk@1"; + fdt = "fdt@2"; + }; + + config@3 { + description = "tqm5200s denx-2.4.25 configuration"; + kernel = "kernel@3"; + ramdisk = "ramdisk@2"; + }; + }; +}; diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt new file mode 100644 index 0000000..3f7104f --- /dev/null +++ b/doc/uImage.FIT/source_file_format.txt @@ -0,0 +1,262 @@ +U-boot new uImage source file format (bindings definition) +========================================================== + +Author: Marian Balakowicz + +1) Introduction +--------------- + +Evolution of the 2.6 Linux kernel for embedded PowerPC systems introduced new +booting method which requires that hardware description is available to the +kernel in the form of Flattened Device Tree. + +Booting with a Flattened Device Tree is much more flexible and is intended to +replace direct passing of 'struct bd_info' which was used to boot pre-FDT +kernels. + +However, U-boot needs to support both techniques to provide backward +compatibility for platforms which are not FDT ready. Number of elements +playing role in the booting process has increased and now includes the FDT +blob. Kernel image, FDT blob and possibly ramdisk image - all must be placed +in the system memory and passed to bootm as a arguments. Some of them may be +missing: FDT is not present for legacy platforms, ramdisk is always optional. +Additionally, old uImage format has been extended to support multi sub-images +but the support is limited by simple format of the legacy uImage structure. +Single binary header 'struct image_header' is not flexible enough to cover all +possible scenarios. + +All those factors combined clearly show that there is a need for new, more +flexible, multi component uImage format. + + +2) New uImage format assumptions +-------------------------------- + +a) Implementation + +Libfdt has been selected for the new uImage format implementation as (1) it +provides needed functionality, (2) is actively maintained and developed and +(3) increases code reuse as it is already part of the U-boot source tree. + +b) Terminology + +This document defines new uImage structure by providing FDT bindings for new +uImage internals. Bindings are defined from U-boot perspective, i.e. describe +final form of the uImage at the moment when it reaches U-boot. User +perspective may be simpler, as some of the properties (like timestamps and +hashes) will need to be filled in automatically by the U-boot mkimage tool. + +To avoid confusion with the kernel FDT the following naming convention is +proposed for the new uImage format related terms: + +FIT - Flattened uImage Tree + +FIT is formally a flattened device tree (in the libfdt meaning), which +conforms to bindings defined in this document. + +.its - image tree source +.itb - image tree blob + +c) Image building procedure + +The following picture shows how the new uImage is prepared. Input consists of +image source file (.its) and a set of data files. Image is created with the +help of standard U-boot mkimage tool which in turn uses dtc (device tree +compiler) to produce image tree blob (.itb). Resulting .itb file is is the +actual binary of a new uImage. + + +tqm5200.its ++ +vmlinux.bin.gz mkimage + dtc xfer to target +eldk-4.2-ramdisk --------------> tqm5200.itb --------------> bootm +tqm5200.dtb /|\ +... | + 'new uImage' + + - create .its file, automatically filled-in properties are omitted + - call mkimage tool on a .its file + - mkimage calls dtc to create .itb image and assures that + missing properties are added + - .itb (new uImage) is uploaded onto the target and used therein + + +d) Unique identifiers + +To identify FIT sub-nodes representing images, hashes, configurations (which +are defined in the following sections), the "unit name" of the given sub-node +is used as it's identifier as it assures uniqueness without additional +checking required. + + +3) Root node properties +----------------------- + +Root node of the uImage Tree should have the following layout: + +/ o image-tree + |- description = "image description" + |- timestamp = <12399321> + |- #address-cells = <1> + | + o images + | | + | o img@1 {...} + | o img@2 {...} + | ... + | + o configurations + |- default = "cfg@1" + | + o cfg@1 {...} + o cfg@2 {...} + ... + + + Optional property: + - description : Textual description of the uImage + + Mandatory property: + - timestamp : Last image modification time being counted in seconds since + 1970-01-01 00:00:00 - to be automatically calculated by mkimage tool. + + Conditionally mandatory property: + - #address-cells : Number of 32bit cells required to represent entry and + load addresses supplied within sub-image nodes. May be omitted when no + entry or load addresses are used. + + Mandatory node: + - images : This node contains a set of sub-nodes, each of them representing + single component sub-image (like kernel, ramdisk, etc.). At least one + sub-image is required. + + Optional node: + - configurations : Contains a set of available configuration nodes and + defines a default configuration. + + +4) '/images' node +----------------- + +This node is a container node for component sub-image nodes. Each sub-node of +the '/images' node should have the following layout: + + o image@1 + |- description = "component sub-image description" + |- data = /incbin/("path/to/data/file.bin") + |- type = "sub-image type name" + |- arch = "ARCH name" + |- os = "OS name" + |- compression = "compression name" + |- load = <00000000> + |- entry = <00000000> + | + o hash@1 {...} + o hash@2 {...} + ... + + Mandatory properties: + - description : Textual description of the component sub-image + - type : Name of component sub-image type, supported types are: + "standalone", "kernel", "ramdisk", "firmware", "script", "filesystem", + "fdt". + - data : Path to the external file which contains this node's binary data. + - compression : Compression used by included data. Supported compressions + are "gzip" and "bzip2". If no compression is used compression property + should be set to "none". + + Conditionally mandatory property: + - os : OS name, mandatory for type="kernel", valid OS names are: "openbsd", + "netbsd", "freebsd", "4_4bsd", "linux", "svr4", "esix", "solaris", "irix", + "sco", "dell", "ncr", "lynxos", "vxworks", "psos", "qnx", "u_boot", + "rtems", "artos", "unity". + - arch : Architecture name, mandatory for types: "standalone", "kernel", + "firmware", "ramdisk" and "fdt". Valid architecture names are: "alpha", + "arm", "i386", "ia64", "mips", "mips64", "ppc", "s390", "sh", "sparc", + "sparc64", "m68k", "nios", "microblaze", "nios2", "blackfin", "avr32", + "st200". + - entry : entry point address, address size is determined by + '#address-cells' property of the root node. Mandatory for for types: + "standalone" and "kernel". + - load : load address, address size is determined by '#address-cells' + property of the root node. Mandatory for types: "standalone" and "kernel". + + Optional nodes: + - hash@1 : Each hash sub-node represents separate hash or checksum + calculated for node's data according to specified algorithm. + + +5) Hash nodes +------------- + +o hash@1 + |- algo = "hash or checksum algorithm name" + |- value = [hash or checksum value] + + Mandatory properties: + - algo : Algorithm name, supported are "crc32", "md5" and "sha1". + - value : Actual checksum or hash value, correspondingly 4, 16 or 20 bytes + long. + + +6) '/configurations' node +------------------------- + +The 'configurations' node is optional. If present, it allows to create a +convenient, labeled boot configurations, which combine together kernel images +with their ramdisks and fdt blobs. + +The 'configurations' node has has the following structure: + +o configurations + |- default = "default configuration sub-node unit name" + | + o config@1 {...} + o config@2 {...} + ... + + + Optional property: + - default : Selects one of the configuration sub-nodes as a default + configuration. + + Mandatory nodes: + - configuration-sub-node-unit-name : At least one of the configuration + sub-nodes is required. + + +7) Configuration nodes +---------------------- + +Each configuration has the following structure: + +o config@1 + |- description = "configuration description" + |- kernel = "kernel sub-node unit name" + |- ramdisk = "ramdisk sub-node unit name" + |- fdt = "fdt sub-node unit-name" + + + Mandatory properties: + - description : Textual configuration description. + - kernel : Unit name of the corresponding kernel image (image sub-node of a + "kernel" type). + + Optional properties: + - ramdisk : Unit name of the corresponding ramdisk image (component image + node of a "ramdisk" type). + - fdt : Unit name of the corresponding fdt blob (component image node of a + "fdt type"). + +The FDT blob is required to properly boot FDT based kernel, so the minimal +configuration for 2.6 FDT kernel is (kernel, fdt) pair. + +Older, 2.4 kernel and 2.6 non-FDT kernel do not use FDT blob, in such cases +'struct bd_info' must be passed instead of FDT blob, thus fdt property *must +not* be specified in a configuration node. + + +8) Examples +----------- + +Please see examples/*.its for actual image source files. -- cgit v0.10.2 From afe45c87e3c5d77bad76b1a57dccd20764d45b5d Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Wed, 12 Mar 2008 12:14:15 +0100 Subject: [new uImage] Fix build issue on ARM ARM platforms don't have a bd->bi_memsize so use bd->bi_dram[0].size instead. Signed-off-by: Kumar Gala diff --git a/common/image.c b/common/image.c index bb57d6d..a2a739e 100644 --- a/common/image.c +++ b/common/image.c @@ -463,8 +463,10 @@ ulong getenv_bootm_low(void) return tmp; } -#ifdef CFG_SDRAM_BASE +#if defined(CFG_SDRAM_BASE) return CFG_SDRAM_BASE; +#elif defined(CONFIG_ARM) + return gd->bd->bi_dram[0].start; #else return 0; #endif @@ -478,7 +480,11 @@ ulong getenv_bootm_size(void) return tmp; } +#if defined(CONFIG_ARM) + return gd->bd->bi_dram[0].size; +#else return gd->bd->bi_memsize; +#endif } void memmove_wd (void *to, void *from, size_t len, ulong chunksz) -- cgit v0.10.2 From 0ede0c383530a418cf98be9122371a86573cd0db Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Fri, 14 Mar 2008 16:22:34 +0100 Subject: Add the MD5 algorithm MD5 supoprt is turned on by defining CONFIG_MD5, the digest can be then calculated using the md5() function -- see include/md5.h for details. Signed-off-by: Bartlomiej Sieka diff --git a/include/md5.h b/include/md5.h new file mode 100644 index 0000000..046d1ee --- /dev/null +++ b/include/md5.h @@ -0,0 +1,23 @@ +/* + * This file was transplanted with slight modifications from Linux sources + * (fs/cifs/md5.h) into U-Boot by Bartlomiej Sieka . + */ + +#ifndef _MD5_H +#define _MD5_H + +#include + +struct MD5Context { + __u32 buf[4]; + __u32 bits[2]; + unsigned char in[64]; +}; + +/* + * Calculate and store in 'output' the MD5 digest of 'len' bytes at + * 'input'. 'output' must have enough space to hold 16 bytes. + */ +void md5 (unsigned char *input, int len, unsigned char output[16]); + +#endif /* _MD5_H */ diff --git a/lib_generic/Makefile b/lib_generic/Makefile index b10793b..abee19a 100644 --- a/lib_generic/Makefile +++ b/lib_generic/Makefile @@ -36,6 +36,7 @@ COBJS-y += display_options.o COBJS-y += div64.o COBJS-y += lmb.o COBJS-y += ldiv.o +COBJS-$(CONFIG_MD5) += md5.o COBJS-y += sha1.o COBJS-y += string.o COBJS-y += vsprintf.o diff --git a/lib_generic/md5.c b/lib_generic/md5.c new file mode 100644 index 0000000..a51da45 --- /dev/null +++ b/lib_generic/md5.c @@ -0,0 +1,274 @@ +/* + * This file was transplanted with slight modifications from Linux sources + * (fs/cifs/md5.c) into U-Boot by Bartlomiej Sieka . + */ + +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +/* This code slightly modified to fit into Samba by + abartlet@samba.org Jun 2001 + and to fit the cifs vfs by + Steve French sfrench@us.ibm.com */ + +#include +#include +#include + +static void +MD5Transform(__u32 buf[4], __u32 const in[16]); + +/* + * Note: this code is harmless on little-endian machines. + */ +static void +byteReverse(unsigned char *buf, unsigned longs) +{ + __u32 t; + do { + t = (__u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(__u32 *) buf = t; + buf += 4; + } while (--longs); +} + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +static void +MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +static void +MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + register __u32 t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((__u32) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memmove(p, buf, len); + return; + } + memmove(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (__u32 *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memmove(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (__u32 *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memmove(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +static void +MD5Final(unsigned char digest[16], struct MD5Context *ctx) +{ + unsigned int count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (__u32 *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((__u32 *) ctx->in)[14] = ctx->bits[0]; + ((__u32 *) ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (__u32 *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memmove(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ +} + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +static void +MD5Transform(__u32 buf[4], __u32 const in[16]) +{ + register __u32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/* + * Calculate and store in 'output' the MD5 digest of 'len' bytes at + * 'input'. 'output' must have enough space to hold 16 bytes. + */ +void +md5 (unsigned char *input, int len, unsigned char output[16]) +{ + struct MD5Context context; + + MD5Init(&context); + MD5Update(&context, input, len); + MD5Final(output, &context); +} -- cgit v0.10.2 From 766529fccc860ecb9e955b4239dff69cd9e4ea09 Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Fri, 14 Mar 2008 16:22:34 +0100 Subject: Add MD5 support to the new uImage format Signed-off-by: Bartlomiej Sieka diff --git a/Makefile b/Makefile index c56518f..3bb8a74 100644 --- a/Makefile +++ b/Makefile @@ -2873,7 +2873,7 @@ clobber: clean @rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS \ $(obj)cscope.* $(obj)*.*~ @rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL) - @rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,sha1.c,inca-swap-bytes} + @rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,md5.c,sha1.c,inca-swap-bytes} @rm -f $(obj)tools/{image.c,fdt.c,fdt_ro.c,fdt_rw.c,fdt_strerror.c} @rm -f $(obj)tools/{fdt_wip.c,libfdt_internal.h} @rm -f $(obj)cpu/mpc824x/bedbug_603e.c diff --git a/common/image.c b/common/image.c index a2a739e..6508df9 100644 --- a/common/image.c +++ b/common/image.c @@ -54,6 +54,7 @@ #endif #if defined(CONFIG_FIT) +#include #include static int fit_check_ramdisk (const void *fit, int os_noffset, @@ -70,6 +71,7 @@ static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch, int verify); #else #include "mkimage.h" +#include #include #include #endif /* !USE_HOSTCC*/ @@ -1940,8 +1942,8 @@ static int calculate_hash (const void *data, int data_len, const char *algo, (unsigned char *) value); *value_len = 20; } else if (strcmp (algo, "md5") == 0 ) { - printf ("MD5 not supported\n"); - *value_len = 0; + md5 ((unsigned char *)data, data_len, value); + *value_len = 16; } else { debug ("Unsupported hash alogrithm\n"); return -1; diff --git a/include/image.h b/include/image.h index fbd8c30..f22dafd 100644 --- a/include/image.h +++ b/include/image.h @@ -64,6 +64,7 @@ #include #include #include +#define CONFIG_MD5 /* FIT images need MD5 support */ #endif /* diff --git a/tools/.gitignore b/tools/.gitignore index 0ce2e77..979f2da 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -4,6 +4,7 @@ /environment.c /gen_eth_addr /img2srec +/md5.c /mkimage /sha1.c /ubsha1 diff --git a/tools/Makefile b/tools/Makefile index aa4af18..9f0dedf 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -23,7 +23,7 @@ BIN_FILES = img2srec$(SFX) mkimage$(SFX) envcrc$(SFX) ubsha1$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX) -OBJ_LINKS = environment.o crc32.o sha1.o image.o +OBJ_LINKS = environment.o crc32.o md5.o sha1.o image.o OBJ_FILES = img2srec.o mkimage.o envcrc.o ubsha1.o gen_eth_addr.o bmp_logo.o ifeq ($(ARCH),mips) @@ -143,7 +143,7 @@ $(obj)img2srec$(SFX): $(obj)img2srec.o $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(STRIP) $@ -$(obj)mkimage$(SFX): $(obj)mkimage.o $(obj)crc32.o $(obj)image.o $(obj)sha1.o $(LIBFDT_OBJ_FILES) +$(obj)mkimage$(SFX): $(obj)mkimage.o $(obj)crc32.o $(obj)image.o $(obj)md5.o $(obj)sha1.o $(LIBFDT_OBJ_FILES) $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(STRIP) $@ @@ -176,6 +176,9 @@ $(obj)ubsha1.o: $(src)ubsha1.c $(obj)crc32.o: $(obj)crc32.c $(CC) -g $(CFLAGS) -c -o $@ $< +$(obj)md5.o: $(obj)md5.c + $(CC) -g $(CFLAGS) -c -o $@ $< + $(obj)sha1.o: $(obj)sha1.c $(CC) -g $(CFLAGS) -c -o $@ $< @@ -237,6 +240,10 @@ $(obj)crc32.c: @rm -f $(obj)crc32.c ln -s $(src)../lib_generic/crc32.c $(obj)crc32.c +$(obj)md5.c: + @rm -f $(obj)md5.c + ln -s $(src)../lib_generic/md5.c $(obj)md5.c + $(obj)sha1.c: @rm -f $(obj)sha1.c ln -s $(src)../lib_generic/sha1.c $(obj)sha1.c -- cgit v0.10.2 From 5e339fd9ed539a7d7fec59cfc88f0857ab26a53f Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Wed, 19 Mar 2008 10:00:06 +0100 Subject: [new uImage] Fix style issue spotted by Wolfgang Denk Signed-off-by: Bartlomiej Sieka diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c index 5311e12..46110cc 100644 --- a/board/trab/auto_update.c +++ b/board/trab/auto_update.c @@ -218,14 +218,12 @@ au_check_cksum_valid(int idx, long nbytes) } #endif - if (nbytes != image_get_image_size (hdr)) - { + if (nbytes != image_get_image_size (hdr)) { printf ("Image %s bad total SIZE\n", aufile[idx]); return -1; } /* check the data CRC */ - if (!image_check_dcrc (hdr)) - { + if (!image_check_dcrc (hdr)) { printf ("Image %s bad data checksum\n", aufile[idx]); return -1; } @@ -255,13 +253,11 @@ au_check_header_valid(int idx, long nbytes) printf("size %#x %#lx ", image_get_data_size (hdr), nbytes); printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL); #endif - if (nbytes < image_get_header_size ()) - { + if (nbytes < image_get_header_size ()) { printf ("Image %s bad header SIZE\n", aufile[idx]); return -1; } - if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_ARM)) - { + if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_ARM)) { printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]); return -1; } @@ -271,7 +267,8 @@ au_check_header_valid(int idx, long nbytes) return -1; } /* check the type - could do this all in one gigantic if() */ - if ((idx == IDX_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) { + if ((idx == IDX_FIRMWARE) && + !image_check_type (hdr, IH_TYPE_FIRMWARE)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } @@ -289,8 +286,7 @@ au_check_header_valid(int idx, long nbytes) return -1; } if ((idx == IDX_PREPARE || idx == IDX_PREINST || idx == IDX_POSTINST) - && !image_check_type (hdr, IH_TYPE_SCRIPT)) - { + && !image_check_type (hdr, IH_TYPE_SCRIPT)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } -- cgit v0.10.2 From 43142e817f0597be412e7cbe19413f5532eafa5d Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Thu, 20 Mar 2008 23:10:19 +0100 Subject: [new uImage] Fix *.its files location in documentation Signed-off-by: Bartlomiej Sieka diff --git a/doc/uImage.FIT/howto.txt b/doc/uImage.FIT/howto.txt index 35ab97d..4ae5303 100644 --- a/doc/uImage.FIT/howto.txt +++ b/doc/uImage.FIT/howto.txt @@ -49,10 +49,11 @@ Consider a simple scenario, where a PPC Linux kernel built from sources on the development host is to be booted old-style (non-FDT) by U-Boot on an embedded target. Assume that the outcome of the build is vmlinux.bin.gz, a file which contains a gzip-compressed PPC Linux kernel (the only data file in this case). -The uImage can be produced using the image source file examples/kernel.its -(note that kernel.its assumes that vmlinux.bin.gz is in the current working -directory; if desired, an alternative path can be specified in the kernel.its -file). Here's how to create the image and inspect its contents: +The uImage can be produced using the image source file +doc/uImage.FIT/kernel.its (note that kernel.its assumes that vmlinux.bin.gz is +in the current working directory; if desired, an alternative path can be +specified in the kernel.its file). Here's how to create the image and inspect +its contents: [on the host system] $ mkimage -f kernel.its kernel.itb @@ -159,10 +160,10 @@ Example 2 -- new-style (FDT) kernel booting Consider another simple scenario, where a PPC Linux kernel is to be booted new-style, i.e., with a FDT blob. In this case there are two prerequisite data files: vmlinux.bin.gz (Linux kernel) and target.dtb (FDT blob). The uImage can -be produced using image source file examples/kernel_fdt.its like this (note -again, that both prerequisite data files are assumed to be present in the -current working directory -- image source file kernel_fdt.its can be modified -to take the files from some other location if needed): +be produced using image source file doc/uImage.FIT/kernel_fdt.its like this +(note again, that both prerequisite data files are assumed to be present in +the current working directory -- image source file kernel_fdt.its can be +modified to take the files from some other location if needed): [on the host system] $ mkimage -f kernel_fdt.its kernel_fdt.itb @@ -292,5 +293,5 @@ Bytes transferred = 1109776 (10ef10 hex) Example 3 -- advanced booting ----------------------------- -Refer to examples/multi.its for an image source file that allows more +Refer to doc/uImage.FIT/multi.its for an image source file that allows more sophisticated booting scenarios (multiple kernels, ramdisks and fdt blobs). diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt index 3f7104f..1d75458 100644 --- a/doc/uImage.FIT/source_file_format.txt +++ b/doc/uImage.FIT/source_file_format.txt @@ -259,4 +259,4 @@ not* be specified in a configuration node. 8) Examples ----------- -Please see examples/*.its for actual image source files. +Please see doc/uImage.FIT/*.its for actual image source files. -- cgit v0.10.2 From 36cc8cbb3379d5166f882641123521735c469f92 Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Thu, 20 Mar 2008 23:10:19 +0100 Subject: [new uImage] Fix autoscr command used with new uImage format Signed-off-by: Bartlomiej Sieka diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c index 5163d57..1a37b90 100644 --- a/common/cmd_autoscript.c +++ b/common/cmd_autoscript.c @@ -100,6 +100,13 @@ autoscript (ulong addr, const char *fit_uname) puts ("Empty Script\n"); return 1; } + + /* + * scripts are just multi-image files with one component, seek + * past the zero-terminated sequence of image lengths to get + * to the actual image data + */ + while (*data++); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: @@ -155,8 +162,6 @@ autoscript (ulong addr, const char *fit_uname) return 1; } - while (*data++); - /* make sure cmd is null terminated */ memmove (cmd, (char *)data, len); *(cmd + len) = 0; -- cgit v0.10.2 From fbe7a155027beacebaee9b32e1ada781fe924bca Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Thu, 20 Mar 2008 19:38:45 +0100 Subject: [new uImage] Compilation and new uImage handling fixes for imxtract Fix imxtract command not being compiled-in despite CONFIG_CMD_XIMG being in include/config_cmd_default.h. Fix few warnings and handling of new format images. Signed-off-by: Bartlomiej Sieka diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index 77f68c4..7916fc1 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -24,7 +24,6 @@ * MA 02111-1307 USA */ -#if defined(CONFIG_CMD_XIMG) /* * Multi Image extract @@ -40,13 +39,12 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) ulong addr = load_addr; ulong dest = 0; ulong data, len, count; - int i, verify; + int verify; int part = 0; char pbuf[10]; - char *s; image_header_t *hdr; #if defined(CONFIG_FIT) - const char *uname; + const char *uname = NULL; const void* fit_hdr; int noffset; const void *fit_data; @@ -134,7 +132,7 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } /* get subimage node offset */ - noffset = fit_image_get_node (fit_hdr, fit_uname); + noffset = fit_image_get_node (fit_hdr, uname); if (noffset < 0) { printf ("Can't find '%s' FIT subimage\n", uname); return 1; @@ -160,7 +158,7 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 1; } - data = (ulong *)fit_data; + data = (ulong)fit_data; len = (ulong)fit_len; break; #endif @@ -190,5 +188,3 @@ U_BOOT_CMD(imxtract, 4, 1, do_imgextract, " - extract subimage from FIT image at and copy to \n" #endif ); - -#endif -- cgit v0.10.2 From dafaede8a46c7159310239e036c93e31c6374487 Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Thu, 20 Mar 2008 23:20:31 +0100 Subject: [new uImage] Disable debuging output in preparation for merge with master Signed-off-by: Bartlomiej Sieka diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 2f232e7..789ee03 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -21,7 +21,6 @@ * MA 02111-1307 USA */ -#define DEBUG /* * Boot support diff --git a/common/image.c b/common/image.c index 6508df9..f04826a 100644 --- a/common/image.c +++ b/common/image.c @@ -23,7 +23,6 @@ * MA 02111-1307 USA */ -#define DEBUG #ifndef USE_HOSTCC #include diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index 8cdace2..89463e3 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -23,7 +23,6 @@ * MA 02111-1307 USA */ -#define DEBUG #include #include -- cgit v0.10.2 From 95f4ec2b9c910c7261e6f060ea530d58b039692d Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Thu, 20 Mar 2008 23:23:13 +0100 Subject: [new uImage] Do not compile new uImage format support by default Disable default building of new uImage format support in preparation for merge with the master. Support for new format can be enabled on a per-board basis, by defining the following in the board's config file: #define CONFIG_FIT 1 #define CONFIG_OF_LIBFDT 1 This can be optionally defined to give more verbose output: #define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ Signed-off-by: Bartlomiej Sieka diff --git a/include/image.h b/include/image.h index f22dafd..36143e2 100644 --- a/include/image.h +++ b/include/image.h @@ -41,12 +41,6 @@ #include #include -/* new uImage format support enabled on target - * To be moved to board configuration file */ -#define CONFIG_FIT 1 -#define CONFIG_OF_LIBFDT 1 -#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ - #else /* new uImage format support enabled on host */ -- cgit v0.10.2 From 388b82fddc7c05596f3f615f190da0448227dc82 Mon Sep 17 00:00:00 2001 From: Bartlomiej Sieka Date: Thu, 20 Mar 2008 23:23:13 +0100 Subject: [new uImage] Enable new uImage support for the pcs440ep board. Signed-off-by: Bartlomiej Sieka diff --git a/include/configs/pcs440ep.h b/include/configs/pcs440ep.h index 893924b..ba6d932 100644 --- a/include/configs/pcs440ep.h +++ b/include/configs/pcs440ep.h @@ -27,6 +27,12 @@ #ifndef __CONFIG_H #define __CONFIG_H + +/* new uImage format support */ +#define CONFIG_FIT 1 +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ + /*----------------------------------------------------------------------- * High Level Configuration Options *----------------------------------------------------------------------*/ -- cgit v0.10.2