Linux - 内存 - 预留内存占用分析
说明
- 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 = 0x0000000004e06000memory.cnt = 0x1memory[0x0] [0x0000000080000000-0x0000000087f3ffff], 0x0000000007f40000 bytes flags: 0x0reserved.cnt = 0x4reserved[0x0] [0x0000000080000000-0x000000008007ffff], 0x0000000000080000 bytes flags: 0x0reserved[0x1] [0x0000000080200000-0x00000000807bdfff], 0x00000000005be000 bytes flags: 0x0reserved[0x2] [0x0000000082dcd000-0x0000000082dd2fff], 0x0000000000006000 bytes flags: 0x0reserved[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 rangesnode 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/0xc2DMA32 zone: 446 pages used for memmapDMA32 zone: 0 pages reservedDMA32 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)
...
total size由来
- Linux感知的内存total size,可以通过uboot bootargs传递也可以通过dts配置,公司SOC使用dts配置,如下:
//file: xxx.dtsi #include <xxx.h>/ {memory@80000000 {device_type = "memory";reg = <0x00 XXXMMAP_KERNEL_MEMORY_ADDR 0x00 XXXMMAP_KERNEL_MEMORY_SIZE>;};....
};
- 为兼容多个平台,dts中使用头文件中的宏定义来定义物理内存地址和大小,头文件由脚本生成,如下:
//file: memmap.pyDRAM_BASE = 0x80000000DRAM_SIZE = 128 * SIZE_1M# 小核预留FREERTOS_SIZE = 768 * SIZE_1K....# =========================# memory@DRAM_BASE in .dts.# =========================# Ignore the area of FreeRTOS in u-boot and kernelKERNEL_MEMORY_ADDR = DRAM_BASEKERNEL_MEMORY_SIZE = DRAM_SIZE - FREERTOS_SIZE
- 因此kernel感知的实际total size(128MB * 1024 - 768 = 130304K)与启动log匹配。
memblock分配器初始化前的预留内存占用
- memblock初始化成功的配置
MEMBLOCK configuration:memory size = 0x0000000007f40000 reserved size = 0x0000000004e06000 //总size(130304K)和初始化前的预留内存占用sizememory.cnt = 0x1memory[0x0] [0x0000000080000000-0x0000000087f3ffff], 0x0000000007f40000 bytes flags: 0x0 //总size(130304K)reserved.cnt = 0x4 // 初始化前的预留内存占用reserved[0x0] [0x0000000080000000-0x000000008007ffff], 0x0000000000080000 bytes flags: 0x0reserved[0x1] [0x0000000080200000-0x00000000807bdfff], 0x00000000005be000 bytes flags: 0x0reserved[0x2] [0x0000000082dcd000-0x0000000082dd2fff], 0x0000000000006000 bytes flags: 0x0reserved[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_INITRDsetup_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);elsememblock_reserve(__pa(PAGE_OFFSET), LOAD_OFFSET);...
}
- 根据代码可知预留内存占用如下:
- 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_HIGHMEMtotalhigh_pages() << (PAGE_SHIFT - 10),
#endifstr ? ", " : "", str ? str : "");
}
相关文章:

Linux - 内存 - 预留内存占用分析
说明 Linux启动log中会显示平台的内存信息,公司SOC平台,物理DRAM实际size是128M,但是启动log中total size不足128MB,并且预留内存(82272K reserved)过多,启动log如下: Memory: 480…...

Java学习之路 —— Java高级
文章目录 前言1. 单元测试2. 反射2.1 获取Class对象的三种方式2.2 获取类的构造器的方法2.3 获取类的成员变量2.4 获取类的成员方法2.5 反射的作用 3. 注解3.1 自定义注解3.2 注解的原理3.3 元注解3.4 注解的解析 4. 动态代理5. 总结 前言 终于走到新手村的末端了,…...

git使用及常用命令
在初入公司中,若使用的是git管理工具,需要做以下步骤: 1,常用命令在: (1),git config --global user.name xxx(名字) //若不设置 那么下次提交代码时会报错 其次该设置名字和…...

