• 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)
    
    • 1
    • 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>;
        };
        ....
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 为兼容多个平台,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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 因此kernel感知的实际total size(128MB * 1024 - 768 = 130304K)与启动log匹配。

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

    • 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 分配代码
    //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
    • 根据代码可知预留内存占用如下:
    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_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
  • 相关阅读:
    远程桌面无法复制粘贴文件
    听大佬讲:学习 AXI从哪里开始?
    python中的字符串也是可迭代对象吗?
    泡泡玛特加速海外布局,泰国首店开业吸引超千名粉丝排队
    猿创征文|我的前端学习之旅【来自一名大四老学长的真情流露】
    Linux发展史&目录结构&Vim编辑器
    uniapp配置网络请求
    c++11~c++20 -09-类型别名和别名模板
    openh264 中背景检测功能源码分析
    01 # 手写 new 的原理
  • 原文地址:https://blog.csdn.net/qazw9600/article/details/134447988