diff options
| author | Tom Rini <[email protected]> | 2025-06-25 09:57:01 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2025-06-25 09:57:01 -0600 |
| commit | b40d7b8f72f181d539b03c807d2dcaf864af552e (patch) | |
| tree | 09c88d38702458d0020d06ca0898ae0b62d4cc73 /doc/develop | |
| parent | 0862a8c48f226fffb832fd2a8501d70e68711e95 (diff) | |
| parent | 9b0ed9e69bcbc6af7115ddaee9536cf63b800c1d (diff) | |
Merge patch series "lmb: use a single API for all allocations"
Sughosh Ganu <[email protected]> says:
The LMB module has a bunch for API's which are used for allocating
memory. There are a couple of API's for requesting memory, and two
more for reserving regions of memory. Replace these different API's
with a single one, lmb_alloc_mem(). The type of allocation to be made
is specified through one of the parameters to the function.
Additionally, the two API's for reserving regions of memory,
lmb_reserve() and lmb_alloc_addr() are the same with one
difference. One can reserve any memory region with lmb_reserve(),
while lmb_alloc_addr() actually checks that the memory region being
requested is part of the LMB memory map. Reserving memory that is not
part of the LMB memory map is pretty futile -- the allocation
functions do not allocate memory which has not been added to the LMB
memory map.
This series also removes the functionality allowing for reserving
memory regions outside the LMB memory map. Any request for reserving a
region of memory outside the LMB memory map now returns an -EINVAL
error.
Certain places in the common code using the LMB API's were not
checking the return value of the functions. Checks have been added for
them. There are some calls being made from the architecture/platform
specific code which too do not check the return value. Those have been
kept the same, as I do not have the platform with me to check if it
causes any issues on those platforms.
In addition, there is a patch which refactors code in
lmb_overlaps_region() and lmb_can_reserve_region() so that both
functionalities can be put in a single function, lmb_overlap_checks().
Finally, a new patch has been added which checks the return value of
the lmb allocation function before copying the device-tree to the
allocated address.
Link: https://lore.kernel.org/r/[email protected]
[trini: Rework arch/arm/mach-snapdragon/board.c merge]
Signed-off-by: Tom Rini <[email protected]>
Diffstat (limited to 'doc/develop')
| -rw-r--r-- | doc/develop/index.rst | 1 | ||||
| -rw-r--r-- | doc/develop/lmb.rst | 166 |
2 files changed, 167 insertions, 0 deletions
diff --git a/doc/develop/index.rst b/doc/develop/index.rst index 0c83ef109ab..3c044e67927 100644 --- a/doc/develop/index.rst +++ b/doc/develop/index.rst @@ -46,6 +46,7 @@ Implementation cedit event global_data + lmb logging makefiles menus diff --git a/doc/develop/lmb.rst b/doc/develop/lmb.rst new file mode 100644 index 00000000000..b9d0f09c2bb --- /dev/null +++ b/doc/develop/lmb.rst @@ -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 + |