vue 学习 -- day36(分析工程结构)
//引入的不再是Vue构造函数了,引入的是一个名为createApp的工厂函数 import { createApp } from vue import App from ./App.vue //创建应用实例对象——app(类似于之前Vue2中的vm,但app比vm更“轻”,它少了很多属性和方法) const app creat…...

SQL Injection
SQL Injection SQL injection(SQL注入),通过在输入字段或URL查询参数中执行SQL命令,导致对数据库的未经授权的访问。如果SQL注入成功,未经授权的人可能会读取、创建、更新甚至删除数据库表的记录 举个例子:…...

【Go入门】 Go搭建一个Web服务器
【Go入门】 Go搭建一个Web服务器 前面小节已经介绍了Web是基于http协议的一个服务,Go语言里面提供了一个完善的net/http包,通过http包可以很方便的搭建起来一个可以运行的Web服务。同时使用这个包能很简单地对Web的路由,静态文件,…...

VS 将 localhost访问改为ip访问
项目场景: 使用vs进行本地调试时需要多人访问界面,使用ip访问报错 问题描述 vs通过ip访问报错 虚拟机或其它电脑不能正常打开 原因分析: 原因是vs访问规则默认是iis,固定默认启动地址是localhost 解决方案: 1.vs项目启动之后会出现这个 右…...

