doc: add lmb documentation
The LMB module has undergone significant changes in the recent past. Add a document which briefly describes what the LMB module does, and the changes that have been made to it's design since the 2025.01 release. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
@@ -17,7 +17,6 @@ U-Boot API documentation
|
||||
interrupt
|
||||
led
|
||||
linker_lists
|
||||
lmb
|
||||
logging
|
||||
nvmem
|
||||
part
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
Logical memory blocks
|
||||
=====================
|
||||
|
||||
.. kernel-doc:: include/lmb.h
|
||||
:internal:
|
||||
@@ -46,6 +46,7 @@ Implementation
|
||||
cedit
|
||||
event
|
||||
global_data
|
||||
lmb
|
||||
logging
|
||||
makefiles
|
||||
menus
|
||||
|
||||
166
doc/develop/lmb.rst
Normal file
166
doc/develop/lmb.rst
Normal file
@@ -0,0 +1,166 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
Logical Memory Blocks (LMB)
|
||||
===========================
|
||||
|
||||
U-Boot has support for reserving chunks of memory which is primarily
|
||||
used for loading images to the DRAM memory, before these are booted,
|
||||
or written to non-volatile storage medium. This functionality is
|
||||
provided through the Logical Memory Blocks (LMB) module.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The LMB module manages allocation requests for memory region not
|
||||
occupied by the U-Boot image. Allocation requests that are made
|
||||
through malloc() and similar functions result in memory getting
|
||||
allocated from the heap region, which is part of the U-Boot
|
||||
image. Typically, the heap memory is a few MiB in size. Loading an
|
||||
image like the linux kernel might require lot more memory than what
|
||||
the heap can provide. Such allocations are usually handled through the
|
||||
LMB module.
|
||||
|
||||
The U-Boot image typically gets relocated to the top of the usable
|
||||
DRAM memory region. A typical memory layout looks as follows::
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
--- +--------------+ <--- U-Boot ram top
|
||||
| | |
|
||||
| | Text |
|
||||
| +--------------+
|
||||
| | |
|
||||
| | Data |
|
||||
| +--------------+
|
||||
| | |
|
||||
| | BSS |
|
||||
U-Boot Image +--------------+
|
||||
| | |
|
||||
| | Heap |
|
||||
| | |
|
||||
| +--------------+
|
||||
| | |
|
||||
| | |
|
||||
| | Stack |
|
||||
| | |
|
||||
| | |
|
||||
--- +--------------+
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+--------------+ <--- ram start
|
||||
|
||||
|
||||
|
||||
The region of memory below the U-Boot image is the one controlled by
|
||||
the LMB module.
|
||||
|
||||
|
||||
Types of LMB Allocations
|
||||
------------------------
|
||||
|
||||
There are two classes of allocation requests that get made to the LMB
|
||||
module. One type of allocation requests are requesting memory of a
|
||||
particular number of bytes. This type of allocation is similar to that
|
||||
done using the malloc type of function calls. The other type of
|
||||
allocations, are requests made for a specific memory address. The
|
||||
second type of allocations are usually made for loading images to a
|
||||
particular memory address.
|
||||
|
||||
|
||||
LMB design Pre 2025.01
|
||||
----------------------
|
||||
|
||||
The earlier versions of U-Boot (pre 2025.01 release)
|
||||
had a local memory map based LMB implementation whereby it was
|
||||
possible to declare the LMB map inside a function or a C file. This
|
||||
design resulted in temporary, non-global LMB maps, which also allowed
|
||||
for re-use of memory. This meant that it was possible to use a region
|
||||
of memory to load some image, and subsequently the same region of
|
||||
memory could be used for loading a different image. A typical example
|
||||
of this usage would be loading an image to a memory address, followed
|
||||
by writing that image to some non-volatile storage medium. Once this
|
||||
is done, the same address can be used for loading a different image
|
||||
and then writing it to it's non-volatile storage
|
||||
destination. Typically, environment variables like `loadaddr`,
|
||||
`kernel_addr_r`, `ramdisk_addr_r` are used for loading images to
|
||||
memory regions.
|
||||
|
||||
|
||||
Current LMB implementation
|
||||
--------------------------
|
||||
|
||||
Changes were made in the 2025.01 release to make the LMB memory map
|
||||
global and persistent. With this, the LMB memory map is the same
|
||||
across all of U-Boot, and also persists as long as U-Boot is
|
||||
active. Even with this change, there has been consistency as far as
|
||||
re-use of memory is concerned to maintain backward compatibility. It
|
||||
is allowed for re-requesting the same region of memory if the memory
|
||||
region has a particular attribute (LMB_NONE).
|
||||
|
||||
As part of the platform boot, DRAM memory available for use in U-Boot
|
||||
gets added to the LMB memory map. Any allocation requests made
|
||||
subsequently will be made from this memory added as part of the board
|
||||
init.
|
||||
|
||||
|
||||
Allocation API
|
||||
--------------
|
||||
|
||||
Any request for non-heap memory can be made through the LMB allocation
|
||||
API.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int lmb_alloc_mem(enum lmb_mem_type type, u64 align,
|
||||
phys_addr_t *addr, phys_size_t size,
|
||||
u32 flags);
|
||||
|
||||
Correspondingly, the allocated memory can be free'd
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
long lmb_free(phys_addr_t base, phys_size_t size, u32 flags);
|
||||
|
||||
For a detailed API description, please refer to the header file.
|
||||
|
||||
|
||||
UEFI allocations with LMB as the backend
|
||||
----------------------------------------
|
||||
|
||||
The UEFI specification describes boot-time API's for allocation of
|
||||
memory. These API's use the same memory that is being used by the LMB
|
||||
module. Pre 2025.01 release, there wasn't any synchronisation between
|
||||
the EFI sub-system and the LMB module about the memory that was
|
||||
getting allocated by each of these modules. This was the primary
|
||||
reason for making the LMB memory map global and persistent. With this
|
||||
change, the EFI memory allocation API's have also been changed to use
|
||||
the LMB module as the backend for the allocation requests. Any other
|
||||
sub-system which might wish to use the same memory region for it's use
|
||||
can then use the LMB as the backend for the memory allocations and
|
||||
it's associated book-keeping.
|
||||
|
||||
|
||||
API documentation
|
||||
-----------------
|
||||
|
||||
.. kernel-doc:: include/lmb.h
|
||||
|
||||
Reference in New Issue
Block a user