diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/Kconfig | 9 | ||||
-rw-r--r-- | cmd/Makefile | 1 | ||||
-rw-r--r-- | cmd/booti.c | 40 | ||||
-rw-r--r-- | cmd/fat.c | 6 | ||||
-rw-r--r-- | cmd/mem.c | 92 | ||||
-rw-r--r-- | cmd/unlz4.c | 45 |
6 files changed, 160 insertions, 33 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig index faa133da65..a46c77d69d 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 f1dd513a4b..6692ed96c6 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 de5058236e..4fff8cfcf6 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" @@ -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> @@ -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 0000000000..5320b378d3 --- /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" +); |