Linux - 内存 - 预留内存占用分析

本文分析Linux启动时内存预留问题。公司SOC平台物理DRAM 128M,但启动log中total size不足且预留内存过多。通过分析,明确total size由来,统计memblock分配器初始化前后预留内存占用,最后发现统计的预留内存size与打印不一致是因打印时做了页对齐。

说明

  • 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
### 如何在RISC-V架构的Linux系统中预留内存 #### 使用内核命令行参数预留内存 对于希望保留特定区域不被操作系统使用的场景,在启动时可以通过传递给内核特殊指令来实现这一目标。通过指定`memmap`选项到内核命令行可以完成对物理RAM部分区间的保护,防止其被分配出去。 例如,为了排除一段从起始位置开始大小为16MB的内存区间供其他用途专用而不受干扰,可以在引导加载程序配置里加入如下所示设置: ```bash memmap=16M$0 ``` 上述做法告知内核有关于哪些范围内的帧不应该纳入管理范畴之内[^3]。 #### 修改内核源码以支持自定义预留机制 如果需求更为复杂,则可能涉及到调整或扩展内核本身的逻辑处理流程。这通常意味着要深入研究并修改与体系结构紧密关联的部分代码片段,比如针对RISC-V平台特有的文件如`arch/riscv/mm/init.c`等处着手实施必要的改动以便更好地满足应用层面提出的各种约束条件。 当面对需要长期维护定制化特性的项目时,这种方法虽然初期投入较大但是能够提供更加灵活可控的支持方式[^1]。 #### 利用设备树(Device Tree) 另外一种途径就是借助device tree blob(DTB),这是一种描述硬件布局的数据结构形式。对于某些嵌入式开发板而言,编辑对应的.dts文件同样能达到预期效果——即告诉内核存在不可触及的记忆体区块。具体操作上会涉及更改节点属性从而影响最终解析后的行为表现[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值