bootmem_init() – ARM64

<kernel v5.15>

부트 메모리 초기화

bootmem_init()

arch/arm64/mm/init.c

void __init bootmem_init(void)
{
        unsigned long min, max;

        min = PFN_UP(memblock_start_of_DRAM());
        max = PFN_DOWN(memblock_end_of_DRAM());

        early_memtest(min << PAGE_SHIFT, max << PAGE_SHIFT);

        max_pfn = max_low_pfn = max;
        min_low_pfn = min;

        arm64_numa_init();

        /*
         * must be done after arm64_numa_init() which calls numa_init() to
         * initialize node_online_map that gets used in hugetlb_cma_reserve()
         * while allocating required CMA size across online nodes.
         */
#if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_CMA)
        arm64_hugetlb_cma_reserve();
#endif

        dma_pernuma_cma_reserve();

        kvm_hyp_reserve();

        /*
         * sparse_init() tries to allocate memory from memblock, so must be
         * done after the fixed reservations
         */
        sparse_init();
        zone_sizes_init(min, max);

        /*
         * Reserve the CMA area after arm64_dma_phys_limit was initialised.
         */
        dma_contiguous_reserve(arm64_dma_phys_limit);

        /*
         * request_standard_resources() depends on crashkernel's memory being
         * reserved, so do it here.
         */
        reserve_crashkernel();

        memblock_dump_all();
}

부트 메모리 초기화 루틴에서는 각 노드의 각 존별 초기화를 수행한다.

  • 코드 라인 5~8에서 “memtest=<count>” 커널 파라메터가 주어진 경우 메모리에 대한 패턴 테스트를 <count> 수 만큼 수행한다.
  • 코드 라인 10에서 arm64에는 highmem이 없다. 따라서 highmem 경계를 나타내는 max_low_pfn은 max 값과 동일하다.
  • 코드 라인 11에서 min_low_pfn에 위에서 산출한 min 값을 대입한다.
  • 코드 라인 13에서 NUMA 시스템인 경우 초기화를 수행한다. ACPI 또는 디바이스 트리를 통해 초기화를 수행한다. ACPI 또는 디바이스 트리를 통해 NUMA 초기화를 수행하지 못하는 경우이거나,  “numa=off” 커널 파라메터가 주어진 경우 NUMA disable 상태로 초기화를 수행한다.
  • 코드 라인 21에서 ‘hugetlb_cma=’ 명령을 사용하여 cma 영역에 hugetlb를 지원하도록 한다.
  • 코드 라인 24에서 “cma_pernuma=size” 명령을 사용하여 NUMA 별 cma 영역을 사용할 수 있게 한다.
  • 코드 라인 26에서 kvm 하이퍼 바이저 모듈을 위한 영역을 reserve 한다.
  • 코드 라인 32에서 Sparse memory 모델을 사용하는 시스템을 위해 관리 영역을 할당받고 매핑 초기화한다.
  • 코드 라인 33에서 존별로 메모리 영역을 지정하고 초기화한다.
  • 코드 라인 38에서 dma 사용을 위한 cma 영역을 reserve 한다.
  • 코드 라인 44에서 크래시 상황에서 크래시 커널을 기동하여 크래시 로그를 출력할 수 있도록 크래시커널용 영역을 reserve 한다.
  • 코드 라인 46에서 “memblock=debug” 커널 파라메터가 주어진 경우 memblock 상태를 덤프한다.

 

다음은 4G RAM을 가진 rock960 보드의 memblock 상태를 덤프하여 보여준다.

$ cat /sys/kernel/debug/memblock/memory
   0: 0x0000000000200000..0x00000000f7ffffff
$ cat /sys/kernel/debug/memblock/reserved
   0: 0x0000000002080000..0x00000000033b5fff
   1: 0x00000000ef400000..0x00000000f5dfffff
   2: 0x00000000f5eef000..0x00000000f5f01fff
   3: 0x00000000f6000000..0x00000000f7bfffff
   4: 0x00000000f7df4000..0x00000000f7df4fff
   5: 0x00000000f7df5e00..0x00000000f7df5fff
   6: 0x00000000f7e74000..0x00000000f7f61fff
   7: 0x00000000f7f62600..0x00000000f7f6265f
   8: 0x00000000f7f62680..0x00000000f7f626df
   9: 0x00000000f7f62700..0x00000000f7f6282f
  10: 0x00000000f7f62840..0x00000000f7f62857
  11: 0x00000000f7f62880..0x00000000f7f62887
  12: 0x00000000f7f648c0..0x00000000f7f6492b
  13: 0x00000000f7f64940..0x00000000f7f649ab
  14: 0x00000000f7f649c0..0x00000000f7f64a2b
  15: 0x00000000f7f64a40..0x00000000f7f64a47
  16: 0x00000000f7f64a64..0x00000000f7f64aea
  17: 0x00000000f7f64aec..0x00000000f7f64b1a
  18: 0x00000000f7f64b1c..0x00000000f7f64b4a
  19: 0x00000000f7f64b4c..0x00000000f7f64b7a
  20: 0x00000000f7f64b7c..0x00000000f7f64baa
  21: 0x00000000f7f64bac..0x00000000f7fcdff7
  22: 0x00000000f7fce000..0x00000000f7ffffff

 


 

참고

 

댓글 남기기