当前位置: 首页 > news >正文

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);...
} 
  • 根据代码可知预留内存占用如下:
  1. kernel code等(大约6MB),大小是通过链接脚本ld.s中的符号(vmlinux_end,vmlinux_start)相减所得。
  2. opensbi(512KB),大小是通过uboot传递过来的bootargs(riscv.fwsz=0x80000)所得。
  3. dtb(32KB),大小:fdt_totalsize(dtb_early_va)
  4. dts中定义的ion(70MB)。
  5. dts中定义的其它reserved_mem(大约2MB),根据分配记录(memblock_reserve)可以获取分配的具体信息。

memblock分配器初始化后的预留内存占用

  • 启动log(MEMBLOCK configuration)后的分配打印就是memblock初始化成功后的预留内存占用。
  • 根据代码和分配记录可知预留内存占用主要是内核机制(大约2.3MB),有一些大头,如下:
  1. memmap
  2. setup_per_cpu_areas
  3. Dentry cache hash table entries
  4. Inode-cache hash table entries
  • 不同内核机制的分配,待分析。

预留内存占用统计

  • 将预留内存占用(memblock_reserve)累加再减去预留内存释放(memblock_free)计算出总的预留内存占用为82269K。

问题

  1. 统计出的总预留内存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中会显示平台的内存信息&#xff0c;公司SOC平台&#xff0c;物理DRAM实际size是128M&#xff0c;但是启动log中total size不足128MB&#xff0c;并且预留内存&#xff08;82272K reserved&#xff09;过多&#xff0c;启动log如下&#xff1a; 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. 总结 前言 终于走到新手村的末端了&#xff0c;…...

git使用及常用命令

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

vue 学习 -- day36(分析工程结构)

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

SQL Injection

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

【Go入门】 Go搭建一个Web服务器

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

VS 将 localhost访问改为ip访问

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

app使用

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

【迅搜01】安装运行并测试XunSearch

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

Mac电脑VSCode配置PHP开发环境

1.安装 PHP 首先&#xff0c;打开终端&#xff0c;安装 Homebrew&#xff0c;输入如下命令&#xff1a; $ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 安装了 Homebrew 之后&#xff0c;你可以使用下面的…...

SpirngBoot + Vue 前后端分离开发工具代码

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Java从入门到精通 ✨特色专栏&#xf…...

【数据结构初阶】单链表(附全部码源)

单链表 1&#xff0c;单链表的概念及结构2&#xff0c;单链表的实现2.1初始化内容&#xff08;所需文件&#xff0c;接口&#xff09;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位…...

数据治理入门

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

uniapp 微信小程序登录 新手专用 引入即可

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

PMCW体制雷达系列文章(4) – PMCW雷达之抗干扰

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

Gin框架源码解析

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

MacOS设置JAVA_HOME环境变量

首先先查看一下&#xff0c;系统当前使用的java是谁&#xff0c;可以使用/usr/libexec/java_home命令 % /usr/libexec/java_home /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home检查一下这个路径下的文件&#xff0c;发现这是一个jre的目录。加上-V参数看…...

闭眼检测实现

引言 这段代码是一个实时眼睛状态监测程序&#xff0c;可以用于监测摄像头捕获的人脸图像中的眼睛状态&#xff0c;判断眼睛是否闭合。具体应用实现作用说明如下&#xff1a; 1. 实时监测眼睛状态 通过摄像头捕获的实时视频流&#xff0c;检测人脸关键点并计算眼睛的 EAR&a…...

系列六、Java垃圾回收器主要有哪些?

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

【7】Spring Boot 3 集成组件:缓存组件 spring cache + spring data redis

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

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...