summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/Kconfig21
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/bdinfo.c4
-rw-r--r--cmd/booti.c2
-rw-r--r--cmd/bootmenu.c2
-rw-r--r--cmd/bootz.c2
-rw-r--r--cmd/load.c2
-rw-r--r--cmd/mtd.c2
-rw-r--r--cmd/nand.c103
-rw-r--r--cmd/net-lwip.c7
-rw-r--r--cmd/net.c2
-rw-r--r--cmd/nvedit.c8
-rw-r--r--cmd/rng.c4
-rw-r--r--cmd/sb.c6
-rw-r--r--cmd/ufetch.c229
15 files changed, 370 insertions, 25 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig
index b2d0348fe30..93efeaec6f4 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -176,6 +176,13 @@ config CMD_CPU
internal name) and clock frequency. Other information may be
available depending on the CPU driver.
+config CMD_UFETCH
+ bool "U-Boot fetch"
+ depends on BLK
+ help
+ Fetch utility for U-Boot (akin to neofetch). Prints information
+ about U-Boot and the board it is running on in a pleasing format.
+
config CMD_FWU_METADATA
bool "fwu metadata read"
depends on FWU_MULTI_BANK_UPDATE
@@ -1490,6 +1497,11 @@ config CMD_NAND_TORTURE
help
NAND torture support.
+config CMD_NAND_WATCH
+ bool "nand watch"
+ help
+ NAND watch bitflip support.
+
endif # CMD_NAND
config CMD_NVME
@@ -2016,7 +2028,9 @@ config CMD_PING6
config CMD_CDP
bool "cdp"
help
- Perform CDP network configuration
+ The cdp command is used to announce the U-Boot device in the network
+ and to retrieve configuration data including the VLAN id using the
+ proprietary Cisco Discovery Protocol (CDP).
config CMD_SNTP
bool "sntp"
@@ -2115,11 +2129,8 @@ config CMD_TFTPBOOT
config CMD_WGET
bool "wget"
- depends on CMD_NET
default y if SANDBOX
- select PROT_TCP if NET
- select PROT_TCP_LWIP if NET_LWIP
- select PROT_DNS_LWIP if NET_LWIP
+ select WGET
help
wget is a simple command to download kernel, or other files,
from a http server over TCP.
diff --git a/cmd/Makefile b/cmd/Makefile
index d1f369deec0..1e6d3128c8c 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_CMD_CPU) += cpu.o
obj-$(CONFIG_CMD_DATE) += date.o
obj-$(CONFIG_CMD_DEMO) += demo.o
obj-$(CONFIG_CMD_DM) += dm.o
+obj-$(CONFIG_CMD_UFETCH) += ufetch.o
obj-$(CONFIG_CMD_SOUND) += sound.o
ifdef CONFIG_POST
obj-$(CONFIG_CMD_DIAG) += diag.o
diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c
index 4c0e2adabc3..ae9e1923eac 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -140,10 +140,6 @@ static int bdinfo_print_all(struct bd_info *bd)
#endif
bdinfo_print_num_l("boot_params", (ulong)bd->bi_boot_params);
print_bi_dram(bd);
- if (IS_ENABLED(CONFIG_SYS_HAS_SRAM)) {
- bdinfo_print_num_l("sramstart", (ulong)bd->bi_sramstart);
- bdinfo_print_num_l("sramsize", (ulong)bd->bi_sramsize);
- }
bdinfo_print_num_l("flashstart", (ulong)bd->bi_flashstart);
bdinfo_print_num_l("flashsize", (ulong)bd->bi_flashsize);
bdinfo_print_num_l("flashoffset", (ulong)bd->bi_flashoffset);
diff --git a/cmd/booti.c b/cmd/booti.c
index 43e79e87201..1a57fe91397 100644
--- a/cmd/booti.c
+++ b/cmd/booti.c
@@ -87,7 +87,7 @@ static int booti_start(struct bootm_info *bmi)
images->os.start = relocated_addr;
images->os.end = relocated_addr + image_size;
- lmb_reserve(images->ep, le32_to_cpu(image_size));
+ lmb_reserve(images->ep, le32_to_cpu(image_size), LMB_NONE);
/*
* Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
index ffa63a4628d..b633aedf011 100644
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -239,7 +239,7 @@ static int prepare_bootmenu_entry(struct bootmenu_data *menu,
/**
* prepare_uefi_bootorder_entry() - generate the uefi bootmenu entries
*
- * This function read the "BootOrder" UEFI variable
+ * This function reads the "BootOrder" UEFI variable
* and generate the bootmenu entries in the order of "BootOrder".
*
* @menu: pointer to the bootmenu structure
diff --git a/cmd/bootz.c b/cmd/bootz.c
index 787203f5bd7..99318ff213f 100644
--- a/cmd/bootz.c
+++ b/cmd/bootz.c
@@ -56,7 +56,7 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc,
if (ret != 0)
return 1;
- lmb_reserve(images->ep, zi_end - zi_start);
+ lmb_reserve(images->ep, zi_end - zi_start, LMB_NONE);
/*
* Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
diff --git a/cmd/load.c b/cmd/load.c
index 20d802502ae..899bb4f598e 100644
--- a/cmd/load.c
+++ b/cmd/load.c
@@ -179,7 +179,7 @@ static ulong load_serial(long offset)
{
void *dst;
- ret = lmb_reserve(store_addr, binlen);
+ ret = lmb_reserve(store_addr, binlen, LMB_NONE);
if (ret) {
printf("\nCannot overwrite reserved area (%08lx..%08lx)\n",
store_addr, store_addr + binlen);
diff --git a/cmd/mtd.c b/cmd/mtd.c
index f178d7bea61..c25997cfb24 100644
--- a/cmd/mtd.c
+++ b/cmd/mtd.c
@@ -122,13 +122,11 @@ static void mtd_show_device(struct mtd_info *mtd)
{
/* Device */
printf("* %s\n", mtd->name);
-#if defined(CONFIG_DM)
if (mtd->dev) {
printf(" - device: %s\n", mtd->dev->name);
printf(" - parent: %s\n", mtd->dev->parent->name);
printf(" - driver: %s\n", mtd->dev->driver->name);
}
-#endif
if (IS_ENABLED(CONFIG_OF_CONTROL) && mtd->dev) {
char buf[256];
int res;
diff --git a/cmd/nand.c b/cmd/nand.c
index 5a328e0acdd..2f785deeb7f 100644
--- a/cmd/nand.c
+++ b/cmd/nand.c
@@ -231,6 +231,54 @@ free_dat:
return ret;
}
+#ifdef CONFIG_CMD_NAND_WATCH
+static int nand_watch_bf(struct mtd_info *mtd, ulong off, ulong size, bool quiet)
+{
+ unsigned int max_bf = 0, pages_wbf = 0;
+ unsigned int first_page, pages, i;
+ struct mtd_oob_ops ops = {};
+ u_char *buf;
+ int ret;
+
+ buf = memalign(ARCH_DMA_MINALIGN, mtd->writesize);
+ if (!buf) {
+ puts("No memory for page buffer\n");
+ return 1;
+ }
+
+ first_page = off / mtd->writesize;
+ pages = size / mtd->writesize;
+
+ ops.datbuf = buf;
+ ops.len = mtd->writesize;
+ for (i = first_page; i < first_page + pages; i++) {
+ ulong addr = mtd->writesize * i;
+ ret = mtd_read_oob_bf(mtd, addr, &ops);
+ if (ret < 0) {
+ if (quiet)
+ continue;
+
+ printf("Page %7d (0x%08lx) -> error %d\n",
+ i, addr, ret);
+ } else if (ret) {
+ max_bf = max(max_bf, (unsigned int)ret);
+ pages_wbf++;
+ if (quiet)
+ continue;
+ printf("Page %7d (0x%08lx) -> up to %2d bf/chunk\n",
+ i, addr, ret);
+ }
+ }
+
+ printf("Maximum number of bitflips: %u\n", max_bf);
+ printf("Pages with bitflips: %u/%u\n", pages_wbf, pages);
+
+ free(buf);
+
+ return 0;
+}
+#endif
+
/* ------------------------------------------------------------------------- */
static int set_dev(int dev)
@@ -781,6 +829,55 @@ static int do_nand(struct cmd_tbl *cmdtp, int flag, int argc,
return ret == 0 ? 0 : 1;
}
+#ifdef CONFIG_CMD_NAND_WATCH
+ if (strncmp(cmd, "watch", 5) == 0) {
+ int args = 2;
+
+ if (cmd[5]) {
+ if (!strncmp(&cmd[5], ".part", 5)) {
+ args = 1;
+ } else if (!strncmp(&cmd[5], ".chip", 5)) {
+ args = 0;
+ } else {
+ goto usage;
+ }
+ }
+
+ if (cmd[10])
+ if (!strncmp(&cmd[10], ".quiet", 6))
+ quiet = true;
+
+ if (argc != 2 + args)
+ goto usage;
+
+ ret = mtd_arg_off_size(argc - 2, argv + 2, &dev, &off, &size,
+ &maxsize, MTD_DEV_TYPE_NAND, mtd->size);
+ if (ret)
+ return ret;
+
+ /* size is unspecified */
+ if (argc < 4)
+ adjust_size_for_badblocks(&size, off, dev);
+
+ if ((off & (mtd->writesize - 1)) ||
+ (size & (mtd->writesize - 1))) {
+ printf("Attempt to read non page-aligned data\n");
+ return -EINVAL;
+ }
+
+ ret = set_dev(dev);
+ if (ret)
+ return ret;
+
+ mtd = get_nand_dev_by_index(dev);
+
+ printf("\nNAND watch for bitflips in area 0x%llx-0x%llx:\n",
+ off, off + size);
+
+ return nand_watch_bf(mtd, off, size, quiet);
+ }
+#endif
+
#ifdef CONFIG_CMD_NAND_TORTURE
if (strcmp(cmd, "torture") == 0) {
loff_t endoff;
@@ -946,6 +1043,12 @@ U_BOOT_LONGHELP(nand,
"nand erase.chip [clean] - erase entire chip'\n"
"nand bad - show bad blocks\n"
"nand dump[.oob] off - dump page\n"
+#ifdef CONFIG_CMD_NAND_WATCH
+ "nand watch <off> <size> - check an area for bitflips\n"
+ "nand watch.part <part> - check a partition for bitflips\n"
+ "nand watch.chip - check the whole device for bitflips\n"
+ "\t\t.quiet - Query only the summary, not the details\n"
+#endif
#ifdef CONFIG_CMD_NAND_TORTURE
"nand torture off - torture one block at offset\n"
"nand torture off [size] - torture blocks from off to off+size\n"
diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c
index 6f5fc743030..0fd446ecb20 100644
--- a/cmd/net-lwip.c
+++ b/cmd/net-lwip.c
@@ -27,6 +27,9 @@ U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname",
#endif
#if defined(CONFIG_CMD_WGET)
-U_BOOT_CMD(wget, 3, 1, do_wget, "boot image via network using HTTP protocol",
- "[loadAddress] URL");
+U_BOOT_CMD(wget, 3, 1, do_wget,
+ "boot image via network using HTTP/HTTPS protocol",
+ "[loadAddress] url\n"
+ "wget [loadAddress] [host:]path"
+);
#endif
diff --git a/cmd/net.c b/cmd/net.c
index c90578e1b9f..79525f73a51 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -196,6 +196,8 @@ U_BOOT_CMD(
#if defined(CONFIG_CMD_WGET)
static int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
{
+ wget_info = &default_wget_info;
+
return netboot_common(WGET, cmdtp, argc, argv);
}
diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 392f90f8698..1f259801293 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -523,6 +523,9 @@ static int do_env_default(struct cmd_tbl *cmdtp, int flag,
case 'f': /* force */
env_flag |= H_FORCE;
break;
+ case 'k':
+ env_flag |= H_NOCLEAR;
+ break;
default:
return cmd_usage(cmdtp);
}
@@ -1133,8 +1136,9 @@ U_BOOT_LONGHELP(env,
#if defined(CONFIG_CMD_ENV_CALLBACK)
"callbacks - print callbacks and their associated variables\nenv "
#endif
- "default [-f] -a - [forcibly] reset default environment\n"
- "env default [-f] var [...] - [forcibly] reset variable(s) to their default values\n"
+ "default [-k] [-f] -a - [forcibly] reset default environment\n"
+ "env default [-k] [-f] var [...] - [forcibly] reset variable(s) to their default values\n"
+ " \"-k\": keep variables not defined in default environment\n"
"env delete [-f] var [...] - [forcibly] delete variable(s)\n"
#if defined(CONFIG_CMD_EDITENV)
"env edit name - edit environment variable\n"
diff --git a/cmd/rng.c b/cmd/rng.c
index 2fb7202303a..4d91094a8ec 100644
--- a/cmd/rng.c
+++ b/cmd/rng.c
@@ -75,6 +75,6 @@ static int do_rng(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
U_BOOT_CMD(
rng, 3, 0, do_rng,
"print bytes from the hardware random number generator",
- "list - list all the probed rng devices\n"
- "rng [dev] [n] - print n random bytes(max 64) read from dev\n"
+ "list - list all probed rng devices\n"
+ "rng [dev [n]] - print n random bytes (max 64) read from dev\n"
);
diff --git a/cmd/sb.c b/cmd/sb.c
index 9245052492e..79f3fb0aacd 100644
--- a/cmd/sb.c
+++ b/cmd/sb.c
@@ -15,10 +15,8 @@ static int do_sb_handoff(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
#if CONFIG_IS_ENABLED(HANDOFF)
- struct spl_handoff *handoff = handoff_get();
-
- if (handoff)
- printf("SPL handoff magic %lx\n", handoff->arch.magic);
+ if (gd->spl_handoff)
+ printf("SPL handoff magic %lx\n", gd->spl_handoff->arch.magic);
else
printf("SPL handoff info not received\n");
diff --git a/cmd/ufetch.c b/cmd/ufetch.c
new file mode 100644
index 00000000000..0b825d7e8c7
--- /dev/null
+++ b/cmd/ufetch.c
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* Small "fetch" utility for U-Boot */
+
+#ifdef CONFIG_ARM64
+#include <asm/system.h>
+#endif
+#include <dm/device.h>
+#include <dm/uclass-internal.h>
+#include <display_options.h>
+#include <mmc.h>
+#include <time.h>
+#include <asm/global_data.h>
+#include <cli.h>
+#include <command.h>
+#include <dm/ofnode.h>
+#include <env.h>
+#include <rand.h>
+#include <vsprintf.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <version.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define LINE_WIDTH 40
+#define BLUE "\033[38;5;4m"
+#define YELLOW "\033[38;5;11m"
+#define BOLD "\033[1m"
+#define RESET "\033[0m"
+static const char * const logo_lines[] = {
+ BLUE BOLD " ......::...... ",
+ BLUE BOLD " ...::::::::::::::::::... ",
+ BLUE BOLD " ..::::::::::::::::::::::::::.. ",
+ BLUE BOLD " .::::.:::::::::::::::...::::.::::. ",
+ BLUE BOLD " .::::::::::::::::::::..::::::::::::::. ",
+ BLUE BOLD " .::.:::::::::::::::::::" YELLOW "=*%#*" BLUE "::::::::::.::. ",
+ BLUE BOLD " .:::::::::::::::::....." YELLOW "*%%*-" BLUE ":....::::::::::. ",
+ BLUE BOLD " .:.:::...:::::::::.:-" YELLOW "===##*---==-" BLUE "::::::::::.:. ",
+ BLUE BOLD " .::::..::::........" YELLOW "-***#****###****-" BLUE "...::::::.:. ",
+ BLUE BOLD " ::.:.-" YELLOW "+***+=" BLUE "::-" YELLOW "=+**#%%%%%%%%%%%%###*= " BLUE "-::...::::. ",
+ BLUE BOLD ".:.::-" YELLOW "*****###%%%%%%%%%%%%%%%%%%%%%%%%%%#*=" BLUE ":..:::: ",
+ BLUE BOLD ".::" YELLOW "##" BLUE ":" YELLOW "***#%%%%%%#####%%%%%%%####%%%%%####%%%*" BLUE "-.::. ",
+ BLUE BOLD ":.:" YELLOW "#%" BLUE "::" YELLOW "*%%%%%%%#*****##%%%#*****##%%##*****#%%+" BLUE ".::.",
+ BLUE BOLD ".::" YELLOW "**==#%%%%%%%##****#%%%%##****#%%%%#****###%%" BLUE ":.. ",
+ BLUE BOLD "..:" YELLOW "#%" BLUE "::" YELLOW "*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#%%%%%+ " BLUE ".:.",
+ BLUE BOLD " ::" YELLOW "##" BLUE ":" YELLOW "+**#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%* " BLUE "-.:: ",
+ BLUE BOLD " ..::-" YELLOW "#****#%#%%%%%%%%%%%%%%%%%%%%%%%%%%#*=" BLUE "-..::. ",
+ BLUE BOLD " ...:=" YELLOW "*****=" BLUE "::-" YELLOW "=+**###%%%%%%%%###**+= " BLUE "--:...::: ",
+ BLUE BOLD " .::.::--:........::::::--::::::......::::::. ",
+ BLUE BOLD " .::.....::::::::::...........:::::::::.::. ",
+ BLUE BOLD " .::::::::::::::::::::::::::::::::::::. ",
+ BLUE BOLD " .::::.::::::::::::::::::::::.::::. ",
+ BLUE BOLD " ..::::::::::::::::::::::::::.. ",
+ BLUE BOLD " ...::::::::::::::::::... ",
+ BLUE BOLD " ......::...... ",
+};
+
+enum output_lines {
+ FIRST,
+ SECOND,
+ KERNEL,
+ SYSINFO,
+ HOST,
+ UPTIME,
+ IP,
+ CMDS,
+ CONSOLES,
+ FEATURES,
+ RELOCATION,
+ CORES,
+ MEMORY,
+ STORAGE,
+
+ /* Up to 10 storage devices... Should be enough for anyone right? */
+ _LAST_LINE = (STORAGE + 10),
+#define LAST_LINE (_LAST_LINE - 1UL)
+};
+
+/*
+ * TODO/ideas:
+ * - Refactor to not use a for loop
+ * - Handle multiple network interfaces
+ * - Include stats about number of bound/probed devices
+ * - Show U-Boot's size and malloc usage, fdt size, etc.
+ */
+
+
+static int do_ufetch(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ int num_lines = max(LAST_LINE + 1, ARRAY_SIZE(logo_lines));
+ const char *model, *compatible;
+ char *ipaddr;
+ int n_cmds, n_cpus = 0, ret, compatlen;
+ size_t size;
+ ofnode np;
+ struct udevice *dev;
+ struct blk_desc *desc;
+ bool skip_ascii = false;
+
+ if (argc > 1 && strcmp(argv[1], "-n") == 0) {
+ skip_ascii = true;
+ num_lines = LAST_LINE;
+ }
+
+ for (int line = 0; line < num_lines; line++) {
+ if (!skip_ascii) {
+ if (line < ARRAY_SIZE(logo_lines))
+ printf("%s ", logo_lines[line]);
+ else
+ printf("%*c ", LINE_WIDTH, ' ');
+ }
+ switch (line) {
+ case FIRST:
+ compatible = ofnode_read_string(ofnode_root(), "compatible");
+ if (!compatible)
+ compatible = "unknown";
+ printf(RESET "%s\n", compatible);
+ compatlen = strlen(compatible);
+ break;
+ case SECOND:
+ for (int j = 0; j < compatlen; j++)
+ putc('-');
+ putc('\n');
+ break;
+ case KERNEL:
+ printf("Kernel:" RESET " %s\n", U_BOOT_VERSION);
+ break;
+ case SYSINFO:
+ printf("Config:" RESET " %s_defconfig\n", CONFIG_SYS_CONFIG_NAME);
+ break;
+ case HOST:
+ model = ofnode_read_string(ofnode_root(), "model");
+ if (model)
+ printf("Host:" RESET " %s\n", model);
+ break;
+ case UPTIME:
+ printf("Uptime:" RESET " %ld seconds\n", get_timer(0) / 1000);
+ break;
+ case IP:
+ ipaddr = env_get("ipaddr");
+ if (!ipaddr)
+ ipaddr = "none";
+ printf("IP Address:" RESET " %s", ipaddr);
+ ipaddr = env_get("ipv6addr");
+ if (ipaddr)
+ printf(", %s\n", ipaddr);
+ else
+ putc('\n');
+ break;
+ case CMDS:
+ n_cmds = ll_entry_count(struct cmd_tbl, cmd);
+ printf("Commands:" RESET " %d (help)\n", n_cmds);
+ break;
+ case CONSOLES:
+ printf("Consoles:" RESET " %s", env_get("stdout"));
+ if (gd->baudrate)
+ printf(" (%d baud)", gd->baudrate);
+ putc('\n');
+ break;
+ case FEATURES:
+ printf("Features:" RESET " ");
+ if (IS_ENABLED(CONFIG_NET))
+ printf("Net");
+ if (IS_ENABLED(CONFIG_EFI_LOADER))
+ printf(", EFI");
+ if (IS_ENABLED(CONFIG_CMD_CAT))
+ printf(", cat :3");
+#ifdef CONFIG_ARM64
+ switch (current_el()) {
+ case 2:
+ printf(", VMs");
+ break;
+ case 3:
+ printf(", full control!");
+ break;
+ }
+#endif
+ printf("\n");
+ break;
+ case RELOCATION:
+ if (gd->flags & GD_FLG_SKIP_RELOC)
+ printf("Relocated:" RESET " no\n");
+ else
+ printf("Relocated:" RESET " to %#011lx\n", gd->relocaddr);
+ break;
+ case CORES:
+ ofnode_for_each_subnode(np, ofnode_path("/cpus")) {
+ if (ofnode_name_eq(np, "cpu"))
+ n_cpus++;
+ }
+ printf("CPU:" RESET " %d (1 in use)\n", n_cpus);
+ break;
+ case MEMORY:
+ for (int j = 0; j < CONFIG_NR_DRAM_BANKS && gd->bd->bi_dram[j].size; j++)
+ size += gd->bd->bi_dram[j].size;
+ printf("Memory:" RESET " ");
+ print_size(size, "\n");
+ break;
+ case STORAGE:
+ default:
+ ret = uclass_find_device_by_seq(UCLASS_BLK, line - STORAGE, &dev);
+ if (!ret && dev) {
+ desc = dev_get_uclass_plat(dev);
+ size = desc->lba * desc->blksz;
+ printf("%4s %d: " RESET, blk_get_uclass_name(desc->uclass_id),
+ desc->lun);
+ if (size)
+ print_size(size, "");
+ else
+ printf("No media");
+ } else if (ret == -ENODEV && (skip_ascii || line > ARRAY_SIZE(logo_lines))) {
+ break;
+ }
+ printf("\n");
+ }
+ }
+
+ printf(RESET "\n\n");
+
+ return 0;
+}
+
+U_BOOT_CMD(ufetch, 2, 1, do_ufetch,
+ "U-Boot fetch utility",
+ "Print information about your device.\n"
+ " -n Don't print the ASCII logo"
+);