Hi Caleb, Thank you for the patch.
On mer., nov. 13, 2024 at 05:22, Caleb Connolly <caleb.conno...@linaro.org> wrote: > 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 > > Signed-off-by: Caleb Connolly <caleb.conno...@linaro.org> Tested-by: Mattijs Korpershoek <mkorpersh...@baylibre.com> # vim3 > --- > Ephemeral screenshot: https://0x0.st/XkQU.png > > 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.conno...@linaro.org > --- > MAINTAINERS | 5 ++ > cmd/Kconfig | 7 ++ > cmd/Makefile | 1 + > cmd/ufetch.c | 224 +++++++++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 237 insertions(+) > create mode 100644 cmd/ufetch.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index 38c714cf46a6..d1eb164ad590 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -1724,8 +1724,13 @@ M: Heiko Schocher <h...@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.conno...@linaro.org> > +S: Maintained > +F: cmd/ufetch.c > + > UFS > M: Neil Armstrong <neil.armstr...@linaro.org> > M: Bhupesh Sharma <bhupesh.li...@gmail.com> > M: Neha Malcom Francis <n-fran...@ti.com> > diff --git a/cmd/Kconfig b/cmd/Kconfig > index 4fba9fe67034..da736249a3cf 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..1bd0565b9f08 > --- /dev/null > +++ b/cmd/ufetch.c > @@ -0,0 +1,224 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +/* Small "fetch" utility for U-Boot */ > + > +#ifdef CONFIG_ARM > +#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, > + DEVICES, > + 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) > +}; > + > +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 (%d baud)\n", > env_get("stdout"), > + gd->baudrate); > + break; > + case DEVICES: > + printf("Devices:" RESET " "); > + /* TODO: walk the DM tree */ > + printf("Uncountable!\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_ARM > + 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("%s %d: " RESET, desc->uclass_id == > UCLASS_SCSI ? "SCSI" : > + desc->uclass_id == UCLASS_MMC > + ? "MMC" : "Storage", > + desc->lun); > + if (size) > + print_size(size, ""); > + else > + printf("No media"); > + } > + 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" > +); > -- > 2.47.0