From f18c048e6e6194b4f64d440f514dc158e4eb12a7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 21 Oct 2024 10:19:30 +0200 Subject: [PATCH] cmd: Update the meminfo command to show the memory map U-Boot has a fairly rigid memory map which is normally not visible unless debugging is enabled in board_f.c Update the 'meminfo' command to show it. This command does not cover arch-specific pieces but gives a good overview of where things are. Signed-off-by: Simon Glass --- cmd/Kconfig | 11 ++++ cmd/meminfo.c | 51 ++++++++++++++- doc/usage/cmd/meminfo.rst | 128 ++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + test/cmd/Makefile | 3 +- test/cmd/meminfo.c | 38 +++++++++++ 6 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 doc/usage/cmd/meminfo.rst create mode 100644 test/cmd/meminfo.c diff --git a/cmd/Kconfig b/cmd/Kconfig index ec2fe7ad35..f79fda64a9 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -889,6 +889,17 @@ config CMD_MEMINFO help Display memory information. +config CMD_MEMINFO_MAP + bool "- with memory map" + depends on CMD_MEMINFO + default y if SANDBOX + help + Shows a memory map, in addition to just the DRAM size. This allows + seeing where U-Boot's memory area is, at the top of DRAM, as well as + detail about each piece of it. + + See doc/usage/cmd/meminfo.rst for more information. + config CMD_MEMORY bool "md, mm, nm, mw, cp, cmp, base, loop" default y diff --git a/cmd/meminfo.c b/cmd/meminfo.c index bb9bcec2e3..0e6d2f9cc2 100644 --- a/cmd/meminfo.c +++ b/cmd/meminfo.c @@ -4,18 +4,67 @@ * Written by Simon Glass */ +#include +#include #include #include +#include +#include #include DECLARE_GLOBAL_DATA_PTR; +static void print_region(const char *name, ulong base, ulong size, ulong *uptop) +{ + ulong end = base + size; + + printf("%-12s %8lx %8lx %8lx", name, base, size, end); + if (*uptop) + printf(" %8lx", *uptop - end); + putc('\n'); + *uptop = base; +} + static int do_meminfo(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) + char *const argv[]) { + ulong upto, stk_bot; + puts("DRAM: "); print_size(gd->ram_size, "\n"); + if (!IS_ENABLED(CONFIG_CMD_MEMINFO_MAP)) + return 0; + + printf("\n%-12s %8s %8s %8s %8s\n", "Region", "Base", "Size", "End", + "Gap"); + printf("------------------------------------------------\n"); + upto = 0; + if (IS_ENABLED(CONFIG_VIDEO)) + print_region("video", gd_video_bottom(), + gd_video_size(), &upto); + if (IS_ENABLED(CONFIG_TRACE)) + print_region("trace", map_to_sysmem(gd_trace_buff()), + gd_trace_size(), &upto); + print_region("code", gd->relocaddr, gd->mon_len, &upto); + print_region("malloc", map_to_sysmem((void *)mem_malloc_start), + mem_malloc_end - mem_malloc_start, &upto); + print_region("board_info", map_to_sysmem(gd->bd), + sizeof(struct bd_info), &upto); + print_region("global_data", map_to_sysmem((void *)gd), + sizeof(struct global_data), &upto); + print_region("devicetree", map_to_sysmem(gd->fdt_blob), + fdt_totalsize(gd->fdt_blob), &upto); + if (IS_ENABLED(CONFIG_BOOTSTAGE)) + print_region("bootstage", map_to_sysmem(gd_bootstage()), + bootstage_get_size(false), &upto); + if (IS_ENABLED(CONFIG_BLOBLIST)) + print_region("bloblist", map_to_sysmem(gd_bloblist()), + bloblist_get_total_size(), &upto); + stk_bot = gd->start_addr_sp - CONFIG_STACK_SIZE; + print_region("stack", stk_bot, CONFIG_STACK_SIZE, &upto); + print_region("free", gd->ram_base, stk_bot, &upto); + return 0; } diff --git a/doc/usage/cmd/meminfo.rst b/doc/usage/cmd/meminfo.rst new file mode 100644 index 0000000000..6c94493ccc --- /dev/null +++ b/doc/usage/cmd/meminfo.rst @@ -0,0 +1,128 @@ +.. SPDX-License-Identifier: GPL-2.0+: + +.. index:: + single: meminfo (command) + +meminfo command +=============== + +Synopsis +-------- + +:: + + meminfo + +Description +----------- + +The meminfo command shows the amount of memory. If ``CONFIG_CMD_MEMINFO_MAP`` is +enabled, then it also shows the layout of memory used by U-Boot and the region +which is free for use by images. + +The layout of memory is set up before relocation, within the init sequence in +``board_init_f()``, specifically the various ``reserve_...()`` functions. This +'reservation' of memory starts from the top of RAM and proceeds downwards, +ending with the stack. This results in the maximum possible amount of memory +being left free for image-loading. + +The meminfo command writes the DRAM size, then the rest of its outputs in 5 +columns: + +Region + Name of the region + +Base + Base address of the region, i.e. where it starts in memory + +Size + Size of the region, which may be a little smaller than the actual size + reserved, e.g. due to alignment + +End + End of the region. The last byte of the region is one lower than the address + shown here + +Gap + Gap between the end of this region and the base of the one above + +Regions shown are: + +video + Memory reserved for video framebuffers. This reservation happens in the + bind() methods of all video drivers which are present before relocation, + so the size depends on that maximum amount of memory which all such drivers + want to reserve. This may be significantly greater than the amount actually + needed, if the display is ultimately set to a smaller resolution or colour + depth than the maximum supported. + +code + U-Boot's code and Block-Starting Symbol (BSS) region. Before relocation, + U-Boot copies its code to a high region and sets up a BSS immediately after + that. The size of this region is generally therefore ``__bss_end`` - + ``__image_copy_start`` + +malloc + Contains the malloc() heap. The size of this is set by + ``CONFIG_SYS_MALLOC_LEN``. + +board_info + Contains the ``bd_info`` structure, with some information about the current + board. + +global_data + Contains the global-data structure, pointed to by ``gd``. This includes + various pointers, values and flags which control U-Boot. + +devicetree + Contains the flatted devicetree blob (FDT) being used by U-Boot to configure + itself and its devices. + +bootstage + Contains the bootstage records, which keep track of boot time as U-Boot + executes. The size of this is determined by + ``CONFIG_BOOTSTAGE_RECORD_COUNT``, with each record taking approximately + 32 bytes. + +bloblist + Contains the bloblist, which is a list of tables and other data created by + U-Boot while executed. The size of this is determined by + ``CONFIG_BLOBLIST_SIZE``. + +stack + Contains U-Boot's stack, growing downwards from the top. The nominal size of + this region is set by ``CONFIG_STACK_SIZE`` but there is no actual limit + enforced, so the stack can grow behind that. Images should be loaded lower + in memory to avoid any conflict. + +free + Free memory, which is available for loading images. The base address of + this is ``gd->ram_base`` which is generally set by ``CFG_SYS_SDRAM_BASE``. + +Example +------- + +This example shows output with both ``CONFIG_CMD_MEMINFO`` and +``CONFIG_CMD_MEMINFO_MAP`` enabled:: + + => meminfo + DRAM: 256 MiB + + Region Base Size End Gap + ------------------------------------------------ + video f000000 1000000 10000000 + code ec3a000 3c5d28 efffd28 2d8 + malloc 8c38000 6002000 ec3a000 0 + board_info 8c37f90 68 8c37ff8 8 + global_data 8c37d80 208 8c37f88 8 + devicetree 8c33000 4d7d 8c37d7d 3 + bootstage 8c32c20 3c8 8c32fe8 18 + bloblist 8c32000 400 8c32400 820 + stack 7c31ff0 1000000 8c31ff0 10 + free 0 7c31ff0 7c31ff0 0 + + +Return value +------------ + +The return value $? is always 0 (true). diff --git a/doc/usage/index.rst b/doc/usage/index.rst index b84d8ee909..db71711c39 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -84,6 +84,7 @@ Shell commands cmd/loads cmd/loadx cmd/loady + cmd/meminfo cmd/mbr cmd/md cmd/mmc diff --git a/test/cmd/Makefile b/test/cmd/Makefile index 4080835096..4b487c1d2c 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -19,8 +19,9 @@ obj-$(CONFIG_CMD_FDT) += fdt.o obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o obj-$(CONFIG_CMD_HISTORY) += history.o obj-$(CONFIG_CMD_LOADM) += loadm.o -obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o +obj-$(CONFIG_CMD_MEMINFO) += meminfo.o obj-$(CONFIG_CMD_MEMORY) += mem_copy.o +obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o ifdef CONFIG_CMD_PCI obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o endif diff --git a/test/cmd/meminfo.c b/test/cmd/meminfo.c new file mode 100644 index 0000000000..84981305bf --- /dev/null +++ b/test/cmd/meminfo.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for 'meminfo' command + * + * Copyright 2024 Google LLC + * Written by Simon Glass + */ + +#include +#include +#include + +/* Test 'meminfo' command */ +static int cmd_test_meminfo(struct unit_test_state *uts) +{ + ut_assertok(run_command("meminfo", 0)); + ut_assert_nextline("DRAM: 256 MiB"); + ut_assert_nextline_empty(); + + ut_assert_nextline("Region Base Size End Gap"); + ut_assert_nextlinen("-"); + + /* For now we don't worry about checking the values */ + ut_assert_nextlinen("video"); + ut_assert_nextlinen("code"); + ut_assert_nextlinen("malloc"); + ut_assert_nextlinen("board_info"); + ut_assert_nextlinen("global_data"); + ut_assert_nextlinen("devicetree"); + ut_assert_nextlinen("bootstage"); + ut_assert_nextlinen("bloblist"); + ut_assert_nextlinen("stack"); + ut_assert_nextlinen("free"); + ut_assert_console_end(); + + return 0; +} +CMD_TEST(cmd_test_meminfo, UTF_CONSOLE); -- 2.39.5