static int do_bootm_rtems (int flag, int argc, char *argv[], bootm_headers_t *images) { void (*entry_point)(bd_t *); if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { fit_unsupported_reset ("RTEMS"); return 1; } #endif entry_point = (void (*)(bd_t *))images->ep; printf ("## Transferring control to RTEMS (at address %08lx) ...\n", (ulong)entry_point); show_boot_progress (15); /* * RTEMS Parameters: * r3: ptr to board info data */ (*entry_point)(gd->bd); return 1; }
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { void (*theKernel)(int magic, void *tagtable); struct tag *params, *params_start; char *commandline = getenv("bootargs"); int ret; theKernel = (void *)images->ep; 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 (images->rd_start) { params = setup_ramdisk_tag(params, PHYSADDR(images->rd_start), PHYSADDR(images->rd_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); /* does not return */ error: return 1; }
int mv_load_fpga(void) { int result; size_t data_size = 0; void *fpga_data = NULL; char *datastr = getenv("fpgadata"); char *sizestr = getenv("fpgadatasize"); if (getenv("skip_fpga")) { printf("found 'skip_fpga' -> FPGA _not_ loaded !\n"); return -1; } printf("loading FPGA\n"); if (datastr) fpga_data = (void *)simple_strtoul(datastr, NULL, 16); if (sizestr) data_size = (size_t)simple_strtoul(sizestr, NULL, 16); if (!data_size) { printf("fpgadatasize invalid -> FPGA _not_ loaded !\n"); return -1; } result = fpga_load(0, fpga_data, data_size); if (!result) show_boot_progress(0); return result; }
void env_relocate (void) { #if defined (CONFIG_VLSI_EMULATOR) set_default_env("!For emulator speed up"); #else #if defined(CONFIG_NEEDS_MANUAL_RELOC) extern void env_reloc(void); env_reloc(); #endif if (gd->env_valid == 0) { #if defined(CONFIG_ENV_IS_NOWHERE) /* Environment not changable */ set_default_env(NULL); #else show_boot_progress (-60); set_default_env("!bad CRC"); #endif } else { env_relocate_spec (); } #endif //#if !defined (CONFIG_VLSI_EMULATOR) #if defined(CONFIG_SILENT_CONSOLE) && \ defined(CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC) if (getenv("silent") != NULL) { puts("silenced by env\n"); gd->flags |= GD_FLG_SILENT; } else { gd->flags &= ~GD_FLG_SILENT; } #endif }
static int do_bootm_integrity (int flag, int argc, char *argv[], bootm_headers_t *images) { void (*entry_point)(void); if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { fit_unsupported_reset ("INTEGRITY"); return 1; } #endif entry_point = (void (*)(void))images->ep; printf ("## Transferring control to INTEGRITY (at address %08lx) ...\n", (ulong)entry_point); show_boot_progress (15); /* * INTEGRITY Parameters: * None */ (*entry_point)(); return 1; }
ulong bootstage_add_record(enum bootstage_id id, const char *name, int flags, ulong mark) { struct bootstage_data *data = gd->bootstage; struct bootstage_record *rec; /* * initf_bootstage() is called very early during boot but since hang() * calls bootstage_error() we can be called before bootstage is set up. * Add a check to avoid this. */ if (!data) return mark; if (flags & BOOTSTAGEF_ALLOC) id = data->next_id++; /* Only record the first event for each */ rec = find_id(data, id); if (!rec && data->rec_count < RECORD_COUNT) { rec = &data->record[data->rec_count++]; rec->time_us = mark; rec->name = name; rec->flags = flags; rec->id = id; } /* Tell the board about this progress */ show_boot_progress(flags & BOOTSTAGEF_ERROR ? -id : id); return mark; }
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) { /* First parameter is mapped to $r5 for kernel boot args */ void (*theKernel) (char *, ulong, ulong); char *commandline = getenv ("bootargs"); ulong rd_data_start, rd_data_end; if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1; int ret; char *of_flat_tree = NULL; #if defined(CONFIG_OF_LIBFDT) ulong of_size = 0; /* find flattened device tree */ ret = boot_get_fdt (flag, argc, argv, images, &of_flat_tree, &of_size); if (ret) return 1; #endif theKernel = (void (*)(char *, ulong, ulong))images->ep; /* find ramdisk */ ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_MICROBLAZE, &rd_data_start, &rd_data_end); if (ret) return 1; show_boot_progress (15); if (!(ulong) of_flat_tree) of_flat_tree = (char *)simple_strtoul (argv[3], NULL, 16); #ifdef DEBUG printf ("## Transferring control to Linux (at address 0x%08lx) " \ "ramdisk 0x%08lx, FDT 0x%08lx...\n", (ulong) theKernel, rd_data_start, (ulong) of_flat_tree); #endif #ifdef XILINX_USE_DCACHE #ifdef XILINX_DCACHE_BYTE_SIZE flush_cache(0, XILINX_DCACHE_BYTE_SIZE); #else #warning please rebuild BSPs and update configuration flush_cache(0, 32768); #endif #endif /* * Linux Kernel Parameters (passing device tree): * r5: pointer to command line * r6: pointer to ramdisk * r7: pointer to the fdt, followed by the board info data */ theKernel (commandline, rd_data_start, (ulong) of_flat_tree); /* does not return */ return 1; }
void hang(void) { puts("### ERROR ### Please RESET the board ###\n"); #ifdef CONFIG_SHOW_BOOT_PROGRESS show_boot_progress(-30); #endif for (;;) ; }
void env_relocate (void) { unsigned char initEthAddr = 0; DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__, gd->reloc_off); #ifdef CONFIG_AMIGAONEG3SE enable_nvram(); #endif #ifdef ENV_IS_EMBEDDED /* * The environment buffer is embedded with the text segment, * just relocate the environment pointer */ env_ptr = (env_t *)((ulong)env_ptr + gd->reloc_off); DEBUGF ("%s[%d] embedded ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); #else /* * We must allocate a buffer for the environment */ env_ptr = (env_t *)malloc (CONFIG_ENV_SIZE); DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); #endif if (gd->env_valid == 0) { #if defined(CONFIG_GTH) || defined(CONFIG_ENV_IS_NOWHERE) /* Environment not changable */ puts ("Using default environment\n\n"); #else puts ("*** Warning - bad CRC, using default environment\n\n"); show_boot_progress (-60); #endif set_default_env(); initEthAddr = 1; } else { env_relocate_spec (); } gd->env_addr = (ulong)&(env_ptr->data); #ifdef CONFIG_AMIGAONEG3SE disable_nvram(); #endif if (initEthAddr) { const char * ethaddr = getenv("ethaddr"); if (ethaddr == 0L) { extern const char * env_read_backup_mac(void ); ethaddr = env_read_backup_mac(); if (ethaddr != 0L && strlen(ethaddr) == 17) { setenv("ethaddr", ethaddr); } } } }
void env_relocate (void) { DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__, gd->reloc_off); #ifdef CONFIG_AMIGAONEG3SE enable_nvram(); #endif #ifdef ENV_IS_EMBEDDED /* * The environment buffer is embedded with the text segment, * just relocate the environment pointer */ env_ptr = (env_t *)((ulong)env_ptr + gd->reloc_off); DEBUGF ("%s[%d] embedded ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); #else /* * We must allocate a buffer for the environment */ env_ptr = (env_t *)malloc (CFG_ENV_SIZE); DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); #endif /* * After relocation to RAM, we can always use the "memory" functions */ env_get_char = env_get_char_memory; if (gd->env_valid == 0) { #if defined(CONFIG_GTH) || defined(CFG_ENV_IS_NOWHERE) /* Environment not changable */ puts ("Using default environment\n\n"); #else puts ("*** Warning - bad CRC, using default environment\n\n"); show_boot_progress (-60); #endif } #ifdef CFG_PREBOOT_OVERRIDE if (preboot_override) gd->env_valid = 0; #endif if (gd->env_valid == 0) default_env(); else { env_relocate_spec (); } gd->env_addr = (ulong)&(env_ptr->data); #ifdef CONFIG_AMIGAONEG3SE disable_nvram(); #endif }
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"); 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; }
/** * 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 * * image_get_kernel() verifies legacy image integrity and returns pointer to * legacy image header if image verification was completed successfully. * * returns: * 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) { 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; } #if defined(CONFIG_MX51_BBG) || defined(CONFIG_MX51_3DS) if (image_get_load(hdr) < 0x90000000) image_set_load(hdr, image_get_load(hdr)+0x20000000); if (image_get_ep(hdr) < 0x90000000) image_set_ep(hdr, image_get_ep(hdr)+0x20000000); #endif #if defined(CONFIG_MX6SL) if (image_get_load(hdr) < 0x80000000) image_set_load(hdr, image_get_load(hdr)+0x70000000); if (image_get_ep(hdr) < 0x80000000) image_set_ep(hdr, image_get_ep(hdr)+0x70000000); #endif 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; }
void env_relocate (void) { if (gd->env_valid == 0) { puts ("*** Warning - bad CRC, using default environment\n\n"); show_boot_progress (-60); set_default_env(); } else { env_relocate_spec (); } gd->env_addr = (ulong)&(env_ptr->data); }
void env_relocate(void) { #if defined(CONFIG_NEEDS_MANUAL_RELOC) env_reloc(); #endif if (gd->env_valid == 0) { #if defined(CONFIG_ENV_IS_NOWHERE) /* Environment not changable */ set_default_env(NULL); #else show_boot_progress(-60); set_default_env("!bad CRC"); #endif } else { env_relocate_spec(); } }
void env_relocate (void) { DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__, gd->reloc_off); #ifdef CONFIG_AMIGAONEG3SE enable_nvram(); #endif #ifdef ENV_IS_EMBEDDED /* * The environment buffer is embedded with the text segment, * just relocate the environment pointer */ env_ptr = (env_t *)((ulong)env_ptr + gd->reloc_off); DEBUGF ("%s[%d] embedded ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); #else /* * We must allocate a buffer for the environment */ env_ptr = (env_t *)malloc (CONFIG_ENV_SIZE); DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); #endif if (gd->env_valid == 0) { #if defined(CONFIG_GTH) || defined(CONFIG_ENV_IS_NOWHERE) /* Environment not changable */ puts ("Using default environment\n\n"); #else puts ("*** Warning - bad CRC, using default environment\n\n"); show_boot_progress (-60); #endif set_default_env(); } else { env_relocate_spec (); } gd->env_addr = (ulong)&(env_ptr->data); //#if defined(CONFIG_ARCH_NS2816_DEMO) gd->bd->bi_env = gd->env_addr; //#endif #ifdef CONFIG_AMIGAONEG3SE disable_nvram(); #endif }
void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { /* First parameter is mapped to $r5 for kernel boot args */ void (*theKernel) (char *); char *commandline = getenv ("bootargs"); 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) { 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"); goto error; } theKernel = (void (*)(char *))ep; show_boot_progress (15); #ifdef DEBUG printf ("## Transferring control to Linux (at address %08lx) ...\n", (ulong) theKernel); #endif if (!images->autostart) return ; theKernel (commandline); /* does not return */ return; error: if (images->autostart) do_reset (cmdtp, flag, argc, argv); return; }
ulong bootstage_add_record(enum bootstage_id id, const char *name, int flags, ulong mark) { struct bootstage_record *rec; if (flags & BOOTSTAGEF_ALLOC) id = next_id++; if (id < BOOTSTAGE_ID_COUNT) { rec = &record[id]; /* Only record the first event for each */ if (!rec->time_us) { rec->time_us = mark; rec->name = name; rec->flags = flags; rec->id = id; } } /* Tell the board about this progress */ show_boot_progress(flags & BOOTSTAGEF_ERROR ? -id : id); return mark; }
/** * 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 * * image_get_kernel() verifies legacy image integrity and returns pointer to * legacy image header if image verification was completed successfully. * * returns: * 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) { 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; }
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong iflag; ulong load_end = 0; int ret; boot_os_fn *boot_fn; /* relocate boot function table */ if (!relocated) { int i; for (i = 0; i < ARRAY_SIZE(boot_os); i++) if (boot_os[i] != NULL) boot_os[i] += gd->reloc_off; relocated = 1; } /* determine if we have a sub command */ if (argc > 1) { char *endp; simple_strtoul(argv[1], &endp, 16); /* endp pointing to NULL means that argv[1] was just a * valid number, pass it along to the normal bootm processing * * If endp is ':' or '#' assume a FIT identifier so pass * along for normal processing. * * Right now we assume the first arg should never be '-' */ if ((*endp != 0) && (*endp != ':') && (*endp != '#')) return do_bootm_subcommand(cmdtp, flag, argc, argv); } if (bootm_start(cmdtp, flag, argc, argv)) return 1; /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ iflag = disable_interrupts(); #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the * SDRAM while Linux is booting. This could happen (at least for OHCI * controller), because the HCCA (Host Controller Communication Area) * lies within the SDRAM and the host controller writes continously to * this area (as busmaster!). The HccaFrameNumber is for example * updated every 1 ms within the HCCA structure in SDRAM! For more * details see the OpenHCI specification. */ usb_stop(); #endif #ifdef CONFIG_AMIGAONEG3SE /* * We've possible left the caches enabled during * bios emulation, so turn them off again */ icache_disable(); dcache_disable(); #endif ret = bootm_load_os(images.os, &load_end, 1); if (ret < 0) { if (ret == BOOTM_ERR_RESET) do_reset (cmdtp, flag, argc, argv); if (ret == BOOTM_ERR_OVERLAP) { if (images.legacy_hdr_valid) { if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI) puts ("WARNING: legacy format multi component " "image overwritten\n"); } else { puts ("ERROR: new format image overwritten - " "must RESET the board to recover\n"); show_boot_progress (-113); do_reset (cmdtp, flag, argc, argv); } } if (ret == BOOTM_ERR_UNIMPLEMENTED) { if (iflag) enable_interrupts(); show_boot_progress (-7); return 1; } } lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); if (images.os.type == IH_TYPE_STANDALONE) { if (iflag) enable_interrupts(); /* This may return when 'autostart' is 'no' */ bootm_start_standalone(iflag, argc, argv); return 0; } show_boot_progress (8); #ifdef CONFIG_SILENT_CONSOLE if (images.os.os == IH_OS_LINUX) fixup_silent_linux(); #endif boot_fn = boot_os[images.os.os]; if (boot_fn == NULL) { if (iflag) enable_interrupts(); printf ("ERROR: booting os '%s' (%d) is not supported\n", genimg_get_os_name(images.os.os), images.os.os); show_boot_progress (-8); return 1; } boot_fn(0, argc, argv, &images); show_boot_progress (-9); #ifdef DEBUG puts ("\n## Control returned to monitor - resetting...\n"); #endif do_reset (cmdtp, flag, argc, argv); return 1; }
static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress) { uint8_t comp = os.comp; ulong load = os.load; ulong blob_start = os.start; ulong blob_end = os.end; ulong image_start = os.image_start; ulong image_len = os.image_len; uint unc_len = CONFIG_SYS_BOOTM_LEN; const char *type_name = genimg_get_type_name (os.type); switch (comp) { case IH_COMP_NONE: if (load == blob_start) { printf (" XIP %s ... ", type_name); } else { printf (" Loading %s ... ", type_name); if (load != image_start) { memmove_wd ((void *)load, (void *)image_start, image_len, CHUNKSZ); } } *load_end = load + image_len; puts("OK\n"); break; case IH_COMP_GZIP: printf (" Uncompressing %s ... ", type_name); if (gunzip ((void *)load, unc_len, (uchar *)image_start, &image_len) != 0) { puts ("GUNZIP: uncompress, out-of-mem or overwrite error " "- must RESET board to recover\n"); if (boot_progress) show_boot_progress (-6); return BOOTM_ERR_RESET; } *load_end = load + image_len; break; #ifdef CONFIG_BZIP2 case IH_COMP_BZIP2: printf (" Uncompressing %s ... ", type_name); /* * If we've got less than 4 MB of malloc() space, * use slower decompression algorithm which requires * at most 2300 KB of memory. */ int i = BZ2_bzBuffToBuffDecompress ((char*)load, &unc_len, (char *)image_start, image_len, CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { printf ("BUNZIP2: uncompress or overwrite error %d " "- must RESET board to recover\n", i); if (boot_progress) show_boot_progress (-6); return BOOTM_ERR_RESET; } *load_end = load + unc_len; break; #endif /* CONFIG_BZIP2 */ #ifdef CONFIG_LZMA case IH_COMP_LZMA: printf (" Uncompressing %s ... ", type_name); int ret = lzmaBuffToBuffDecompress( (unsigned char *)load, &unc_len, (unsigned char *)image_start, image_len); if (ret != SZ_OK) { printf ("LZMA: uncompress or overwrite error %d " "- must RESET board to recover\n", ret); show_boot_progress (-6); return BOOTM_ERR_RESET; } *load_end = load + unc_len; break; #endif /* CONFIG_LZMA */ default: printf ("Unimplemented compression type %d\n", comp); return BOOTM_ERR_UNIMPLEMENTED; } puts ("OK\n"); debug (" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end); if (boot_progress) show_boot_progress (7); if ((load < blob_end) && (*load_end > blob_start)) { debug ("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end); debug ("images.os.load = 0x%lx, load_end = 0x%lx\n", load, *load_end); return BOOTM_ERR_OVERLAP; } return 0; }
static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong mem_start; phys_size_t mem_size; void *os_hdr; int ret; memset ((void *)&images, 0, sizeof (images)); images.verify = getenv_yesno ("verify"); lmb_init(&images.lmb); mem_start = getenv_bootm_low(); mem_size = getenv_bootm_size(); lmb_add(&images.lmb, (phys_addr_t)mem_start, mem_size); arch_lmb_reserve(&images.lmb); board_lmb_reserve(&images.lmb); /* get kernel image header, start address and length */ os_hdr = boot_get_kernel (cmdtp, flag, argc, argv, &images, &images.os.image_start, &images.os.image_len); if (images.os.image_len == 0) { puts ("ERROR: can't get kernel image!\n"); return 1; } /* get image parameters */ switch (genimg_get_format (os_hdr)) { case IMAGE_FORMAT_LEGACY: images.os.type = image_get_type (os_hdr); images.os.comp = image_get_comp (os_hdr); images.os.os = image_get_os (os_hdr); images.os.end = image_get_image_end (os_hdr); images.os.load = image_get_load (os_hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: if (fit_image_get_type (images.fit_hdr_os, images.fit_noffset_os, &images.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, &images.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, &images.os.os)) { puts ("Can't get image OS!\n"); show_boot_progress (-111); return 1; } images.os.end = fit_get_end (images.fit_hdr_os); if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os, &images.os.load)) { puts ("Can't get image load address!\n"); show_boot_progress (-112); return 1; } break; #endif default: puts ("ERROR: unknown image format type!\n"); return 1; } /* find kernel entry point */ if (images.legacy_hdr_valid) { images.ep = image_get_ep (&images.legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images.fit_uname_os) { ret = fit_image_get_entry (images.fit_hdr_os, images.fit_noffset_os, &images.ep); if (ret) { puts ("Can't get entry point property!\n"); return 1; } #endif } else { puts ("Could not find kernel entry point!\n"); return 1; } if (images.os.os == IH_OS_LINUX) { /* find ramdisk */ ret = boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH, &images.rd_start, &images.rd_end); if (ret) { puts ("Ramdisk image is corrupt or invalid\n"); return 1; } #if defined(CONFIG_OF_LIBFDT) #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) /* find flattened device tree */ ret = boot_get_fdt (flag, argc, argv, &images, &images.ft_addr, &images.ft_len); if (ret) { puts ("Could not find a valid device tree\n"); return 1; } set_working_fdt_addr(images.ft_addr); #endif #endif } images.os.start = (ulong)os_hdr; images.state = BOOTM_STATE_START; return 0; }
static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress) { uint8_t comp = os.comp; ulong load = os.load; ulong blob_start = os.start; ulong blob_end = os.end; ulong image_start = os.image_start; ulong image_len = os.image_len; #if defined(CONFIG_GZIP) || defined(CONFIG_BZIP2) \ || defined(CONFIG_LZMA) || defined(CONFIG_LZO) uint unc_len = CONFIG_SYS_BOOTM_LEN; #endif ulong image_end; const char *type_name = genimg_get_type_name (os.type); int boot_sp; __asm__ __volatile__( "mov %0, sp\n" :"=r"(boot_sp) : :"cc" ); /* Check whether kernel zImage overwrite uboot, * which will lead to kernel boot fail. */ image_end = load + image_len; /* leave at most 32KByte for move image stack */ boot_sp -= BOOTM_STACK_GUARD; if( !((load > _bss_end) || (image_end < boot_sp)) ) { printf("\nkernel image will overwrite uboot! kernel boot fail!\n"); return BOOTM_ERR_RESET; } switch (comp) { case IH_COMP_NONE: if (load == blob_start || load == image_start) { printf (" XIP %s ... ", type_name); } else { printf (" Loading %s ... ", type_name); memmove_wd ((void *)load, (void *)image_start, image_len, CHUNKSZ); } *load_end = load + image_len; puts("OK\n"); break; #ifdef CONFIG_GZIP case IH_COMP_GZIP: printf (" Uncompressing %s ... ", type_name); if (gunzip ((void *)load, unc_len, (uchar *)image_start, &image_len) != 0) { puts ("GUNZIP: uncompress, out-of-mem or overwrite error " "- must RESET board to recover\n"); if (boot_progress) show_boot_progress (-6); return BOOTM_ERR_RESET; } *load_end = load + image_len; break; #endif /* CONFIG_GZIP */ #ifdef CONFIG_BZIP2 case IH_COMP_BZIP2: printf (" Uncompressing %s ... ", type_name); /* * If we've got less than 4 MB of malloc() space, * use slower decompression algorithm which requires * at most 2300 KB of memory. */ int i = BZ2_bzBuffToBuffDecompress ((char*)load, &unc_len, (char *)image_start, image_len, CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { printf ("BUNZIP2: uncompress or overwrite error %d " "- must RESET board to recover\n", i); if (boot_progress) show_boot_progress (-6); return BOOTM_ERR_RESET; } *load_end = load + unc_len; break; #endif /* CONFIG_BZIP2 */ #ifdef CONFIG_LZMA case IH_COMP_LZMA: printf (" Uncompressing %s ... ", type_name); int ret = lzmaBuffToBuffDecompress( (unsigned char *)load, &unc_len, (unsigned char *)image_start, image_len); if (ret != SZ_OK) { printf ("LZMA: uncompress or overwrite error %d " "- must RESET board to recover\n", ret); show_boot_progress (-6); return BOOTM_ERR_RESET; } *load_end = load + unc_len; break; #endif /* CONFIG_LZMA */ #ifdef CONFIG_LZO case IH_COMP_LZO: printf (" Uncompressing %s ... ", type_name); int ret = lzop_decompress((const unsigned char *)image_start, image_len, (unsigned char *)load, &unc_len); if (ret != LZO_E_OK) { printf ("LZO: uncompress or overwrite error %d " "- must RESET board to recover\n", ret); if (boot_progress) show_boot_progress (-6); return BOOTM_ERR_RESET; } *load_end = load + unc_len; break; #endif /* CONFIG_LZO */ default: printf ("Unimplemented compression type %d\n", comp); return BOOTM_ERR_UNIMPLEMENTED; } puts ("OK\n"); debug (" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end); if (boot_progress) show_boot_progress (7); if ((load < blob_end) && (*load_end > blob_start)) { debug ("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end); debug ("images.os.load = 0x%lx, load_end = 0x%lx\n", load, *load_end); return BOOTM_ERR_OVERLAP; } return 0; }
static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc, char * const argv[]) { char *s; char *end; int rcode = 0; int size; ulong addr; /* pre-set load_addr */ if ((s = getenv("loadaddr")) != NULL) { load_addr = simple_strtoul(s, NULL, 16); } switch (argc) { case 1: break; case 2: /* * Only one arg - accept two forms: * Just load address, or just boot file name. The latter * form must be written in a format which can not be * mis-interpreted as a valid number. */ addr = simple_strtoul(argv[1], &end, 16); if (end == (argv[1] + strlen(argv[1]))) load_addr = addr; else copy_filename(BootFile, argv[1], sizeof(BootFile)); break; case 3: load_addr = simple_strtoul(argv[1], NULL, 16); copy_filename (BootFile, argv[2], sizeof(BootFile)); break; #ifdef CONFIG_CMD_TFTPPUT case 4: save_addr = strict_strtoul(argv[1], NULL, 16); save_size = strict_strtoul(argv[2], NULL, 16); copy_filename(BootFile, argv[3], sizeof(BootFile)); break; #endif default: show_boot_progress (-80); return cmd_usage(cmdtp); } show_boot_progress (80); if ((size = NetLoop(proto)) < 0) { show_boot_progress (-81); return 1; } show_boot_progress (81); /* NetLoop ok, update environment */ netboot_update_env(); /* done if no file was loaded (no errors though) */ if (size == 0) { show_boot_progress (-82); return 0; } /* flush cache */ flush_cache(load_addr, size); show_boot_progress(82); rcode = bootm_maybe_autostart(cmdtp, argv[0]); if (rcode < 0) show_boot_progress (-83); else show_boot_progress (84); return rcode; }
int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *boot_device = NULL; char *ep; int dev; ulong cnt; ulong addr; ulong offset = 0; image_header_t *hdr; int rcode = 0; #if defined(CONFIG_FIT) const void *fit_hdr = NULL; #endif show_boot_progress (34); switch (argc) { case 1: addr = CONFIG_SYS_LOAD_ADDR; boot_device = getenv ("bootdevice"); break; case 2: addr = simple_strtoul(argv[1], NULL, 16); boot_device = getenv ("bootdevice"); break; case 3: addr = simple_strtoul(argv[1], NULL, 16); boot_device = argv[2]; break; case 4: addr = simple_strtoul(argv[1], NULL, 16); boot_device = argv[2]; offset = simple_strtoul(argv[3], NULL, 16); break; default: cmd_usage(cmdtp); show_boot_progress (-35); return 1; } show_boot_progress (35); if (!boot_device) { puts ("\n** No boot device **\n"); show_boot_progress (-36); return 1; } show_boot_progress (36); dev = simple_strtoul(boot_device, &ep, 16); if ((dev >= CONFIG_SYS_MAX_DOC_DEVICE) || (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN)) { printf ("\n** Device %d not available\n", dev); show_boot_progress (-37); return 1; } show_boot_progress (37); printf ("\nLoading from device %d: %s at 0x%lX (offset 0x%lX)\n", dev, doc_dev_desc[dev].name, doc_dev_desc[dev].physadr, offset); if (doc_rw (doc_dev_desc + dev, 1, offset, SECTORSIZE, NULL, (u_char *)addr)) { printf ("** Read error on %d\n", dev); show_boot_progress (-38); return 1; } show_boot_progress (38); switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; image_print_contents (hdr); cnt = image_get_image_size (hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: fit_hdr = (const void *)addr; 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); show_boot_progress (-40); return 1; } 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) { if (!fit_check_format (fit_hdr)) { show_boot_progress (-130); puts ("** Bad FIT image format\n"); return 1; } show_boot_progress (131); fit_print_contents (fit_hdr); } #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]; extern int do_bootm (cmd_tbl_t *, int, int, char *[]); local_args[0] = argv[0]; local_args[1] = NULL; printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); do_bootm (cmdtp, 0, 1, local_args); rcode = 1; } return rcode; }
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { struct bp_tag *params, *params_start; ulong initrd_start, initrd_end; char *commandline = env_get("bootargs"); if (!(flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO))) return 0; show_boot_progress(15); if (images->rd_start) { initrd_start = images->rd_start; initrd_end = images->rd_end; } else { initrd_start = 0; initrd_end = 0; } params_start = (struct bp_tag *)gd->bd->bi_boot_params; params = params_start; params = setup_first_tag(params); params = setup_memory_tag(params); params = setup_commandline_tag(params, commandline); params = setup_serial_tag(params); if (initrd_start) params = setup_ramdisk_tag(params, initrd_start, initrd_end); #ifdef CONFIG_OF_LIBFDT if (images->ft_addr) params = setup_fdt_tag(params, images->ft_addr); #endif printf("\n"); params = setup_last_tag(params); show_boot_progress(15); printf("Transferring Control to Linux @0x%08lx ...\n\n", (ulong)images->ep); flush_dcache_range((unsigned long)params_start, (unsigned long)params); if (flag & BOOTM_STATE_OS_FAKE_GO) return 0; /* * _start() in vmlinux expects boot params in register a2. * NOTE: * Disable/delete your u-boot breakpoints before stepping into linux. */ asm volatile ("mov a2, %0\n\t" "jx %1\n\t" : : "a" (params_start), "a" (images->ep) : "a2"); /* Does not return */ return 1; }
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { 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 if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1; theKernel = (void (*)(int, int, uint))images->ep; s = getenv ("machid"); if (s) { machid = simple_strtoul (s, NULL, 16); printf ("Using machid 0x%x from environment\n", machid); } 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 (images->rd_start && images->rd_end) setup_initrd_tag (bd, images->rd_start, images->rd_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, machid, bd->bi_boot_params); /* does not return */ return 1; }
/** * 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 * * 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 *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; ulong img_addr; #if defined(CONFIG_FIT) void *fit_hdr; const char *fit_uname_config = NULL; const char *fit_uname_kernel = NULL; const void *data; size_t len; int cfg_noffset; int os_noffset; #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); /* 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: 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); *os_len = image_get_data_size (hdr); break; case IH_TYPE_MULTI: image_multi_getimg (hdr, 0, os_data, os_len); break; case IH_TYPE_STANDALONE: if (argc >2) { hdr->ih_load = htonl(simple_strtoul(argv[2], NULL, 16)); } *os_data = image_get_data (hdr); *os_len = image_get_data_size (hdr); break; default: printf ("Wrong Image Type for %s command\n", cmdtp->name); show_boot_progress (-5); return NULL; } /* * copy image header to allow for image overwrites during kernel * decompression. */ memmove (&images->legacy_hdr_os_copy, hdr, sizeof(image_header_t)); /* save pointer to image header */ images->legacy_hdr_os = hdr; images->legacy_hdr_valid = 1; show_boot_progress (6); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: fit_hdr = (void *)img_addr; printf ("## Booting kernel from FIT Image at %08lx ...\n", img_addr); 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) { /* * 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 */ show_boot_progress (101); 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, cfg_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) { 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; images->fit_hdr_os = fit_hdr; images->fit_uname_os = fit_uname_kernel; images->fit_noffset_os = os_noffset; break; #endif default: printf ("Wrong Image Format for %s command\n", cmdtp->name); show_boot_progress (-108); return NULL; } debug (" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", *os_data, *os_len, *os_len); return (void *)img_addr; }
static int do_bootm_netbsd (int flag, int argc, char *argv[], bootm_headers_t *images) { void (*loader)(bd_t *, image_header_t *, char *, char *); image_header_t *os_hdr, *hdr; ulong kernel_data, kernel_len; char *consdev; char *cmdline; if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { fit_unsupported_reset ("NetBSD"); return 1; } #endif hdr = images->legacy_hdr_os; /* * 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. */ os_hdr = NULL; if (image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) { image_multi_getimg (hdr, 1, &kernel_data, &kernel_len); if (kernel_len) os_hdr = hdr; } 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 *))images->ep; 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, os_hdr, consdev, cmdline); return 1; }
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images) { 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); int ret; #ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); #endif /* find kernel entry point */ if (images->legacy_hdr_valid) { ep = image_get_ep (&images->legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images->fit_uname_os) { ret = fit_image_get_entry (images->fit_hdr_os, 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"); goto error; } theKernel = (void (*)(int, int, uint))ep; s = getenv ("machid"); if (s) { machid = simple_strtoul (s, NULL, 16); printf ("Using machid 0x%x from environment\n", machid); } ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_ARM, &initrd_start, &initrd_end); if (ret) goto error; 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, machid, bd->bi_boot_params); /* does not return */ return; error: do_reset (cmdtp, flag, argc, argv); return; }
static int netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char * const argv[]) { char *s; char *end; int rcode = 0; int size; ulong addr; /* pre-set load_addr */ if ((s = getenv("loadaddr")) != NULL) { load_addr = simple_strtoul(s, NULL, 16); } switch (argc) { case 1: break; case 2: /* * Only one arg - accept two forms: * Just load address, or just boot file name. The latter * form must be written in a format which can not be * mis-interpreted as a valid number. */ addr = simple_strtoul(argv[1], &end, 16); /* use default loadaddr address is 0 */ if (!addr) addr = load_addr; else if (end == (argv[1] + strlen(argv[1]))) load_addr = addr; else copy_filename(BootFile, argv[1], sizeof(BootFile)); break; case 3: addr = simple_strtoul(argv[1], &end, 16); /* use default loadaddr address is 0 */ if (!addr) addr = load_addr; else if (end == (argv[1] + strlen(argv[1]))) load_addr = addr; copy_filename (BootFile, argv[2], sizeof(BootFile)); break; default: show_boot_progress (-80); return cmd_usage(cmdtp); } show_boot_progress (80); if ((size = NetLoop(proto)) < 0) { show_boot_progress (-81); return 1; } show_boot_progress (81); /* NetLoop ok, update environment */ netboot_update_env(); /* done if no file was loaded (no errors though) */ if (size == 0) { show_boot_progress (-82); return 0; } /* flush cache */ flush_cache(load_addr, size); /* Loading ok, check if we should attempt an auto-start */ if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) { char *local_args[2]; local_args[0] = argv[0]; local_args[1] = NULL; printf ("Automatic boot of image at addr 0x%08lX ...\n", load_addr); show_boot_progress (82); rcode = do_bootm (cmdtp, 0, 1, local_args); } if (rcode < 0) show_boot_progress (-83); else show_boot_progress (84); return rcode; }