]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
cmd: Update the meminfo command to show the memory map
authorSimon Glass <sjg@chromium.org>
Mon, 21 Oct 2024 08:19:30 +0000 (10:19 +0200)
committerTom Rini <trini@konsulko.com>
Fri, 25 Oct 2024 20:22:24 +0000 (14:22 -0600)
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 <sjg@chromium.org>
cmd/Kconfig
cmd/meminfo.c
doc/usage/cmd/meminfo.rst [new file with mode: 0644]
doc/usage/index.rst
test/cmd/Makefile
test/cmd/meminfo.c [new file with mode: 0644]

index ec2fe7ad35c3ac89465b006c0dffb298b82d58cb..f79fda64a944cafded175150d7b34973db1c3ec6 100644 (file)
@@ -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
index bb9bcec2e3f17eb4e07be7cfd22af0d02f5e8734..0e6d2f9cc2c61a9d8adc6ee74e45b0cb4d1d504c 100644 (file)
@@ -4,18 +4,67 @@
  * Written by Simon Glass <sjg@chromium.org>
  */
 
+#include <bloblist.h>
+#include <bootstage.h>
 #include <command.h>
 #include <display_options.h>
+#include <malloc.h>
+#include <mapmem.h>
 #include <asm/global_data.h>
 
 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 (file)
index 0000000..6c94493
--- /dev/null
@@ -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).
index b84d8ee909fb495ff035679a30170bdcca954661..db71711c3938efbfb5cc321492e6ccb2e5aa9044 100644 (file)
@@ -84,6 +84,7 @@ Shell commands
    cmd/loads
    cmd/loadx
    cmd/loady
+   cmd/meminfo
    cmd/mbr
    cmd/md
    cmd/mmc
index 408083509629fe44b40a8c237a691125630dff16..4b487c1d2cb4a847bc8972ebeeb7fe9bdf07d400 100644 (file)
@@ -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 (file)
index 0000000..8498130
--- /dev/null
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for 'meminfo' command
+ *
+ * Copyright 2024 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <dm/test.h>
+#include <test/cmd.h>
+#include <test/ut.h>
+
+/* 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);