app使用
font-face{font-family:‘kaishu’; src: url(data:application/font-ttf;charsetutf-8;base64,AAEAAAASAQAABAAgRFNJR5PpVzIAAAEsAAAacEdTVUIzhvftAAAbnAAAAXBPUy8yY8pHoQAAHQwAAABWY21hcAsTB9YAAB1kAADD5GN2dCAvAiIAADhSAAAA5pmcGdt/siFHQAA5OQAAAOiZ2FzcAAXAAkAAOiIAAAAEGds…...

【迅搜01】安装运行并测试XunSearch
安装运行并测试XunSearch 这回的新系列,我们将学习到的是一个搜索引擎 迅搜 XunSearch 的使用。这个搜索引擎在 PHP 圈可能还是有一点名气的,而且也是一直在更新的,虽说现在 ElasticSearch 已经是实际上的搜索引擎霸主了,而且还有…...

Mac电脑VSCode配置PHP开发环境
1.安装 PHP 首先,打开终端,安装 Homebrew,输入如下命令: $ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 安装了 Homebrew 之后,你可以使用下面的…...

SpirngBoot + Vue 前后端分离开发工具代码
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Java从入门到精通 ✨特色专栏…...

【数据结构初阶】单链表(附全部码源)
单链表 1,单链表的概念及结构2,单链表的实现2.1初始化内容(所需文件,接口)2.2申请结点2.3打印单链表2.4尾插2.5头插2.6尾删2.7头删2.8查找2.9在pos位置之后插入2.10在pos位置前面插入2.11删除pos之后的值2.12删除pos位…...

数据治理入门
处理模式 模式名称常见场景常见框架批处理夜间几个小时,无人值守hive spark datax流处理7*24H一直运行,无人值守maxwell, flink, flume, kafka即席处理人机交互接口访问 web页面 数据治理的意义 数据质量低:数据错误,不准确或不…...

uniapp 微信小程序登录 新手专用 引入即可
预览 第一步导入插件 在引入的页面的登录按钮下拷贝一下代码 <template><view class"content"><button type"primary" click"login">微信登录</button></view><TC-WXlogin :wxloginwxlogin /> </templ…...

PMCW体制雷达系列文章(4) – PMCW雷达之抗干扰
说明 本文作为PMCW体制雷达系列文章之一,主要聊聊FMCW&PMCW两种体制雷达的干扰问题。事实上不管是通信领域还是雷达领域,对于一切以电磁波作为媒介的信息传递活动,干扰是无处不在的。近年来,随着雷达装车率的提高,…...

Gin框架源码解析
概要 目录 Gin路由详解 Gin框架路由之Radix Tree 一、路由树节点 二、请求方法树 三、路由注册以及匹配 中间件含义 Gin框架中的中间件 主要讲述Gin框架路由和中间件的详细解释。本文章将从Radix树(基数树或者压缩前缀树)、请求处理、路由方法树…...

MacOS设置JAVA_HOME环境变量
首先先查看一下,系统当前使用的java是谁,可以使用/usr/libexec/java_home命令 % /usr/libexec/java_home /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home检查一下这个路径下的文件,发现这是一个jre的目录。加上-V参数看…...
闭眼检测实现
引言 这段代码是一个实时眼睛状态监测程序,可以用于监测摄像头捕获的人脸图像中的眼睛状态,判断眼睛是否闭合。具体应用实现作用说明如下: 1. 实时监测眼睛状态 通过摄像头捕获的实时视频流,检测人脸关键点并计算眼睛的 EAR&a…...

系列六、Java垃圾回收器主要有哪些?
一、Java垃圾回收器主要有哪些? UseSerialGC、UseParallelGC、UseConcMarkSweepGC、UseParallelNewGC、UseParallelOldGC、UseG1GC...

【7】Spring Boot 3 集成组件:缓存组件 spring cache + spring data redis
目录 【7】Spring Boot 3 集成组件:缓存组件 spring cache spring data redis什么是缓存抽象声明式注解JSR-107对应SpEL上下文数据 引入依赖cache 支持的缓存类型缓存类型配置NONESIMPLEREDIS自定义配置 CAFFEINE Hazelcast...总结 个人主页: 【⭐️个人主页】 需要…...

说说Java中的不可重入锁
什么是锁? 简单来讲在Java中,锁是一种用于并发控制的机制,用于保护共享资源,防止多个线程同时访问或修改数据导致的数据不一致性和线程安全问题。在Java虚拟机(JVM)中,每个对象都有一个相关联的…...

C++学习 --vector
目录 1, 什么是vector 2, 创建vector 2-1, 标准数据类型 2-2, 自定义数据类型 2-3, 其他创建方式 3, 操作vector 3-1, 赋值 3-2, 添加元素 3-2-1, 添加元素(assi…...
Android图片涂鸦,Kotlin(1)
Android图片涂鸦,Kotlin(1) import android.content.Context import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.Path import android.graphics.PointF import android.…...

upload-labs(1-17关攻略详解)
upload-labs pass-1 上传一个php文件,发现不行 但是这回显是个前端显示,直接禁用js然后上传 f12禁用 再次上传,成功 右键打开该图像 即为位置,使用蚁剑连接 连接成功 pass-2 源码 $is_upload false; $msg null; if (isse…...

《 机器人基础 》期末试卷(A)
一、填空题(30分,每空2分) 1. 按照相机的工作方式,机器人常用相机分为1)__ 单目摄像头 2)__ 双目摄像头 _ 3)_深度摄像头_ 三类。 2. 度量地图强调…...

Azure Machine Learning - Azure AI 搜索中的矢量搜索
矢量搜索是一种信息检索方法,它使用内容的数字表示形式来执行搜索方案。 由于内容是数字而不是纯文本,因此搜索引擎会匹配与查询最相似的矢量,而不需要匹配确切的字词。本文简要介绍了 Azure AI 搜索中的矢量支持。 其中还解释了与其他 Azure…...

3 redis实现一个消息中间件
使用list实现一个队列,可以从左侧入队,也可以从右侧入对 即可以从左侧读取,也可以从右侧读取 1、Lindex Lindex 命令用于通过索引获取列表中的元素 也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的…...

js添加dom到指定div之后,并给添加的dom类名,然后设置其样式,以及el-popover层级z-index过高问题解决。
遇到一个需求,Vue项目做一个表格,要求表头与表格内容分开,如下效果所示,表头与表格有个高度间隔边距(箭头所示),因为默认我们的el-table的表头与内容是一起的: 思路:通过querySelector获取el-table__header-wrapper元素,通过createElement创建一个div,通过 newElem…...

C语言结构体
#include <stdio.h> #include <string.h> #include <stdlib.h>//struct Student_s { // int num; // char name[20]; // char gender; // int age; // float Chinese; // float Math; // float English; // char addr[30]; //}; //最后的分号一定要写&#x…...

【Python大数据笔记_day10_Hive调优及Hadoop进阶】
hive调优 hive官方配置url: Configuration Properties - Apache Hive - Apache Software Foundation hive命令和参数配置 hive参数配置的意义: 开发Hive应用/调优时,不可避免地需要设定Hive的参数。设定Hive的参数可以调优HQL代码的执行效率,或帮助定位问…...