Message ID | 20241114200856.3450012-1-caleb.connolly@linaro.org |
---|---|
State | New |
Headers | show |
Series | [v3] cmd: add a fetch utility | expand |
Am 14. November 2024 21:08:44 MEZ schrieb Caleb Connolly <caleb.connolly@linaro.org>: >Add a small utility for displaying some information about U-Boot and the >hardware it's running on in a similar fashion to the popular neofetch >tool for Linux [1]. > >While the output is meant to be useful, it should also be pleasing to >look at and perhaps entertaining. The ufetch command aims to bring this >to U-Boot, featuring a colorful ASCII art version of the U-Boot logo. > >[1]: https://en.wikipedia.org/wiki/Neofetch > >Reviewed-by: Simon Glass <sjg@chromium.org> >Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> >Tested-by: Mattijs Korpershoek <mkorpershoek@baylibre.com> # vim3 >Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8560-QRD >Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org> Acked-by: Heinrich Schuchardt <xypron.glpk@gmx.de> >--- >For additional background/context see v1 thread. > >I've enabled this for sandbox so it at least gets build-tested in CI as >Simon originally suggested in v1. > >Changes since v2: > * Fix building on 32-bit ARM > * Enable for sandbox to avoid build regressions > * Remove unused Devices line > * Use blk_get_uclass_name() > * Add TODO/ideas comment > * Avoid printing blank lines at the end when running with -n > * V2: https://lore.kernel.org/u-boot/20241113042536.1792150-2-caleb.connolly@linaro.org > >Changes since v1: > * Rework storage info to be more dynamic > * use print_size() helper everywhere > * manually walk RAM banks to report memory size correctly > * minor formatting changes and fixes > * MAINTAINERS entry > * V1: https://lore.kernel.org/u-boot/20240808163153.2069650-1-caleb.connolly@linaro.org >--- > MAINTAINERS | 5 + > cmd/Kconfig | 7 ++ > cmd/Makefile | 1 + > cmd/ufetch.c | 229 ++++++++++++++++++++++++++++++++++++++ > configs/sandbox_defconfig | 1 + > 5 files changed, 243 insertions(+) > create mode 100644 cmd/ufetch.c > >diff --git a/MAINTAINERS b/MAINTAINERS >index 0399ed1dbf64..1d81bdecc7c3 100644 >--- a/MAINTAINERS >+++ b/MAINTAINERS >@@ -1732,8 +1732,13 @@ M: Heiko Schocher <hs@denx.de> > S: Maintained > T: git https://source.denx.de/u-boot/custodians/u-boot-ubi.git > F: drivers/mtd/ubi/ > >+UFETCH >+M: Caleb Connolly <caleb.connolly@linaro.org> >+S: Maintained >+F: cmd/ufetch.c >+ > UFS > M: Neil Armstrong <neil.armstrong@linaro.org> > M: Bhupesh Sharma <bhupesh.linux@gmail.com> > M: Neha Malcom Francis <n-francis@ti.com> >diff --git a/cmd/Kconfig b/cmd/Kconfig >index 636833646f6e..253fbdfe1dd1 100644 >--- a/cmd/Kconfig >+++ b/cmd/Kconfig >@@ -175,8 +175,15 @@ config CMD_CPU > number of CPUs, type (e.g. manufacturer, architecture, product or > 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 > help >diff --git a/cmd/Makefile b/cmd/Makefile >index d1f369deec0a..1e6d3128c8ca 100644 >--- a/cmd/Makefile >+++ b/cmd/Makefile >@@ -52,8 +52,9 @@ obj-$(CONFIG_CMD_CONSOLE) += console.o > 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 > endif >diff --git a/cmd/ufetch.c b/cmd/ufetch.c >new file mode 100644 >index 000000000000..61bf264d2afb >--- /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("ipvaddr"); >+ 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" >+); >diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig >index d111858082d5..fb2b5ff54f4a 100644 >--- a/configs/sandbox_defconfig >+++ b/configs/sandbox_defconfig >@@ -50,8 +50,9 @@ CONFIG_LOG_DEFAULT_LEVEL=6 > CONFIG_LOGF_FUNC=y > CONFIG_DISPLAY_BOARDINFO_LATE=y > CONFIG_STACKPROTECTOR=y > CONFIG_CMD_CPU=y >+CONFIG_CMD_UFETCH=y > CONFIG_CMD_LICENSE=y > CONFIG_CMD_SMBIOS=y > CONFIG_CMD_BOOTM_PRE_LOAD=y > CONFIG_CMD_BOOTZ=y
On 11/14/24 9:08 PM, Caleb Connolly wrote: [...] > + case IP: > + ipaddr = env_get("ipvaddr"); ipvaddr with 'v' in the middle ? Shouldn't that be 'ipaddr' ? > + if (!ipaddr) > + ipaddr = "none";
On Thu, Nov 14, 2024 at 1:36 PM Marek Vasut <marex@denx.de> wrote: > > On 11/14/24 9:08 PM, Caleb Connolly wrote: > > [...] > > > + case IP: > > + ipaddr = env_get("ipvaddr"); > > ipvaddr with 'v' in the middle ? Shouldn't that be 'ipaddr' ? > > > + if (!ipaddr) > > + ipaddr = "none"; Other than that ipaddr. Tested-by: Tony Dinh <mibodhi@gmail.com> All the best, Tony
diff --git a/MAINTAINERS b/MAINTAINERS index 0399ed1dbf64..1d81bdecc7c3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1732,8 +1732,13 @@ M: Heiko Schocher <hs@denx.de> S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-ubi.git F: drivers/mtd/ubi/ +UFETCH +M: Caleb Connolly <caleb.connolly@linaro.org> +S: Maintained +F: cmd/ufetch.c + UFS M: Neil Armstrong <neil.armstrong@linaro.org> M: Bhupesh Sharma <bhupesh.linux@gmail.com> M: Neha Malcom Francis <n-francis@ti.com> diff --git a/cmd/Kconfig b/cmd/Kconfig index 636833646f6e..253fbdfe1dd1 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -175,8 +175,15 @@ config CMD_CPU number of CPUs, type (e.g. manufacturer, architecture, product or 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 help diff --git a/cmd/Makefile b/cmd/Makefile index d1f369deec0a..1e6d3128c8ca 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -52,8 +52,9 @@ obj-$(CONFIG_CMD_CONSOLE) += console.o 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 endif diff --git a/cmd/ufetch.c b/cmd/ufetch.c new file mode 100644 index 000000000000..61bf264d2afb --- /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("ipvaddr"); + 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" +); diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index d111858082d5..fb2b5ff54f4a 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -50,8 +50,9 @@ CONFIG_LOG_DEFAULT_LEVEL=6 CONFIG_LOGF_FUNC=y CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_STACKPROTECTOR=y CONFIG_CMD_CPU=y +CONFIG_CMD_UFETCH=y CONFIG_CMD_LICENSE=y CONFIG_CMD_SMBIOS=y CONFIG_CMD_BOOTM_PRE_LOAD=y CONFIG_CMD_BOOTZ=y