aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2020-04-20 17:22:47 -0400
committerTom Rini <trini@konsulko.com>2020-04-20 17:22:47 -0400
commita06375805917a5b48c46724ceef4a1cd04935992 (patch)
tree45bba4e4fb8332c55324efaf96e46e6cbd8f4d93 /cmd
parente4837da7828293ea49abc579f939c0f5c4b127c3 (diff)
parent48180e15d3eaff51b1da30a90bc64b7acba8fb51 (diff)
downloadu-boot-a06375805917a5b48c46724ceef4a1cd04935992.zip
u-boot-a06375805917a5b48c46724ceef4a1cd04935992.tar.gz
u-boot-a06375805917a5b48c46724ceef4a1cd04935992.tar.bz2
Merge branch '2020-04-17-master-imports'
- Further cleanups for 'make refcheckdocs' - Another BTRFS fix. - Support for automatic decompression of images with booti as well as unlz4 command for manual decompression.
Diffstat (limited to 'cmd')
-rw-r--r--cmd/Kconfig9
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/booti.c40
-rw-r--r--cmd/fat.c6
-rw-r--r--cmd/mem.c92
-rw-r--r--cmd/unlz4.c45
6 files changed, 160 insertions, 33 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig
index faa133d..a46c77d 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -770,6 +770,13 @@ config CMD_LZMADEC
Support decompressing an LZMA (Lempel-Ziv-Markov chain algorithm)
image from memory.
+config CMD_UNLZ4
+ bool "unlz4"
+ default y if CMD_BOOTI
+ select LZ4
+ help
+ Support decompressing an LZ4 image from memory region.
+
config CMD_UNZIP
bool "unzip"
default y if CMD_BOOTI
@@ -2096,7 +2103,7 @@ config CMD_BEDBUG
help
The bedbug (emBEDded deBUGger) command provides debugging features
for some PowerPC processors. For details please see the
- docuemntation in doc/README.beddbug
+ documentation in doc/README.bedbug.
config CMD_DIAG
bool "diag - Board diagnostics"
diff --git a/cmd/Makefile b/cmd/Makefile
index f1dd513..6692ed9 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -144,6 +144,7 @@ obj-$(CONFIG_CMD_TSI148) += tsi148.o
obj-$(CONFIG_CMD_UBI) += ubi.o
obj-$(CONFIG_CMD_UBIFS) += ubifs.o
obj-$(CONFIG_CMD_UNIVERSE) += universe.o
+obj-$(CONFIG_CMD_UNLZ4) += unlz4.o
obj-$(CONFIG_CMD_UNZIP) += unzip.o
obj-$(CONFIG_CMD_VIRTIO) += virtio.o
obj-$(CONFIG_CMD_WDT) += wdt.o
diff --git a/cmd/booti.c b/cmd/booti.c
index de50582..4fff8cf 100644
--- a/cmd/booti.c
+++ b/cmd/booti.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/sizes.h>
+DECLARE_GLOBAL_DATA_PTR;
/*
* Image booting support
*/
@@ -24,6 +25,12 @@ static int booti_start(cmd_tbl_t *cmdtp, int flag, int argc,
ulong ld;
ulong relocated_addr;
ulong image_size;
+ uint8_t *temp;
+ ulong dest;
+ ulong dest_end;
+ unsigned long comp_len;
+ unsigned long decomp_len;
+ int ctype;
ret = do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START,
images, 1);
@@ -38,6 +45,33 @@ static int booti_start(cmd_tbl_t *cmdtp, int flag, int argc,
debug("* kernel: cmdline image address = 0x%08lx\n", ld);
}
+ temp = map_sysmem(ld, 0);
+ ctype = image_decomp_type(temp, 2);
+ if (ctype > 0) {
+ dest = env_get_ulong("kernel_comp_addr_r", 16, 0);
+ comp_len = env_get_ulong("kernel_comp_size", 16, 0);
+ if (!dest || !comp_len) {
+ puts("kernel_comp_addr_r or kernel_comp_size is not provided!\n");
+ return -EINVAL;
+ }
+ if (dest < gd->ram_base || dest > gd->ram_top) {
+ puts("kernel_comp_addr_r is outside of DRAM range!\n");
+ return -EINVAL;
+ }
+
+ debug("kernel image compression type %d size = 0x%08lx address = 0x%08lx\n",
+ ctype, comp_len, (ulong)dest);
+ decomp_len = comp_len * 10;
+ ret = image_decomp(ctype, 0, ld, IH_TYPE_KERNEL,
+ (void *)dest, (void *)ld, comp_len,
+ decomp_len, &dest_end);
+ if (ret)
+ return ret;
+ /* dest_end contains the uncompressed Image size */
+ memmove((void *) ld, (void *)dest, dest_end);
+ }
+ unmap_sysmem((void *)ld);
+
ret = booti_setup(ld, &relocated_addr, &image_size, false);
if (ret != 0)
return 1;
@@ -100,10 +134,14 @@ int do_booti(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#ifdef CONFIG_SYS_LONGHELP
static char booti_help_text[] =
"[addr [initrd[:size]] [fdt]]\n"
- " - boot Linux 'Image' stored at 'addr'\n"
+ " - boot Linux flat or compressed 'Image' stored at 'addr'\n"
"\tThe argument 'initrd' is optional and specifies the address\n"
"\tof an initrd in memory. The optional parameter ':size' allows\n"
"\tspecifying the size of a RAW initrd.\n"
+ "\tCurrently only booting from gz, bz2, lzma and lz4 compression\n"
+ "\ttypes are supported. In order to boot from any of these compressed\n"
+ "\timages, user have to set kernel_comp_addr_r and kernel_comp_size enviornment\n"
+ "\tvariables beforehand.\n"
#if defined(CONFIG_OF_LIBFDT)
"\tSince booting a Linux kernel requires a flat device-tree, a\n"
"\tthird argument providing the address of the device-tree blob\n"
diff --git a/cmd/fat.c b/cmd/fat.c
index 50df127..abce2f1 100644
--- a/cmd/fat.c
+++ b/cmd/fat.c
@@ -8,13 +8,7 @@
* Boot support
*/
#include <common.h>
-#include <command.h>
-#include <s_record.h>
-#include <net.h>
-#include <ata.h>
-#include <asm/io.h>
#include <mapmem.h>
-#include <part.h>
#include <fat.h>
#include <fs.h>
diff --git a/cmd/mem.c b/cmd/mem.c
index 6d54f19..0bfb608 100644
--- a/cmd/mem.c
+++ b/cmd/mem.c
@@ -801,6 +801,59 @@ static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr,
return errs;
}
+static int compare_regions(volatile unsigned long *bufa,
+ volatile unsigned long *bufb, size_t count)
+{
+ volatile unsigned long *p1 = bufa;
+ volatile unsigned long *p2 = bufb;
+ int errs = 0;
+ size_t i;
+
+ for (i = 0; i < count; i++, p1++, p2++) {
+ if (*p1 != *p2) {
+ printf("FAILURE: 0x%08lx != 0x%08lx (delta=0x%08lx -> bit %ld) at offset 0x%08lx\n",
+ (unsigned long)*p1, (unsigned long)*p2,
+ *p1 ^ *p2, __ffs(*p1 ^ *p2),
+ (unsigned long)(i * sizeof(unsigned long)));
+ errs++;
+ }
+ }
+
+ return errs;
+}
+
+static ulong test_bitflip_comparison(volatile unsigned long *bufa,
+ volatile unsigned long *bufb, size_t count)
+{
+ volatile unsigned long *p1 = bufa;
+ volatile unsigned long *p2 = bufb;
+ unsigned int j, k;
+ unsigned long q;
+ size_t i;
+ int max;
+ int errs = 0;
+
+ max = sizeof(unsigned long) * 8;
+ for (k = 0; k < max; k++) {
+ q = 0x00000001L << k;
+ for (j = 0; j < 8; j++) {
+ WATCHDOG_RESET();
+ q = ~q;
+ p1 = (volatile unsigned long *)bufa;
+ p2 = (volatile unsigned long *)bufb;
+ for (i = 0; i < count; i++)
+ *p1++ = *p2++ = (i % 2) == 0 ? q : ~q;
+
+ errs += compare_regions(bufa, bufb, count);
+ }
+
+ if (ctrlc())
+ return -1UL;
+ }
+
+ return errs;
+}
+
static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr,
vu_long pattern, int iteration)
{
@@ -871,15 +924,10 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
ulong start, end;
vu_long *buf, *dummy;
ulong iteration_limit = 0;
- int ret;
+ ulong count = 0;
ulong errs = 0; /* number of errors, or -1 if interrupted */
ulong pattern = 0;
int iteration;
-#if defined(CONFIG_SYS_ALT_MEMTEST)
- const int alt_test = 1;
-#else
- const int alt_test = 0;
-#endif
start = CONFIG_SYS_MEMTEST_START;
end = CONFIG_SYS_MEMTEST_END;
@@ -921,40 +969,34 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
printf("Iteration: %6d\r", iteration + 1);
debug("\n");
- if (alt_test) {
+ if (IS_ENABLED(CONFIG_SYS_ALT_MEMTEST)) {
errs = mem_test_alt(buf, start, end, dummy);
+ if (errs == -1UL)
+ break;
+ count += errs;
+ errs = test_bitflip_comparison(buf,
+ buf + (end - start) / 2,
+ (end - start) /
+ sizeof(unsigned long));
} else {
errs = mem_test_quick(buf, start, end, pattern,
iteration);
}
if (errs == -1UL)
break;
+ count += errs;
}
- /*
- * Work-around for eldk-4.2 which gives this warning if we try to
- * case in the unmap_sysmem() call:
- * warning: initialization discards qualifiers from pointer target type
- */
- {
- void *vbuf = (void *)buf;
- void *vdummy = (void *)dummy;
-
- unmap_sysmem(vbuf);
- unmap_sysmem(vdummy);
- }
+ unmap_sysmem((void *)buf);
+ unmap_sysmem((void *)dummy);
if (errs == -1UL) {
/* Memory test was aborted - write a newline to finish off */
putc('\n');
- ret = 1;
- } else {
- printf("Tested %d iteration(s) with %lu errors.\n",
- iteration, errs);
- ret = errs != 0;
}
+ printf("Tested %d iteration(s) with %lu errors.\n", iteration, count);
- return ret;
+ return errs != 0;
}
#endif /* CONFIG_CMD_MEMTEST */
diff --git a/cmd/unlz4.c b/cmd/unlz4.c
new file mode 100644
index 0000000..5320b37
--- /dev/null
+++ b/cmd/unlz4.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020
+ * FUJITSU COMPUTERTECHNOLOGIES LIMITED. All rights reserved.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <env.h>
+#include <lz4.h>
+
+static int do_unlz4(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ unsigned long src, dst;
+ size_t src_len = ~0UL, dst_len = ~0UL;
+ int ret;
+
+ switch (argc) {
+ case 4:
+ src = simple_strtoul(argv[1], NULL, 16);
+ dst = simple_strtoul(argv[2], NULL, 16);
+ dst_len = simple_strtoul(argv[3], NULL, 16);
+ break;
+ default:
+ return CMD_RET_USAGE;
+ }
+
+ ret = ulz4fn((void *)src, src_len, (void *)dst, &dst_len);
+ if (ret) {
+ printf("Uncompressed err :%d\n", ret);
+ return 1;
+ }
+
+ printf("Uncompressed size: %zd = 0x%zX\n", dst_len, dst_len);
+ env_set_hex("filesize", dst_len);
+
+ return 0;
+}
+
+U_BOOT_CMD(unlz4, 4, 1, do_unlz4,
+ "lz4 uncompress a memory region",
+ "srcaddr dstaddr dstsize\n"
+ "NOTE: Specify the destination size that is sufficiently larger\n"
+ " than the source size.\n"
+);