Boot time memory management

https://www.kernel.org/doc/html/latest/core-api/boot-time-mm.html

# Boot time memory management

> Early system initialization cannot use “normal” memory management simply because it is not set up yet. But there is still need to allocate memory for various data structures, for instance for the physical page allocator.

システムの初期化を開始した直後では、通常のメモリマネージャーは単純に利用できません、なぜならばそれの準備はまだできていないからです。しかしながら、例えば、physical page allocatorのように、さまざまなデータ構造に対するメモリを割り当てる必要があります。

> A specialized allocator called memblock performs the boot time memory management. The architecture specific initialization must set it up in setup_arch() and tear it down in mem_init() functions.

memblockと呼ばれる特別なallocatorは、起動時のmemory managementを実行します。アーキテクチャ固有の初期化処理では、setup_arch()で設定を行い、mem_init()関数でそれを破棄する必要があります。

> Once the early memory management is available it offers a variety of functions and macros for memory allocations. The allocation request may be directed to the first (and probably the only) node or to a particular node in a NUMA system. There are API variants that panic when an allocation fails and those that don’t.

early memory managementは有効になったら、memory allocationsのための様々な関数やマクロが有効になります。allocationは、NUMA systemにおいて最初の（そしておそらく唯一の）nodeや特定nodeに送信されます。割り当てに失敗した時に、panicになるAPIと、そうではないAPIがあります。

> Memblock also offers a variety of APIs that control its own behaviour.

Memblockはまた、自信の振る舞いを制御するための様々なAPIも提供しています。

# Memblock Overview

> Memblock is a method of managing memory regions during the early boot period when the usual kernel memory allocators are not up and running.

Memblockは、通常、kernel　memory allocatiorがまた起動も動作もしていないであろうearly boot periodにおけるmemory regionの管理する方法です。

> Memblock views the system memory as collections of contiguous regions. There are several types of these collections:

Memblockはsystem memroy を連続したregionの集合として捉えます。これらの集合にはいくつかのタイプがあります。

> ・memory - describes the physical memory available to the kernel; this may differ from the actual physical memory installed in the system, for instance when the memory is restricted with mem= command line parameter
・reserved - describes the regions that were allocated
・physmap - describes the actual physical memory regardless of the possible restrictions; the physmap type is only available on some architectures.

 ・memory - カーネルに対して、物理的なメモリを記述する；これは実際にシステムに装着されている物理メモリと異なる場合があります。例えば、mem= command line parameterによって、制限がなされている場合。
・reserved -すでにallocatedされているregion を記述する。
・physmap - 可能な制限に関係なく、実際の物理メモリを記述します。physmap typeは一部のアーキテクチャだけで利用できます。


> Each region is represented by struct memblock_region that defines the region extents, its attributes and NUMA node id on NUMA systems. Every memory type is described by the struct memblock_type which contains an array of memory regions along with the allocator metadata. The memory types are nicely wrapped with struct memblock. This structure is statically initialzed at build time. 

それぞれのregionは、region 範囲、その属性、NUMA systemではNUMA node idを定義する、構造体memblock_regionで表現されます。すべてのmemory typeは、struct memblock_typeで記述されます。それは、allocator metadataと共に、memory regionの配列を含みます。memory typeは、構造体memblockを上手く包み込みます。この構造体は、起動時に静的に初期化されます。

> The region arrays for the “memory” and “reserved” types are initially sized to INIT_MEMBLOCK_REGIONS and for the “physmap” type to INIT_PHYSMEM_REGIONS. The memblock_allow_resize() enables automatic resizing of the region arrays during addition of new regions. This feature should be used with care so that memory allocated for the region array will not overlap with areas that should be reserved, for example initrd.

"memory"と"reserved" typeであるregion arrayは、INIT_MEMBLOCK_REGIONSのサイズで初期化され、"physmap" typeでは、INIT_PHYSMEM_REGIONSです。memblock_allow_resize()は、新しいregionが追加される間、自動的にregion arrayのサイズを変更します。この機能は、region arrayに割り当てられたmemoryが例えばinitrdなどの予約する必要があるregionと重複しないように、気を付ける必要があります。

> The early architecture setup should tell memblock what the physical memory layout is by using memblock_add() or memblock_add_node() functions. The first function does not assign the region to a NUMA node and it is appropriate for UMA systems. Yet, it is possible to use it on NUMA systems as well and assign the region to a NUMA node later in the setup process using memblock_set_node(). The memblock_add_node() performs such an assignment directly.

初期のアーキテクチャーセットアップでは、memblock_add() or memblock_add_node() functionsを利用して、物理メモリレイアウトを、memblockへ通知する必要があります、最初の関数は領域をNUMA nodeに割り当てないので、UMAシステムに適しています。ただし、NUMAシステムでも利用可能です。memblock_set_node()を使ってセットアッププロセスを実行した後、NUMA nodeを割り当ててください。The memblock_add_node()は直接このような割り当てを実行します。

> Once memblock is setup the memory can be allocated using one of the API variants:

memblockでメモリがセットアップされると　、API variantsの１つを使ってメモリを割り当てることができます。

> ・memblock_phys_alloc*() - these functions return the physical address of the allocated memory
・memblock_alloc*() - these functions return the virtual address of the allocated memory.

・memblock_phys_alloc*() - これらの関数では、物理アドレスの確保されたメモリを戻値として返します。
・memblock_alloc*() - これらの関数では確保済みメモリの仮想アドレスを返します。

> Note, that both API variants use implict assumptions about allowed memory ranges and the fallback methods. Consult the documentation of memblock_alloc_internal() and memblock_alloc_range_nid() functions for more elaborate description.

どちらのAPI variantsでも許可されたメモリ範囲とfallback手段について、暗黙の過程を利用することに注意してください。より詳細な説明については、memblock_alloc_internal）およびmemblock_alloc_range_nid）関数のドキュメントを参照してください。

> As the system boot progresses, the architecture specific mem_init() function frees all the memory to the buddy page allocator.

system boot progressの時に、アーキテクチャ固有のmem_init()関数で、buddy page allocatorのメモリはすべて解放されます。

> Unless an architecture enables CONFIG_ARCH_KEEP_MEMBLOCK, the memblock data structures will be discarded after the system initialization completes.

アーキテクチャがCONFIG_ARCH_KEEP_MEMBLOCKを有効にしない限り、memblockデータ構造はシステムの初期化が完了した後に破棄されます。