static int do_zip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long src, dst; unsigned long src_len, dst_len = ~0UL; switch (argc) { case 5: dst_len = simple_strtoul(argv[4], NULL, 16); /* fall through */ case 4: src = simple_strtoul(argv[1], NULL, 16); src_len = simple_strtoul(argv[2], NULL, 16); dst = simple_strtoul(argv[3], NULL, 16); break; default: return cmd_usage(cmdtp); } if (gzip((void *) dst, &dst_len, (void *) src, src_len) != 0) return 1; printf("Compressed size: %ld = 0x%lX\n", dst_len, dst_len); env_set_hex("filesize", dst_len); return 0; }
static int zynqmp_verify_secure(u8 *key_ptr, u8 *src_ptr, u32 len) { int ret; u32 src_lo, src_hi; u32 key_lo = 0; u32 key_hi = 0; u32 ret_payload[PAYLOAD_ARG_CNT]; u64 addr; if ((ulong)src_ptr != ALIGN((ulong)src_ptr, CONFIG_SYS_CACHELINE_SIZE)) { printf("Failed: source address not aligned:%p\n", src_ptr); return -EINVAL; } src_lo = lower_32_bits((ulong)src_ptr); src_hi = upper_32_bits((ulong)src_ptr); flush_dcache_range((ulong)src_ptr, (ulong)(src_ptr + len)); if (key_ptr) { key_lo = lower_32_bits((ulong)key_ptr); key_hi = upper_32_bits((ulong)key_ptr); flush_dcache_range((ulong)key_ptr, (ulong)(key_ptr + KEY_PTR_LEN)); } ret = invoke_smc(ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD, src_lo, src_hi, key_lo, key_hi, ret_payload); if (ret) { printf("Failed: secure op status:0x%x\n", ret); } else { addr = (u64)ret_payload[1] << 32 | ret_payload[2]; printf("Verified image at 0x%llx\n", addr); env_set_hex("zynqmp_verified_img_addr", addr); } return ret; }
static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { const cmd_tbl_t *c; if (argc < 2) /* no subcommand */ return cmd_usage(cmdtp); c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], ARRAY_SIZE(cmd_spl_export_sub)); if ((c) && ((int)c->cmd <= SPL_EXPORT_LAST)) { argc -= 2; argv += 2; if (call_bootm(argc, argv, subcmd_list[(int)c->cmd])) return -1; switch ((int)c->cmd) { #ifdef CONFIG_OF_LIBFDT case SPL_EXPORT_FDT: printf("Argument image is now in RAM: 0x%p\n", (void *)images.ft_addr); env_set_addr("fdtargsaddr", images.ft_addr); env_set_hex("fdtargslen", fdt_totalsize(images.ft_addr)); if (fdt_totalsize(images.ft_addr) > CONFIG_CMD_SPL_WRITE_SIZE) puts("WARN: FDT size > CMD_SPL_WRITE_SIZE\n"); break; #endif case SPL_EXPORT_ATAGS: printf("Argument image is now in RAM at: 0x%p\n", (void *)gd->bd->bi_boot_params); break; } } else { /* Unrecognized command */ return cmd_usage(cmdtp); } return 0; }
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; struct blk_desc *dev_desc; unsigned long count; const char *addr_str; struct zfs_file zfile; struct zfs_device_s vdev; if (argc < 3) return CMD_RET_USAGE; count = 0; addr = simple_strtoul(argv[3], NULL, 16); filename = env_get("bootfile"); switch (argc) { case 3: addr_str = env_get("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 = blk_get_device_part_str(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; dev = dev_desc->devnum; printf("Loading file \"%s\" from %s device %d%c%c\n", filename, argv[1], dev, part ? ':' : ' ', part ? part + '0' : ' '); zfs_set_blk_dev(&vdev, dev_desc, &info); 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); env_set_hex("filesize", zfile.size); return 0; }
int ubi_volume_read(char *volume, char *buf, size_t size) { int err, lnum, off, len, tbuf_size; void *tbuf; unsigned long long tmp; struct ubi_volume *vol; loff_t offp = 0; size_t len_read; vol = ubi_find_volume(volume); if (vol == NULL) return ENODEV; if (vol->updating) { printf("updating"); return EBUSY; } if (vol->upd_marker) { printf("damaged volume, update marker is set"); return EBADF; } if (offp == vol->used_bytes) return 0; if (size == 0) { printf("No size specified -> Using max size (%lld)\n", vol->used_bytes); size = vol->used_bytes; } printf("Read %zu bytes from volume %s to %p\n", size, volume, buf); if (vol->corrupted) printf("read from corrupted volume %d", vol->vol_id); if (offp + size > vol->used_bytes) size = vol->used_bytes - offp; tbuf_size = vol->usable_leb_size; if (size < tbuf_size) tbuf_size = ALIGN(size, ubi->min_io_size); tbuf = malloc_cache_aligned(tbuf_size); if (!tbuf) { printf("NO MEM\n"); return ENOMEM; } len = size > tbuf_size ? tbuf_size : size; tmp = offp; off = do_div(tmp, vol->usable_leb_size); lnum = tmp; len_read = size; do { if (off + len >= vol->usable_leb_size) len = vol->usable_leb_size - off; err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0); if (err) { printf("read err %x\n", err); err = -err; break; } off += len; if (off == vol->usable_leb_size) { lnum += 1; off -= vol->usable_leb_size; } size -= len; offp += len; memcpy(buf, tbuf, len); buf += len; len = size > tbuf_size ? tbuf_size : size; } while (size); if (!size) env_set_hex("filesize", len_read); free(tbuf); return err; }
/** * 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. */ 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); /* Load the OS */ if (!ret && (states & BOOTM_STATE_LOADOS)) { iflag = bootm_disable_interrupts(); ret = bootm_load_os(images, 0); if (ret && ret != BOOTM_ERR_OVERLAP) goto err; 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) { env_set_hex("initrd_start", images->initrd_start); env_set_hex("initrd_end", images->initrd_end); } } #endif #if IMAGE_ENABLE_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 = bootm_os_get_boot_func(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)) { #if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) if (images->os.os == IH_OS_LINUX) fixup_silent_linux(); #endif 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 = env_get("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; }
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 = env_get_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) && !image_check_type(hdr, IH_TYPE_SCRIPT)) { 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/external data address and length */ if (fit_image_get_data_and_size(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"); } flush_cache(dest, ALIGN(len, ARCH_DMA_MINALIGN)); env_set_hex("fileaddr", data); env_set_hex("filesize", len); return 0; }