说明
Linux启动log中会显示平台的内存信息,公司SOC,物理DRAM实际size是128M,但是启动log中total size不足128MB,并且预留内存(82272K reserved)过多,启动log如下:
Memory: 48032K/130304K available (3478K kernel code, 500K rwdata, 1504K rodata, 124K init, 212K bss, 82272K reserved, 0K cma-reserved)
total size:130304K,预留size 82272K相减得到剩余size(48032K)。
分析
平台使用memblock管理早期内存分配,打开memblock debug重启后,启动log如下:
memblock_reserve: [0x0000000080200000-0x00000000807bdfff] setup_bootmem+0x86/0x162
memblock_reserve: [0x0000000082dcd000-0x0000000082dd2fff] setup_bootmem+0xde/0x162
memblock_reserve: [0x0000000080000000-0x000000008007ffff] setup_bootmem+0x100/0x162
memblock_reserve: [0x0000000080000000-0x000000008007ffff] early_init_fdt_scan_reserved_mem+0x46/0x76
memblock_reserve: [0x0000000080000000-0x000000008003ffff] __fdt_scan_reserved_mem+0x20a/0x27a
memblock_reserve: [0x000000008377e000-0x000000008393ffff] fdt_init_reserved_mem+0x306/0x42a
memblock_reserve: [0x0000000083940000-0x0000000087f3ffff] fdt_init_reserved_mem+0x360/0x42a
Ion: Ion memory setup at 0x0000000083940000 size 70 MiB
OF: reserved mem: initialized node ion, compatible id ion-region
MEMBLOCK configuration:
memory size = 0x0000000007f40000 reserved size = 0x0000000004e06000
memory.cnt = 0x1
memory[0x0] [0x0000000080000000-0x0000000087f3ffff], 0x0000000007f40000 bytes flags: 0x0
reserved.cnt = 0x4
reserved[0x0] [0x0000000080000000-0x000000008007ffff], 0x0000000000080000 bytes flags: 0x0
reserved[0x1] [0x0000000080200000-0x00000000807bdfff], 0x00000000005be000 bytes flags: 0x0
reserved[0x2] [0x0000000082dcd000-0x0000000082dd2fff], 0x0000000000006000 bytes flags: 0x0
reserved[0x3] [0x000000008377e000-0x0000000087f3ffff], 0x00000000047c2000 bytes flags: 0x0
memblock_reserve: [0x000000008377d000-0x000000008377dfff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008377c000-0x000000008377cfff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008377b000-0x000000008377bfff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008377a000-0x000000008377afff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083779000-0x0000000083779fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083778000-0x0000000083778fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083777000-0x0000000083777fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083776000-0x0000000083776fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083775000-0x0000000083775fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083774000-0x0000000083774fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083773000-0x0000000083773fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083772000-0x0000000083772fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083771000-0x0000000083771fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083770000-0x0000000083770fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008376f000-0x000000008376ffff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008376e000-0x000000008376efff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008376d000-0x000000008376dfff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008376c000-0x000000008376cfff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008376b000-0x000000008376bfff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008376a000-0x000000008376afff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083769000-0x0000000083769fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083768000-0x0000000083768fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083767000-0x0000000083767fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083766000-0x0000000083766fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083765000-0x0000000083765fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083764000-0x0000000083764fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083763000-0x0000000083763fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083762000-0x0000000083762fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083761000-0x0000000083761fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083760000-0x0000000083760fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008375f000-0x000000008375ffff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008375e000-0x000000008375efff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008375d000-0x000000008375dfff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008375c000-0x000000008375cfff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008375b000-0x000000008375bfff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008375a000-0x000000008375afff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083759000-0x0000000083759fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083758000-0x0000000083758fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083757000-0x0000000083757fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083756000-0x0000000083756fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083755000-0x0000000083755fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083754000-0x0000000083754fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083753000-0x0000000083753fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083752000-0x0000000083752fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083751000-0x0000000083751fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083750000-0x0000000083750fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008374f000-0x000000008374ffff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008374e000-0x000000008374efff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008374d000-0x000000008374dfff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008374c000-0x000000008374cfff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008374b000-0x000000008374bfff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008374a000-0x000000008374afff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083749000-0x0000000083749fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083748000-0x0000000083748fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083747000-0x0000000083747fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083746000-0x0000000083746fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083745000-0x0000000083745fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083744000-0x0000000083744fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083743000-0x0000000083743fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083742000-0x0000000083742fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083741000-0x0000000083741fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x0000000083740000-0x0000000083740fff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008373f000-0x000000008373ffff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008373e000-0x000000008373efff] memblock_alloc_range_nid+0x96/0xc2
memblock_reserve: [0x000000008373d000-0x000000008373dfff] memblock_alloc_range_nid+0x96/0xc2
Zone ranges:
DMA32 [mem 0x0000000080000000-0x0000000087f3ffff]
Normal empty
Movable zone start for each node
Early memory node ranges
node 0: [mem 0x0000000080000000-0x0000000087f3ffff]
Initmem setup node 0 [mem 0x0000000080000000-0x0000000087f3ffff]
On node 0 totalpages: 32576
memblock_alloc_try_nid: 1835008 bytes align=0x40 nid=0 from=0x0000000000000000 max_addr=0x0000000000000000 alloc_node_mem_map.constprop.0+0x4c/0xd0
memblock_reserve: [0x000000008357d000-0x000000008373cfff] memblock_alloc_range_nid+0x96/0xc2
DMA32 zone: 446 pages used for memmap
DMA32 zone: 0 pages reserved
DMA32 zone: 32576 pages, LIFO batch:7
memblock_alloc_try_nid: 32 bytes align=0x40 nid=0 from=0x0000000000000000 max_addr=0x0000000000000000 setup_usemap.constprop.0+0x48/0x6c
memblock_reserve: [0x000000008357cfc0-0x000000008357cfdf] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 64 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 paging_init+0x228/0x2a2
memblock_reserve: [0x000000008357cf80-0x000000008357cfbf] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 96564 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x16/0x3e
memblock_reserve: [0x0000000083565648-0x000000008357cf7b] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 44 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x16/0x3e
memblock_reserve: [0x0000000083565618-0x0000000083565643] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 44 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x16/0x3e
memblock_reserve: [0x00000000835655e8-0x0000000083565613] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 44 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x16/0x3e
memblock_reserve: [0x00000000835655b8-0x00000000835655e3] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 44 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x16/0x3e
memblock_reserve: [0x0000000083565588-0x00000000835655b3] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 44 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x16/0x3e
memblock_reserve: [0x0000000083565558-0x0000000083565583] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 47 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x16/0x3e
memblock_reserve: [0x0000000083565528-0x0000000083565556] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 47 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x16/0x3e
memblock_reserve: [0x00000000835654f8-0x0000000083565526] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 47 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x16/0x3e
memblock_reserve: [0x00000000835654c8-0x00000000835654f6] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 47 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x16/0x3e
memblock_reserve: [0x0000000083565498-0x00000000835654c6] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 47 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x16/0x3e
memblock_reserve: [0x0000000083565468-0x0000000083565496] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 49 bytes align=0x8 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 early_init_dt_alloc_memory_arch+0x16/0x3e
memblock_reserve: [0x0000000083565430-0x0000000083565460] memblock_alloc_range_nid+0x96/0xc2
SBI specification v0.3 detected
SBI implementation ID=0x1 Version=0x9
SBI v0.2 TIME extension detected
SBI v0.2 IPI extension detected
SBI v0.2 RFENCE extension detected
riscv: ISA extensions acdfimsuv
riscv: ELF capabilities acdfimv
memblock_alloc_try_nid: 229 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 start_kernel+0x82/0x346
memblock_reserve: [0x0000000083565340-0x0000000083565424] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 229 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 start_kernel+0xb2/0x346
memblock_reserve: [0x0000000083565240-0x0000000083565324] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 4096 bytes align=0x1000 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 pcpu_alloc_alloc_info+0x44/0x78
memblock_reserve: [0x0000000083564000-0x0000000083564fff] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 32768 bytes align=0x1000 nid=-1 from=0x0000000080000000 max_addr=0x0000000000000000 setup_per_cpu_areas+0x2c/0x66
memblock_reserve: [0x000000008355c000-0x0000000083563fff] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 8 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 pcpu_setup_first_chunk+0x13a/0x36e
memblock_reserve: [0x0000000083565200-0x0000000083565207] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 8 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 pcpu_setup_first_chunk+0x168/0x36e
memblock_reserve: [0x00000000835651c0-0x00000000835651c7] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 4 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 pcpu_setup_first_chunk+0x178/0x36e
memblock_reserve: [0x0000000083565180-0x0000000083565183] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 8 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 pcpu_setup_first_chunk+0x188/0x36e
memblock_reserve: [0x0000000083565140-0x0000000083565147] memblock_alloc_range_nid+0x96/0xc2
pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
pcpu-alloc: [0] 0
memblock_alloc_try_nid: 240 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 pcpu_setup_first_chunk+0x224/0x36e
memblock_reserve: [0x0000000083565040-0x000000008356512f] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 128 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 pcpu_alloc_first_chunk+0x5c/0x19a
memblock_reserve: [0x000000008355bf80-0x000000008355bfff] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 1024 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 pcpu_alloc_first_chunk+0xa4/0x19a
memblock_reserve: [0x000000008355bb80-0x000000008355bf7f] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 1032 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 pcpu_alloc_first_chunk+0xc2/0x19a
memblock_reserve: [0x000000008355b740-0x000000008355bb47] memblock_alloc_range_nid+0x96/0xc2
memblock_alloc_try_nid: 256 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 pcpu_alloc_first_chunk+0xd8/0x19a
memblock_reserve: [0x000000008355b640-0x000000008355b73f] memblock_alloc_range_nid+0x96/0xc2
memblock_free: [0x0000000083564000-0x0000000083564fff] start_kernel+0xe0/0x346
Built 1 zonelists, mobility grouping on. Total pages: 32130
Kernel command line: rootfstype=squashfs rootwait ro root=/dev/mtdblock4 mtdparts=10000000.cvi-spif:1024K(fip),3072K(BOOT),64K(ENV),64K(ENV_BAK),10240K(ROOTFS),512K(DATA) console=ttyS0,115200 earlycon=sbi loglevel=9 riscv.fwsz=0x80000 memblock=debug
memblock_alloc_try_nid: 131072 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 alloc_large_system_hash+0x108/0x1d0
memblock_reserve: [0x000000008353b640-0x000000008355b63f] memblock_alloc_range_nid+0x96/0xc2
Dentry cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
memblock_alloc_try_nid: 65536 bytes align=0x40 nid=-1 from=0x0000000000000000 max_addr=0x0000000000000000 alloc_large_system_hash+0x108/0x1d0
memblock_reserve: [0x000000008352b640-0x000000008353b63f] memblock_alloc_range_nid+0x96/0xc2
Inode-cache hash table entries: 8192 (order: 4, 65536 bytes, linear)
Sorting __ex_table...
mem auto-init: stack:off, heap alloc:off, heap free:off
Memory: 48032K/130304K available (3478K kernel code, 500K rwdata, 1504K rodata, 124K init, 212K bss, 82272K reserved, 0K cma-reserved)
...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
total size由来
Linux感知的内存total size,可以通过uboot bootargs传递也可以通过dts配置,公司SOC使用dts配置,如下:
//file: xxx.dtsi
#include
/ {
memory@80000000 {
device_type = "memory";
reg = <0x00 XXXMMAP_KERNEL_MEMORY_ADDR 0x00 XXXMMAP_KERNEL_MEMORY_SIZE>;
};
....
};
为兼容多个平台,dts中使用头文件中的宏定义来定义物理内存地址和大小,头文件由脚本生成,如下:
//file: memmap.py
DRAM_BASE = 0x80000000
DRAM_SIZE = 128 * SIZE_1M
# 小核预留
FREERTOS_SIZE = 768 * SIZE_1K
....
# =========================
# memory@DRAM_BASE in .dts.
# =========================
# Ignore the area of FreeRTOS in u-boot and kernel
KERNEL_MEMORY_ADDR = DRAM_BASE
KERNEL_MEMORY_SIZE = DRAM_SIZE - FREERTOS_SIZE
因此kernel感知的实际total size(128MB * 1024 - 768 = 130304K)与启动log匹配。
memblock分配器初始化前的预留内存占用
MEMBLOCK configuration:
memory size = 0x0000000007f40000 reserved size = 0x0000000004e06000 //总size(130304K)和初始化前的预留内存占用size
memory.cnt = 0x1
memory[0x0] [0x0000000080000000-0x0000000087f3ffff], 0x0000000007f40000 bytes flags: 0x0 //总size(130304K)
reserved.cnt = 0x4 // 初始化前的预留内存占用
reserved[0x0] [0x0000000080000000-0x000000008007ffff], 0x0000000000080000 bytes flags: 0x0
reserved[0x1] [0x0000000080200000-0x00000000807bdfff], 0x00000000005be000 bytes flags: 0x0
reserved[0x2] [0x0000000082dcd000-0x0000000082dd2fff], 0x0000000000006000 bytes flags: 0x0
reserved[0x3] [0x000000008377e000-0x0000000087f3ffff], 0x00000000047c2000 bytes flags: 0x0
4块预留内存的详细分配记录(内存段相邻时会合并成一块)
memblock_reserve: [0x0000000080200000-0x00000000807bdfff] setup_bootmem+0x86/0x162
memblock_reserve: [0x0000000082dcd000-0x0000000082dd2fff] setup_bootmem+0xde/0x162
memblock_reserve: [0x0000000080000000-0x000000008007ffff] setup_bootmem+0x100/0x162
memblock_reserve: [0x0000000080000000-0x000000008007ffff] early_init_fdt_scan_reserved_mem+0x46/0x76
memblock_reserve: [0x0000000080000000-0x000000008003ffff] __fdt_scan_reserved_mem+0x20a/0x27a
memblock_reserve: [0x000000008377e000-0x000000008393ffff] fdt_init_reserved_mem+0x306/0x42a
memblock_reserve: [0x0000000083940000-0x0000000087f3ffff] fdt_init_reserved_mem+0x360/0x42a
//file: arch/riscv/mm/init.c
void __init setup_bootmem(void)
{
phys_addr_t mem_start = 0;
phys_addr_t start, end = 0;
phys_addr_t vmlinux_end = __pa_symbol(&_end);
phys_addr_t vmlinux_start = __pa_symbol(&_start);
u64 i;
/* Find the memory region containing the kernel */
for_each_mem_range(i, &start, &end) {
phys_addr_t size = end - start;
if (!mem_start)
mem_start = start;
if (start <= vmlinux_start && vmlinux_end <= end)
BUG_ON(size == 0);
}
/*
* The maximal physical memory size is -PAGE_OFFSET.
* Make sure that any memory beyond mem_start + (-PAGE_OFFSET) is removed
* as it is unusable by kernel.
*/
memblock_enforce_memory_limit(-PAGE_OFFSET);
/* Reserve from the start of the kernel to the end of the kernel */
memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);
max_pfn = PFN_DOWN(memblock_end_of_DRAM());
max_low_pfn = max_pfn;
set_max_mapnr(max_low_pfn);
#ifdef CONFIG_BLK_DEV_INITRD
setup_initrd();
#endif /* CONFIG_BLK_DEV_INITRD */
/*
* Avoid using early_init_fdt_reserve_self() since __pa() does
* not work for DTB pointers that are fixmap addresses
*/
memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
if (firmware_size > PAGE_SIZE && firmware_size < LOAD_OFFSET)
memblock_reserve(__pa(PAGE_OFFSET), firmware_size);
else
memblock_reserve(__pa(PAGE_OFFSET), LOAD_OFFSET);
...
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
kernel code等(大约6MB),大小是通过链接脚本ld.s中的符号(vmlinux_end,vmlinux_start)相减所得。 opensbi(512KB),大小是通过uboot传递过来的bootargs(riscv.fwsz=0x80000)所得。 dtb(32KB),大小:fdt_totalsize(dtb_early_va) dts中定义的ion(70MB)。 dts中定义的其它reserved_mem(大约2MB),根据分配记录(memblock_reserve)可以获取分配的具体信息。
memblock分配器初始化后的预留内存占用
启动log(MEMBLOCK configuration)后的分配打印就是memblock初始化成功后的预留内存占用。 根据代码和分配记录可知预留内存占用主要是内核机制(大约2.3MB),有一些大头,如下:
memmap setup_per_cpu_areas Dentry cache hash table entries Inode-cache hash table entries
预留内存占用统计
将预留内存占用(memblock_reserve)累加再减去预留内存释放(memblock_free)计算出总的预留内存占用为82269K。
问题
统计出的总预留内存size和打印不匹配
启动log中的预留内存总size(82272K reserved)和实际计算出的总size(82269K)不一致,是因为打印启动log时会做页对齐,对齐后就一样了,如下:
// file: linux_5.10/mm/page_alloc.c
void __init mem_init_print_info(const char *str)
{
...
pr_info("Memory: %luK/%luK available (%luK kernel code, %luK rwdata, %luK rodata, %luK init, %luK bss, %luK reserved, %luK cma-reserved"
#ifdef CONFIG_HIGHMEM
", %luK highmem"
#endif
"%s%s)\n",
nr_free_pages() << (PAGE_SHIFT - 10),
physpages << (PAGE_SHIFT - 10),
codesize >> 10, datasize >> 10, rosize >> 10,
(init_data_size + init_code_size) >> 10, bss_size >> 10,
(physpages - totalram_pages() - totalcma_pages) << (PAGE_SHIFT - 10), // 根据内存页size 对齐
totalcma_pages << (PAGE_SHIFT - 10),
#ifdef CONFIG_HIGHMEM
totalhigh_pages() << (PAGE_SHIFT - 10),
#endif
str ? ", " : "", str ? str : "");
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20