static int do_unzip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long src, dst; unsigned long src_len = ~0UL, dst_len = ~0UL; switch (argc) { case 4: dst_len = simple_strtoul(argv[3], NULL, 16); /* fall through */ case 3: src = simple_strtoul(argv[1], NULL, 16); dst = simple_strtoul(argv[2], NULL, 16); break; default: return CMD_RET_USAGE; } if (gunzip((void *) dst, dst_len, (void *) src, &src_len) != 0) return 1; printf("Uncompressed size: %ld = 0x%lX\n", src_len, src_len); setenv_hex("filesize", src_len); setenv_hex("fileaddr", dst); return 0; }
void set_working_fdt_addr(ulong addr) { void *buf; buf = map_sysmem(addr, 0); working_fdt = buf; setenv_hex("fdtaddr", addr); }
static void nand_print_and_set_info(int idx) { nand_info_t *nand = &nand_info[idx]; struct nand_chip *chip = nand->priv; printf("Device %d: ", idx); if (chip->numchips > 1) printf("%dx ", chip->numchips); printf("%s, sector size %u KiB\n", nand->name, nand->erasesize >> 10); printf(" Page size %8d b\n", nand->writesize); printf(" OOB size %8d b\n", nand->oobsize); printf(" Erase size %8d b\n", nand->erasesize); /* Set geometry info */ setenv_hex("nand_writesize", nand->writesize); setenv_hex("nand_oobsize", nand->oobsize); setenv_hex("nand_erasesize", nand->erasesize); }
int misc_init_r(void) { #ifdef CONFIG_PREBOOT preboot_keys(); #endif #ifdef CONFIG_CMD_BMODE add_board_boot_modes(board_boot_modes); #endif setenv_hex("reset_cause", get_imx_reset_cause()); return 0; }
static int set_fdt_addr(void) { int ret; ret = setenv_hex("fdt_addr", nvtboot_boot_x0); if (ret) { printf("Failed to set fdt_addr to point at DTB: %d\n", ret); return ret; } return 0; }
/** * Routine implementing fsload u-boot command. This routine tries to load * a requested file from cramfs filesystem at location 'cramfsaddr'. * cramfsaddr is an evironment variable. * * @param cmdtp command internal data * @param flag command flag * @param argc number of arguments supplied to the command * @param argv arguments list * @return 0 on success, 1 otherwise */ int do_cramfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename; int size; ulong offset = load_addr; struct part_info part; struct mtd_device dev; struct mtdids id; ulong addr; addr = simple_strtoul(getenv("cramfsaddr"), NULL, 16); /* hack! */ /* cramfs_* only supports NOR flash chips */ /* fake the device type */ id.type = MTD_DEV_TYPE_NOR; id.num = 0; dev.id = &id; part.dev = &dev; /* fake the address offset */ part.offset = addr - OFFSET_ADJUSTMENT; /* pre-set Boot file name */ if ((filename = getenv("bootfile")) == NULL) { filename = "uImage"; } if (argc == 2) { filename = argv[1]; } if (argc == 3) { offset = simple_strtoul(argv[1], NULL, 0); load_addr = offset; filename = argv[2]; } size = 0; if (cramfs_check(&part)) size = cramfs_load ((char *) offset, &part, filename); if (size > 0) { printf("### CRAMFS load complete: %d bytes loaded to 0x%lx\n", size, offset); setenv_hex("filesize", size); } else { printf("### CRAMFS LOAD ERROR<%x> for %s!\n", size, filename); } return !(size > 0); }
static int bootm_start_standalone(ulong iflag, int argc, char * const argv[]) { char *s; int (*appl)(int, char * const []); /* Don't start if "autostart" is set to "no" */ if (((s = getenv("autostart")) != NULL) && (strcmp(s, "no") == 0)) { setenv_hex("filesize", images.os.image_len); return 0; } appl = (int (*)(int, char * const []))(ulong)ntohl(images.ep); (*appl)(argc-1, &argv[1]); return 0; }
int last_stage_init(void) { void *fdt = get_fdt_virt(); int len = 0; const uint64_t *prop; int chosen; chosen = fdt_path_offset(fdt, "/chosen"); if (chosen < 0) { printf("Couldn't find /chosen node in fdt\n"); return -EIO; } /* -kernel boot */ prop = fdt_getprop(fdt, chosen, "qemu,boot-kernel", &len); if (prop && (len >= 8)) setenv_hex("qemu_kernel_addr", *prop); /* Give the user a variable for the host fdt */ setenv_hex("fdt_addr_r", (ulong)fdt); return 0; }
static int do_bootm_standalone(int flag, int argc, char * const argv[], bootm_headers_t *images) { char *s; int (*appl)(int, char * const []); /* Don't start if "autostart" is set to "no" */ if (((s = getenv("autostart")) != NULL) && (strcmp(s, "no") == 0)) { setenv_hex("filesize", images->os.image_len); return 0; } appl = (int (*)(int, char * const []))images->ep; appl(argc, argv); return 0; }
/* Compat wrappers for common/cmd_ubifs.c */ int ubifs_load(char *filename, u32 addr, u32 size) { loff_t actread; int err; printf("Loading file '%s' to addr 0x%08x...\n", filename, addr); err = ubifs_read(filename, (void *)addr, 0, size, &actread); if (err == 0) { setenv_hex("filesize", actread); printf("Done\n"); } return err; }
int do_ubifs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename; char *endp; int ret; u32 addr; u32 size = 0; if (!ubifs_mounted) { printf("UBIFS not mounted, use ubifs mount to mount volume first!\n"); return -1; } if (argc < 3) return CMD_RET_USAGE; addr = simple_strtoul(argv[1], &endp, 16); if (addr == 0) addr = load_addr; if (endp == argv[1]) return CMD_RET_USAGE; filename = argv[2]; if (argc == 4) { size = simple_strtoul(argv[3], &endp, 16); if (endp == argv[3]) return CMD_RET_USAGE; } debug("Loading file '%s' to address 0x%08x (size %d)\n", filename, addr, size); ret = ubifs_load(filename, addr, size); if (ret) { printf("** File not found %s **\n", filename); ret = CMD_RET_FAILURE; } setenv_hex("fileaddr", addr); return ret; }
/****************************************************************************** * Reiserfs boot command intepreter. Derived from diskboot */ int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = NULL; int dev, part; ulong addr = 0, filelen; disk_partition_t info; block_dev_desc_t *dev_desc = NULL; unsigned long count; char *addr_str; switch (argc) { case 3: addr_str = getenv("loadaddr"); if (addr_str != NULL) { addr = simple_strtoul (addr_str, NULL, 16); } else { addr = CONFIG_SYS_LOAD_ADDR; } filename = getenv ("bootfile"); count = 0; break; case 4: addr = simple_strtoul (argv[3], NULL, 16); filename = getenv ("bootfile"); count = 0; break; case 5: addr = simple_strtoul (argv[3], NULL, 16); filename = argv[4]; count = 0; break; case 6: addr = simple_strtoul (argv[3], NULL, 16); filename = argv[4]; count = simple_strtoul (argv[5], NULL, 16); break; default: return CMD_RET_USAGE; } if (!filename) { puts ("\n** No boot file defined **\n"); return 1; } part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; dev = dev_desc->dev; printf("Loading file \"%s\" from %s device %d%c%c\n", filename, argv[1], dev, part ? ':' : ' ', part ? part + '0' : ' '); reiserfs_set_blk_dev(dev_desc, &info); if (!reiserfs_mount(info.size)) { printf ("** Bad Reiserfs partition or disk - %s %d:%d **\n", argv[1], dev, part); return 1; } filelen = reiserfs_open(filename); if (filelen < 0) { printf("** File not found %s **\n", filename); return 1; } if ((count < filelen) && (count != 0)) { filelen = count; } if (reiserfs_read((char *)addr, filelen) != filelen) { printf("\n** Unable to read \"%s\" from %s %d:%d **\n", filename, argv[1], dev, part); return 1; } /* Loading ok, update default load address */ load_addr = addr; printf ("\n%ld bytes read\n", filelen); setenv_hex("filesize", filelen); return filelen; }
static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int ret = 0; long state; cmd_tbl_t *c; boot_os_fn *boot_fn; c = find_cmd_tbl(argv[1], &cmd_bootm_sub[0], ARRAY_SIZE(cmd_bootm_sub)); if (c) { state = (long)c->cmd; /* treat start special since it resets the state machine */ if (state == BOOTM_STATE_START) { argc--; argv++; return bootm_start(cmdtp, flag, argc, argv); } } else { /* Unrecognized command */ return CMD_RET_USAGE; } if (images.state < BOOTM_STATE_START || images.state >= state) { printf("Trying to execute a command out of order\n"); return CMD_RET_USAGE; } images.state |= state; boot_fn = boot_os[images.os.os]; switch (state) { ulong load_end; case BOOTM_STATE_START: /* should never occur */ break; case BOOTM_STATE_LOADOS: ret = bootm_load_os(images.os, &load_end, 0); if (ret) return ret; lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); break; #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH case BOOTM_STATE_RAMDISK: { ulong rd_len = images.rd_end - images.rd_start; ret = boot_ramdisk_high(&images.lmb, images.rd_start, rd_len, &images.initrd_start, &images.initrd_end); if (ret) return ret; setenv_hex("initrd_start", images.initrd_start); setenv_hex("initrd_end", images.initrd_end); } break; #endif #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB) case BOOTM_STATE_FDT: { boot_fdt_add_mem_rsv_regions(&images.lmb, images.ft_addr); ret = boot_relocate_fdt(&images.lmb, &images.ft_addr, &images.ft_len); break; } #endif case BOOTM_STATE_OS_CMDLINE: ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, &images); if (ret) printf("cmdline subcommand not supported\n"); break; case BOOTM_STATE_OS_BD_T: ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, &images); if (ret) printf("bdt subcommand not supported\n"); break; case BOOTM_STATE_OS_PREP: ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, &images); if (ret) printf("prep subcommand not supported\n"); break; case BOOTM_STATE_OS_GO: disable_interrupts(); #ifdef CONFIG_NETCONSOLE /* * Stop the ethernet stack if NetConsole could have * left it up */ eth_halt(); #endif arch_preboot_os(); boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images); break; } return ret; }
/** * Execute selected states of the bootm command. * * Note the arguments to this state must be the first argument, Any 'bootm' * or sub-command arguments must have already been taken. * * Note that if states contains more than one flag it MUST contain * BOOTM_STATE_START, since this handles and consumes the command line args. * * Also note that aside from boot_os_fn functions and bootm_load_os no other * functions we store the return value of in 'ret' may use a negative return * value, without special handling. * * @param cmdtp Pointer to bootm command table entry * @param flag Command flags (CMD_FLAG_...) * @param argc Number of subcommand arguments (0 = no arguments) * @param argv Arguments * @param states Mask containing states to run (BOOTM_STATE_...) * @param images Image header information * @param boot_progress 1 to show boot progress, 0 to not do this * @return 0 if ok, something else on error. Some errors will cause this * function to perform a reboot! If states contains BOOTM_STATE_OS_GO * then the intent is to boot an OS, so this function will not return * unless the image type is standalone. */ static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], int states, bootm_headers_t *images, int boot_progress) { boot_os_fn *boot_fn; ulong iflag = 0; int ret = 0, need_boot_fn; images->state |= states; /* * Work through the states and see how far we get. We stop on * any error. */ if (states & BOOTM_STATE_START) ret = bootm_start(cmdtp, flag, argc, argv); if (!ret && (states & BOOTM_STATE_FINDOS)) ret = bootm_find_os(cmdtp, flag, argc, argv); if (!ret && (states & BOOTM_STATE_FINDOTHER)) { ret = bootm_find_other(cmdtp, flag, argc, argv); argc = 0; /* consume the args */ } /* Load the OS */ if (!ret && (states & BOOTM_STATE_LOADOS)) { ulong load_end; iflag = bootm_disable_interrupts(); ret = bootm_load_os(images, &load_end, 0); if (ret == 0) lmb_reserve(&images->lmb, images->os.load, (load_end - images->os.load)); else if (ret && ret != BOOTM_ERR_OVERLAP) goto err; else if (ret == BOOTM_ERR_OVERLAP) ret = 0; #if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) if (images->os.os == IH_OS_LINUX) fixup_silent_linux(); #endif } /* Relocate the ramdisk */ #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH if (!ret && (states & BOOTM_STATE_RAMDISK)) { ulong rd_len = images->rd_end - images->rd_start; ret = boot_ramdisk_high(&images->lmb, images->rd_start, rd_len, &images->initrd_start, &images->initrd_end); if (!ret) { setenv_hex("initrd_start", images->initrd_start); setenv_hex("initrd_end", images->initrd_end); } } #endif #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB) if (!ret && (states & BOOTM_STATE_FDT)) { boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); ret = boot_relocate_fdt(&images->lmb, &images->ft_addr, &images->ft_len); } #endif /* From now on, we need the OS boot function */ if (ret) return ret; boot_fn = boot_os[images->os.os]; need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE | BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO); if (boot_fn == NULL && need_boot_fn) { if (iflag) enable_interrupts(); printf("ERROR: booting os '%s' (%d) is not supported\n", genimg_get_os_name(images->os.os), images->os.os); bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS); return 1; } /* Call various other states that are not generally used */ if (!ret && (states & BOOTM_STATE_OS_CMDLINE)) ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images); if (!ret && (states & BOOTM_STATE_OS_BD_T)) ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images); if (!ret && (states & BOOTM_STATE_OS_PREP)) ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images); #ifdef CONFIG_TRACE /* Pretend to run the OS, then run a user command */ if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) { char *cmd_list = getenv("fakegocmd"); ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO, images, boot_fn); if (!ret && cmd_list) ret = run_command_list(cmd_list, -1, flag); } #endif /* Check for unsupported subcommand. */ if (ret) { puts("subcommand not supported\n"); return ret; } /* Now run the OS! We hope this doesn't return */ if (!ret && (states & BOOTM_STATE_OS_GO)) ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO, images, boot_fn); /* Deal with any fallout */ err: if (iflag) enable_interrupts(); if (ret == BOOTM_ERR_UNIMPLEMENTED) bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL); else if (ret == BOOTM_ERR_RESET) do_reset(cmdtp, flag, argc, argv); return ret; }
int net_loop(enum proto_t protocol) { int ret = -EINVAL; net_restarted = 0; net_dev_exists = 0; net_try_count = 1; debug_cond(DEBUG_INT_STATE, "--- net_loop Entry\n"); bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); net_init(); if (eth_is_on_demand_init() || protocol != NETCONS) { eth_halt(); eth_set_current(); ret = eth_init(); if (ret < 0) { eth_halt(); return ret; } } else { eth_init_state_only(); } restart: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; #endif net_set_state(NETLOOP_CONTINUE); /* * Start the ball rolling with the given start function. From * here on, this code is a state machine driven by received * packets and timer events. */ debug_cond(DEBUG_INT_STATE, "--- net_loop Init\n"); net_init_loop(); switch (net_check_prereq(protocol)) { case 1: /* network not configured */ eth_halt(); return -ENODEV; case 2: /* network device not configured */ break; case 0: net_dev_exists = 1; net_boot_file_size = 0; switch (protocol) { case TFTPGET: #ifdef CONFIG_CMD_TFTPPUT case TFTPPUT: #endif /* always use ARP to get server ethernet address */ tftp_start(protocol); break; #ifdef CONFIG_CMD_TFTPSRV case TFTPSRV: tftp_start_server(); break; #endif #if defined(CONFIG_CMD_DHCP) case DHCP: bootp_reset(); net_ip.s_addr = 0; dhcp_request(); /* Basically same as BOOTP */ break; #endif case BOOTP: bootp_reset(); net_ip.s_addr = 0; bootp_request(); break; #if defined(CONFIG_CMD_RARP) case RARP: rarp_try = 0; net_ip.s_addr = 0; rarp_request(); break; #endif #if defined(CONFIG_CMD_PING) case PING: ping_start(); break; #endif #if defined(CONFIG_CMD_NFS) case NFS: nfs_start(); break; #endif #if defined(CONFIG_CMD_CDP) case CDP: cdp_start(); break; #endif #if defined(CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD) case NETCONS: nc_start(); break; #endif #if defined(CONFIG_CMD_SNTP) case SNTP: sntp_start(); break; #endif #if defined(CONFIG_CMD_DNS) case DNS: dns_start(); break; #endif #if defined(CONFIG_CMD_LINK_LOCAL) case LINKLOCAL: link_local_start(); break; #endif default: break; } break; } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ defined(CONFIG_STATUS_LED) && \ defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR)) status_led_set(STATUS_LED_RED, STATUS_LED_OFF); else status_led_set(STATUS_LED_RED, STATUS_LED_ON); #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 1; #endif /* * Main packet reception loop. Loop receiving packets until * someone sets `net_state' to a state that terminates. */ for (;;) { WATCHDOG_RESET(); #ifdef CONFIG_SHOW_ACTIVITY show_activity(1); #endif if (arp_timeout_check() > 0) time_start = get_timer(0); /* * Check the ethernet for a new packet. The ethernet * receive routine will process it. * Most drivers return the most recent packet size, but not * errors that may have happened. */ eth_rx(); /* * Abort if ctrl-c was pressed. */ if (ctrlc()) { /* cancel any ARP that may not have completed */ net_arp_wait_packet_ip.s_addr = 0; net_cleanup_loop(); eth_halt(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); puts("\nAbort\n"); /* include a debug print as well incase the debug messages are directed to stderr */ debug_cond(DEBUG_INT_STATE, "--- net_loop Abort!\n"); ret = -EINTR; goto done; } /* * Check for a timeout, and run the timeout handler * if we have one. */ if (time_handler && ((get_timer(0) - time_start) > time_delta)) { thand_f *x; #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ defined(CONFIG_STATUS_LED) && \ defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR)) status_led_set(STATUS_LED_RED, STATUS_LED_OFF); else status_led_set(STATUS_LED_RED, STATUS_LED_ON); #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ debug_cond(DEBUG_INT_STATE, "--- net_loop timeout\n"); x = time_handler; time_handler = (thand_f *)0; (*x)(); } if (net_state == NETLOOP_FAIL) ret = net_start_again(); switch (net_state) { case NETLOOP_RESTART: net_restarted = 1; goto restart; case NETLOOP_SUCCESS: net_cleanup_loop(); if (net_boot_file_size > 0) { printf("Bytes transferred = %d (%x hex)\n", net_boot_file_size, net_boot_file_size); setenv_hex("filesize", net_boot_file_size); setenv_hex("fileaddr", load_addr); } if (protocol != NETCONS) eth_halt(); else eth_halt_state_only(); eth_set_last_protocol(protocol); ret = net_boot_file_size; debug_cond(DEBUG_INT_STATE, "--- net_loop Success!\n"); goto done; case NETLOOP_FAIL: net_cleanup_loop(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!\n"); goto done; case NETLOOP_CONTINUE: continue; } } done: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; #endif #ifdef CONFIG_CMD_TFTPPUT /* Clear out the handlers */ net_set_udp_handler(NULL); net_set_icmp_handler(NULL); #endif return ret; }
int ubifs_load(char *filename, u32 addr, u32 size) { struct ubifs_info *c = ubifs_sb->s_fs_info; unsigned long inum; struct inode *inode; struct page page; int err = 0; int i; int count; int last_block_size = 0; c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY); /* ubifs_findfile will resolve symlinks, so we know that we get * the real file here */ inum = ubifs_findfile(ubifs_sb, filename); if (!inum) { err = -1; goto out; } /* * Read file inode */ inode = ubifs_iget(ubifs_sb, inum); if (IS_ERR(inode)) { printf("%s: Error reading inode %ld!\n", __func__, inum); err = PTR_ERR(inode); goto out; } /* * If no size was specified or if size bigger than filesize * set size to filesize */ if ((size == 0) || (size > inode->i_size)) size = inode->i_size; count = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT; printf("Loading file '%s' to addr 0x%08x with size %d (0x%08x)...\n", filename, addr, size, size); page.addr = (void *)addr; page.index = 0; page.inode = inode; for (i = 0; i < count; i++) { /* * Make sure to not read beyond the requested size */ if (((i + 1) == count) && (size < inode->i_size)) last_block_size = size - (i * PAGE_SIZE); err = do_readpage(c, inode, &page, last_block_size); if (err) break; page.addr += PAGE_SIZE; page.index++; } if (err) printf("Error reading file '%s'\n", filename); else { setenv_hex("filesize", size); printf("Done\n"); } ubifs_iput(inode); out: ubi_close_volume(c->ubi); return err; }
static int do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { ulong addr = load_addr; ulong dest = 0; ulong data, len; int verify; int part = 0; #if defined(CONFIG_IMAGE_FORMAT_LEGACY) ulong count; image_header_t *hdr = NULL; #endif #if defined(CONFIG_FIT) const char *uname = NULL; const void* fit_hdr; int noffset; const void *fit_data; size_t fit_len; #endif #ifdef CONFIG_GZIP uint unc_len = CONFIG_SYS_XIMG_LEN; #endif uint8_t comp; verify = getenv_yesno("verify"); if (argc > 1) { addr = simple_strtoul(argv[1], NULL, 16); } 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)) { #if defined(CONFIG_IMAGE_FORMAT_LEGACY) case IMAGE_FORMAT_LEGACY: 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"); return 1; } if (!image_check_hcrc(hdr)) { printf("Bad Header Checksum\n"); return 1; } #ifdef DEBUG image_print_contents(hdr); #endif if (!image_check_type(hdr, IH_TYPE_MULTI)) { printf("Wrong Image Type for %s command\n", cmdtp->name); return 1; } comp = image_get_comp(hdr); if ((comp != IH_COMP_NONE) && (argc < 4)) { printf("Must specify load address for %s command " "with compressed image\n", cmdtp->name); return 1; } if (verify) { printf(" Verifying Checksum ... "); if (!image_check_dcrc(hdr)) { printf("Bad Data CRC\n"); return 1; } printf("OK\n"); } count = image_multi_count(hdr); if (part >= count) { printf("Bad Image Part\n"); return 1; } image_multi_getimg(hdr, part, &data, &len); break; #endif #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: 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, 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) && (argc < 4)) { printf("Must specify load address for %s command " "with compressed image\n", cmdtp->name); return 1; } /* verify integrity */ if (verify) { if (!fit_image_verify(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; } if (fit_image_get_comp(fit_hdr, noffset, &comp)) { puts("Could not find script subimage " "compression type\n"); return 1; } data = (ulong)fit_data; len = (ulong)fit_len; break; #endif default: puts("Invalid image type for imxtract\n"); return 1; } if (argc > 3) { switch (comp) { case IH_COMP_NONE: #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) { size_t l = len; size_t tail; void *to = (void *) dest; void *from = (void *)data; printf(" Loading part %d ... ", part); while (l > 0) { tail = (l > CHUNKSZ) ? CHUNKSZ : l; WATCHDOG_RESET(); memmove(to, from, tail); to += tail; from += tail; l -= tail; } } #else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ printf(" Loading part %d ... ", part); memmove((char *) dest, (char *)data, len); #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ break; #ifdef CONFIG_GZIP case IH_COMP_GZIP: printf(" Uncompressing part %d ... ", part); if (gunzip((void *) dest, unc_len, (uchar *) data, &len) != 0) { puts("GUNZIP ERROR - image not loaded\n"); return 1; } break; #endif #if defined(CONFIG_BZIP2) && defined(CONFIG_IMAGE_FORMAT_LEGACY) case IH_COMP_BZIP2: { int i; printf(" Uncompressing part %d ... ", part); /* * If we've got less than 4 MB of malloc() * space, use slower decompression algorithm * which requires at most 2300 KB of memory. */ i = BZ2_bzBuffToBuffDecompress( map_sysmem(ntohl(hdr->ih_load), 0), &unc_len, (char *)data, len, CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { printf("BUNZIP2 ERROR %d - " "image not loaded\n", i); return 1; } } break; #endif /* CONFIG_BZIP2 */ default: printf("Unimplemented compression type %d\n", comp); return 1; } puts("OK\n"); } setenv_hex("fileaddr", data); setenv_hex("filesize", len); return 0; }
/** * Execute selected states of the bootm command. * * Note the arguments to this state must be the first argument, Any 'bootm' * or sub-command arguments must have already been taken. * * Note that if states contains more than one flag it MUST contain * BOOTM_STATE_START, since this handles and consumes the command line args. * * Also note that aside from boot_os_fn functions and bootm_load_os no other * functions we store the return value of in 'ret' may use a negative return * value, without special handling. * * @param cmdtp Pointer to bootm command table entry * @param flag Command flags (CMD_FLAG_...) * @param argc Number of subcommand arguments (0 = no arguments) * @param argv Arguments * @param states Mask containing states to run (BOOTM_STATE_...) * @param images Image header information * @param boot_progress 1 to show boot progress, 0 to not do this * @return 0 if ok, something else on error. Some errors will cause this * function to perform a reboot! If states contains BOOTM_STATE_OS_GO * then the intent is to boot an OS, so this function will not return * unless the image type is standalone. */ static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], int states, bootm_headers_t *images, int boot_progress) { boot_os_fn *boot_fn; ulong iflag = 0; int ret = 0; images->state |= states; /* * Work through the states and see how far we get. We stop on * any error. */ if (states & BOOTM_STATE_START) ret = bootm_start(cmdtp, flag, argc, argv); if (!ret && (states & BOOTM_STATE_FINDOS)) ret = bootm_find_os(cmdtp, flag, argc, argv); if (!ret && (states & BOOTM_STATE_FINDOTHER)) { ret = bootm_find_other(cmdtp, flag, argc, argv); argc = 0; /* consume the args */ } /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ iflag = disable_interrupts(); #ifdef CONFIG_NETCONSOLE /* Stop the ethernet stack if NetConsole could have left it up */ eth_halt(); #endif #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 /* Load the OS */ if (!ret && (states & BOOTM_STATE_LOADOS)) { ulong load_end; ret = bootm_load_os(images, &load_end, 0); if (ret && ret != BOOTM_ERR_OVERLAP) goto err; if (ret == 0) lmb_reserve(&images->lmb, images->os.load, (load_end - images->os.load)); else if (ret == BOOTM_ERR_OVERLAP) ret = 0; } /* Relocate the ramdisk */ #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH if (!ret && (states & BOOTM_STATE_RAMDISK)) { ulong rd_len = images->rd_end - images->rd_start; ret = boot_ramdisk_high(&images->lmb, images->rd_start, rd_len, &images->initrd_start, &images->initrd_end); if (!ret) { setenv_hex("initrd_start", images->initrd_start); setenv_hex("initrd_end", images->initrd_end); } } #endif #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB) if (!ret && (states & BOOTM_STATE_FDT)) { boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); ret = boot_relocate_fdt(&images->lmb, &images->ft_addr, &images->ft_len); } #endif /* From now on, we need the OS boot function */ if (ret) return ret; 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); bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS); return 1; } /* Call various other states that are not generally used */ if (!ret && (states & BOOTM_STATE_OS_CMDLINE)) ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images); if (!ret && (states & BOOTM_STATE_OS_BD_T)) ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images); if (!ret && (states & BOOTM_STATE_OS_PREP)) ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images); #ifdef CONFIG_TRACE /* Pretend to run the OS, then run a user command */ if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) { char *cmd_list = getenv("fakegocmd"); ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO, images, boot_fn); if (!ret && cmd_list) ret = run_command_list(cmd_list, -1, flag); } #endif /* Now run the OS! We hope this doesn't return */ if (!ret && (states & BOOTM_STATE_OS_GO)) { ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO, images, boot_fn); if (ret) goto err; } return ret; /* Deal with any fallout */ err: if (iflag) enable_interrupts(); if (ret == BOOTM_ERR_UNIMPLEMENTED) bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL); else if (ret == BOOTM_ERR_RESET) do_reset(cmdtp, flag, argc, argv); else puts("subcommand not supported\n"); return ret; }
int NetLoop(enum proto_t protocol) { bd_t *bd = gd->bd; int ret = -1; NetRestarted = 0; NetDevExists = 0; NetTryCount = 1; debug_cond(DEBUG_INT_STATE, "--- NetLoop Entry\n"); bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); net_init(); if (eth_is_on_demand_init() || protocol != NETCONS) { eth_halt(); eth_set_current(); if (eth_init(bd) < 0) { eth_halt(); return -1; } } else eth_init_state_only(bd); restart: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; #endif net_set_state(NETLOOP_CONTINUE); /* * Start the ball rolling with the given start function. From * here on, this code is a state machine driven by received * packets and timer events. */ debug_cond(DEBUG_INT_STATE, "--- NetLoop Init\n"); NetInitLoop(); switch (net_check_prereq(protocol)) { case 1: /* network not configured */ eth_halt(); return -1; case 2: /* network device not configured */ break; case 0: NetDevExists = 1; NetBootFileXferSize = 0; switch (protocol) { case TFTPGET: #ifdef CONFIG_CMD_TFTPPUT case TFTPPUT: #endif /* always use ARP to get server ethernet address */ TftpStart(protocol); break; #ifdef CONFIG_CMD_TFTPSRV case TFTPSRV: TftpStartServer(); break; #endif #if defined(CONFIG_CMD_DHCP) case DHCP: BootpReset(); NetOurIP = 0; DhcpRequest(); /* Basically same as BOOTP */ break; #endif case BOOTP: BootpReset(); NetOurIP = 0; BootpRequest(); break; #if defined(CONFIG_CMD_RARP) case RARP: RarpTry = 0; NetOurIP = 0; RarpRequest(); break; #endif #if defined(CONFIG_CMD_PING) case PING: ping_start(); break; #endif #if defined(CONFIG_CMD_NFS) case NFS: NfsStart(); break; #endif #if defined(CONFIG_CMD_CDP) case CDP: CDPStart(); break; #endif #if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD) case NETCONS: NcStart(); break; #endif #if defined(CONFIG_CMD_SNTP) case SNTP: SntpStart(); break; #endif #if defined(CONFIG_CMD_DNS) case DNS: DnsStart(); break; #endif #if defined(CONFIG_CMD_LINK_LOCAL) case LINKLOCAL: link_local_start(); break; #endif default: break; } break; } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ defined(CONFIG_STATUS_LED) && \ defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR)) status_led_set(STATUS_LED_RED, STATUS_LED_OFF); else status_led_set(STATUS_LED_RED, STATUS_LED_ON); #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 1; #endif /* * Main packet reception loop. Loop receiving packets until * someone sets `net_state' to a state that terminates. */ for (;;) { WATCHDOG_RESET(); #ifdef CONFIG_SHOW_ACTIVITY show_activity(1); #endif /* * Check the ethernet for a new packet. The ethernet * receive routine will process it. */ eth_rx(); /* * Abort if ctrl-c was pressed. */ if (ctrlc()) { /* cancel any ARP that may not have completed */ NetArpWaitPacketIP = 0; net_cleanup_loop(); eth_halt(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); puts("\nAbort\n"); /* include a debug print as well incase the debug messages are directed to stderr */ debug_cond(DEBUG_INT_STATE, "--- NetLoop Abort!\n"); goto done; } ArpTimeoutCheck(); /* * Check for a timeout, and run the timeout handler * if we have one. */ if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) { thand_f *x; #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ defined(CONFIG_STATUS_LED) && \ defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR)) { status_led_set(STATUS_LED_RED, STATUS_LED_OFF); } else { status_led_set(STATUS_LED_RED, STATUS_LED_ON); } #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ debug_cond(DEBUG_INT_STATE, "--- NetLoop timeout\n"); x = timeHandler; timeHandler = (thand_f *)0; (*x)(); } switch (net_state) { case NETLOOP_RESTART: NetRestarted = 1; goto restart; case NETLOOP_SUCCESS: net_cleanup_loop(); if (NetBootFileXferSize > 0) { printf("Bytes transferred = %ld (%lx hex)\n", NetBootFileXferSize, NetBootFileXferSize); setenv_hex("filesize", NetBootFileXferSize); setenv_hex("fileaddr", load_addr); } if (protocol != NETCONS) eth_halt(); else eth_halt_state_only(); eth_set_last_protocol(protocol); ret = NetBootFileXferSize; debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n"); goto done; case NETLOOP_FAIL: net_cleanup_loop(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n"); goto done; case NETLOOP_CONTINUE: continue; } } done: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; #endif #ifdef CONFIG_CMD_TFTPPUT /* Clear out the handlers */ net_set_udp_handler(NULL); net_set_icmp_handler(NULL); #endif return ret; }
/* * env export [-t | -b | -c] [-s size] addr [var ...] * -t: export as text format; if size is given, data will be * padded with '\0' bytes; if not, one terminating '\0' * will be added (which is included in the "filesize" * setting so you can for exmple copy this to flash and * keep the termination). * -b: export as binary format (name=value pairs separated by * '\0', list end marked by double "\0\0") * -c: export as checksum protected environment format as * used for example by "saveenv" command * -s size: * size of output buffer * addr: memory address where environment gets stored * var... List of variable names that get included into the * export. Without arguments, the whole environment gets * exported. * * With "-c" and size is NOT given, then the export command will * format the data as currently used for the persistent storage, * i. e. it will use CONFIG_ENV_SECT_SIZE as output block size and * prepend a valid CRC32 checksum and, in case of resundant * environment, a "current" redundancy flag. If size is given, this * value will be used instead of CONFIG_ENV_SECT_SIZE; again, CRC32 * checksum and redundancy flag will be inserted. * * With "-b" and "-t", always only the real data (including a * terminating '\0' byte) will be written; here the optional size * argument will be used to make sure not to overflow the user * provided buffer; the command will abort if the size is not * sufficient. Any remainign space will be '\0' padded. * * On successful return, the variable "filesize" will be set. * Note that filesize includes the trailing/terminating '\0' byte(s). * * Usage szenario: create a text snapshot/backup of the current settings: * * => env export -t 100000 * => era ${backup_addr} +${filesize} * => cp.b 100000 ${backup_addr} ${filesize} * * Re-import this snapshot, deleting all other settings: * * => env import -d -t ${backup_addr} */ static int do_env_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char buf[32]; char *addr, *cmd, *res; size_t size = 0; ssize_t len; env_t *envp; char sep = '\n'; int chk = 0; int fmt = 0; cmd = *argv; while (--argc > 0 && **++argv == '-') { char *arg = *argv; while (*++arg) { switch (*arg) { case 'b': /* raw binary format */ if (fmt++) goto sep_err; sep = '\0'; break; case 'c': /* external checksum format */ if (fmt++) goto sep_err; sep = '\0'; chk = 1; break; case 's': /* size given */ if (--argc <= 0) return cmd_usage(cmdtp); size = simple_strtoul(*++argv, NULL, 16); goto NXTARG; case 't': /* text format */ if (fmt++) goto sep_err; sep = '\n'; break; default: return CMD_RET_USAGE; } } NXTARG: ; } if (argc < 1) return CMD_RET_USAGE; addr = (char *)simple_strtoul(argv[0], NULL, 16); if (size) memset(addr, '\0', size); argc--; argv++; if (sep) { /* export as text file */ len = hexport_r(&env_htab, sep, H_MATCH_KEY | H_MATCH_IDENT, &addr, size, argc, argv); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } sprintf(buf, "%zX", (size_t)len); setenv("filesize", buf); return 0; } envp = (env_t *)addr; if (chk) /* export as checksum protected block */ res = (char *)envp->data; else /* export as raw binary data */ res = addr; len = hexport_r(&env_htab, '\0', H_MATCH_KEY | H_MATCH_IDENT, &res, ENV_SIZE, argc, argv); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } if (chk) { envp->crc = crc32(0, envp->data, ENV_SIZE); #ifdef CONFIG_ENV_ADDR_REDUND envp->flags = ACTIVE_FLAG; #endif } setenv_hex("filesize", len + offsetof(env_t, data)); return 0; sep_err: printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n", cmd); return 1; }
static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = NULL; int dev; int part; ulong addr = 0; disk_partition_t info; block_dev_desc_t *dev_desc; char buf[12]; unsigned long count; const char *addr_str; struct zfs_file zfile; struct device_s vdev; if (argc < 3) return CMD_RET_USAGE; count = 0; addr = simple_strtoul(argv[3], NULL, 16); filename = getenv("bootfile"); switch (argc) { case 3: addr_str = getenv("loadaddr"); if (addr_str != NULL) addr = simple_strtoul(addr_str, NULL, 16); else addr = CONFIG_SYS_LOAD_ADDR; break; case 4: break; case 5: filename = argv[4]; break; case 6: filename = argv[4]; count = simple_strtoul(argv[5], NULL, 16); break; default: return cmd_usage(cmdtp); } if (!filename) { puts("** No boot file defined **\n"); return 1; } part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; dev = dev_desc->dev; printf("Loading file \"%s\" from %s device %d%c%c\n", filename, argv[1], dev, part ? ':' : ' ', part ? part + '0' : ' '); zfs_set_blk_dev(dev_desc, &info); vdev.part_length = info.size; memset(&zfile, 0, sizeof(zfile)); zfile.device = &vdev; if (zfs_open(&zfile, filename)) { printf("** File not found %s\n", filename); return 1; } if ((count < zfile.size) && (count != 0)) zfile.size = (uint64_t)count; if (zfs_read(&zfile, (char *)addr, zfile.size) != zfile.size) { printf("** Unable to read \"%s\" from %s %d:%d **\n", filename, argv[1], dev, part); zfs_close(&zfile); return 1; } zfs_close(&zfile); /* Loading ok, update default load address */ load_addr = addr; printf("%llu bytes read\n", zfile.size); setenv_hex("filesize", zfile.size); return 0; }