diff options
| author | Tom Rini <[email protected]> | 2020-08-05 16:05:33 -0400 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2020-08-05 16:05:33 -0400 |
| commit | 635dfee2cb522f5072530ca63fd4ab02890b90a2 (patch) | |
| tree | 8abedb1958a51367a9a08922eea3d33cfb6035f4 /cmd | |
| parent | f1c0b7cd4be2081ae3711cec2c4cc2910a5817e1 (diff) | |
| parent | 7b27e0fe13d8d44da6cd357a69668a726b852502 (diff) | |
Merge branch '2020-08-05-misc-fixes'
- A large number of assorted fixes and minor improvements
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/Kconfig | 8 | ||||
| -rw-r--r-- | cmd/Makefile | 1 | ||||
| -rw-r--r-- | cmd/bdinfo.c | 14 | ||||
| -rw-r--r-- | cmd/bootz.c | 2 | ||||
| -rw-r--r-- | cmd/clone.c | 126 |
5 files changed, 147 insertions, 4 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig index d7136b0e790..e11176451b1 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1148,6 +1148,14 @@ config CMD_MMC_SWRITE endif +config CMD_CLONE + bool "clone" + depends on BLK + help + Enable storage cloning over block devices, useful for + initial flashing by external block device without network + or usb support. + config CMD_MTD bool "mtd" depends on MTD diff --git a/cmd/Makefile b/cmd/Makefile index 6e0086ba07f..70750375d12 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -98,6 +98,7 @@ obj-$(CONFIG_CMD_MMC) += mmc.o obj-$(CONFIG_MP) += mp.o obj-$(CONFIG_CMD_MTD) += mtd.o obj-$(CONFIG_CMD_MTDPARTS) += mtdparts.o +obj-$(CONFIG_CMD_CLONE) += clone.o ifneq ($(CONFIG_CMD_NAND)$(CONFIG_CMD_SF),) obj-y += legacy-mtd-utils.o endif diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index 8b2c105e777..9485c404740 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -9,6 +9,7 @@ #include <common.h> #include <command.h> #include <env.h> +#include <lmb.h> #include <net.h> #include <vsprintf.h> #include <asm/cache.h> @@ -33,9 +34,10 @@ static void print_eth(int idx) printf("%-12s= %s\n", name, val); } -static void print_lnum(const char *name, unsigned long long value) +static void print_phys_addr(const char *name, phys_addr_t value) { - printf("%-12s= 0x%.8llX\n", name, value); + printf("%-12s= 0x%.*llx\n", name, 2 * (int)sizeof(ulong), + (unsigned long long)value); } void bdinfo_print_mhz(const char *name, unsigned long hz) @@ -74,7 +76,7 @@ int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) bdinfo_print_num("boot_params", (ulong)bd->bi_boot_params); print_bi_dram(bd); bdinfo_print_num("memstart", (ulong)bd->bi_memstart); - print_lnum("memsize", (u64)bd->bi_memsize); + print_phys_addr("memsize", bd->bi_memsize); bdinfo_print_num("flashstart", (ulong)bd->bi_flashstart); bdinfo_print_num("flashsize", (ulong)bd->bi_flashsize); bdinfo_print_num("flashoffset", (ulong)bd->bi_flashoffset); @@ -96,6 +98,12 @@ int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) #if CONFIG_IS_ENABLED(MULTI_DTB_FIT) bdinfo_print_num("multi_dtb_fit", (ulong)gd->multi_dtb_fit); #endif + if (gd->fdt_blob) { + struct lmb lmb; + + lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); + lmb_dump_all_force(&lmb); + } arch_print_bdinfo(); diff --git a/cmd/bootz.c b/cmd/bootz.c index 1c8b0cf89f9..7556cd2752a 100644 --- a/cmd/bootz.c +++ b/cmd/bootz.c @@ -54,7 +54,7 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc, * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not * have a header that provide this informaiton. */ - if (bootm_find_images(flag, argc, argv, zi_start, zi_end - zi_start)) + if (bootm_find_images(flag, argc, argv, images->ep, zi_end - zi_start)) return 1; return 0; diff --git a/cmd/clone.c b/cmd/clone.c new file mode 100644 index 00000000000..97747f8f080 --- /dev/null +++ b/cmd/clone.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 John Chau <[email protected]> + * + */ + +#include <common.h> +#include <command.h> +#include <malloc.h> +#include <part.h> +#include <blk.h> +#include <vsprintf.h> + +#define BUFSIZE (1 * 1024 * 1024) +static int do_clone(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + int srcdev, destdev; + struct blk_desc *srcdesc, *destdesc; + int srcbz, destbz, ret; + char *unit, *buf; + unsigned long wrcnt, rdcnt, requested, srcblk, destblk; + unsigned long timer; + const unsigned long buffersize = 1024 * 1024; + + if (argc < 6) + return CMD_RET_USAGE; + + srcdev = blk_get_device_by_str(argv[1], argv[2], &srcdesc); + destdev = blk_get_device_by_str(argv[3], argv[4], &destdesc); + if (srcdev < 0) { + printf("Unable to open source device\n"); + return 1; + } else if (destdev < 0) { + printf("Unable to open destination device\n"); + return 1; + } + requested = simple_strtoul(argv[5], &unit, 10); + srcbz = srcdesc->blksz; + destbz = destdesc->blksz; + + if ((srcbz * (buffersize / srcbz) != buffersize) && + (destbz * (buffersize / destbz) != buffersize)) { + printf("failed: cannot match device block sizes\n"); + return 1; + } + if (requested == 0) { + unsigned long a = srcdesc->lba * srcdesc->blksz; + unsigned long b = destdesc->lba * destdesc->blksz; + + if (a > b) + requested = a; + else + requested = b; + } else { + switch (unit[0]) { + case 'g': + case 'G': + requested *= 1024; + case 'm': + case 'M': + requested *= 1024; + case 'k': + case 'K': + requested *= 1024; + break; + } + } + printf("Copying %ld bytes from %s:%s to %s:%s\n", + requested, argv[1], argv[2], argv[3], argv[4]); + wrcnt = 0; + rdcnt = 0; + buf = (char *)malloc(BUFSIZE); + srcblk = 0; + destblk = 0; + timer = get_timer(0); + while (wrcnt < requested) { + unsigned long toread = BUFSIZE / srcbz; + unsigned long towrite = BUFSIZE / destbz; + unsigned long offset = 0; + +read: + ret = blk_dread(srcdesc, srcblk, toread, buf + offset); + if (ret < 0) { + printf("Src read error @blk %ld\n", srcblk); + goto exit; + } + rdcnt += ret * srcbz; + srcblk += ret; + if (ret < toread) { + toread -= ret; + offset += ret * srcbz; + goto read; + } + offset = 0; +write: + ret = blk_dwrite(destdesc, destblk, towrite, buf + offset); + if (ret < 0) { + printf("Dest write error @blk %ld\n", srcblk); + goto exit; + } + wrcnt += ret * destbz; + destblk += ret; + if (ret < towrite) { + towrite -= ret; + offset += ret * destbz; + goto write; + } + } + +exit: + timer = get_timer(timer); + timer = 1000 * timer / CONFIG_SYS_HZ; + printf("%ld read\n", rdcnt); + printf("%ld written\n", wrcnt); + printf("%ldms, %ldkB/s\n", timer, wrcnt / timer); + free(buf); + + return 0; +} + +U_BOOT_CMD( + clone, 6, 1, do_clone, + "simple storage cloning", + "<src interface> <src dev> <dest interface> <dest dev> <size[K/M/G]>\n" + "clone storage from 'src dev' on 'src interface' to 'dest dev' on 'dest interface' with maximum 'size' bytes (or 0 for clone to end)" +); |
