0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux如何防止内存冲突?

jf_44130326 来源:Linux1024 2026-01-30 16:51 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

在聊这个话题之前,我们先回忆一下单片机系统中是如何分配内存的?如果没有bootloader,那硬件环境起来之后就直接进入主程序运行,如果有引导程序bootloader,那就需要设置好跳转地址,否则设置不对,系统就无法启动了。

文章bootloader介绍

那么对于linux系统来说,何尝不是这样呢?因为linux系统包含的文件比较多,启动也分几个阶段,每个阶段也都是通过跳转执行的。如何管理好内存是系统稳定运行的前提。

原生的uboot只能管理自己所在的内存块,无法管理整块空间。于是rk引入了bidram和sysmem,用于管理uboot之外的地址空间,RK平台就把系统所有内存通过sysmem + bidram + malloc管理起来了,防止出现内存冲突等问题。

bidram:管理u-boot、kernel阶段不可用、需要剔除的内存块,例如:ATF、OP-TEE 占用的空间;sysmem:管理kernel 可见、可用的内存块。例如:fdt、ramdisk、kernel、fastboot 占用的空间。

相关代码:

./lib/sysmem.c./lib/bidram.c./include/memblk.h./arch/arm/mach-rockchip/memblk.c

先来大概预览一下源文件吧:

intsysmem_init(void){  struct sysmem *sysmem = &plat_sysmem;  phys_addr_t mem_start;  phys_size_t mem_size;  int ret;
  lmb_init(&sysmem->lmb);  INIT_LIST_HEAD(&sysmem->allocated_head);  INIT_LIST_HEAD(&sysmem->kmem_resv_head);  sysmem->allocated_cnt = 0;  sysmem->kmem_resv_cnt = 0;
  if (gd->flags & GD_FLG_RELOC) {    sysmem->has_initr = true;  } else {    SYSMEM_I("initn");    sysmem->has_initf = true;  }
  /* Add all available system memory */#ifdef CONFIG_NR_DRAM_BANKS  int i;
  for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {    if (!gd->bd->bi_dram[i].size)      continue;          ret = sysmem_add(gd->bd->bi_dram[i].start,         gd->bd->bi_dram[i].size);    if (ret) {      SYSMEM_E("Failed to add sysmem from bi_dram[%d]n", i);      goto fail;    }  }#else  mem_start = env_get_bootm_low();  mem_size = env_get_bootm_size();  ret = sysmem_add(mem_start, mem_size);  if (ret) {    SYSMEM_E("Failed to add sysmem from bootm_low/sizen");    goto fail;  }#endif  /* Reserved for board */  ret = board_sysmem_reserve(sysmem);  if (ret) {    SYSMEM_E("Failed to reserve sysmem for boardn");    goto fail;  }
  /* Reserved for U-boot framework: 'reserve_xxx()' */  mem_start = gd->start_addr_sp;  mem_size = gd->ram_top - mem_start;  if (!sysmem_alloc_base(MEM_UBOOT, mem_start, mem_size)) {    SYSMEM_E("Failed to reserve sysmem for U-Boot frameworkn");    ret = -ENOMEM;    goto fail;  }    /* Reserved for U-Boot stack */  mem_start = gd->start_addr_sp - CONFIG_SYS_STACK_SIZE;  mem_size = CONFIG_SYS_STACK_SIZE;  if (!sysmem_alloc_base(MEM_STACK, mem_start, mem_size)) {    SYSMEM_E("Failed to reserve sysmem for stackn");    ret = -ENOMEM;    goto fail;}return0;fail:  if (ret && !(gd->flags & GD_FLG_RELOC)) {    sysmem_dump();    SYSMEM_W("Maybe malloc size %d MiB is too large?nn",       SIZE_MB(CONFIG_SYS_MALLOC_LEN));}  return ret;}

wKgZO2kaoBuAZ_V-AAI2mYVdcis437.png

sysmem 内存信息表:

sysmem_dump_all:--------------------------------------------------------------------// <1> 这里是sysmem可管理的总内存容量,即bidram<3>之外的可用ddr容量,对kernel可见。memory.rgn[0].addr = 0x00200000 - 0x08400000 (size: 0x08200000)memory.rgn[1].addr = 0x0a200000 - 0x80000000 (size: 0x75e00000)memory.total = 0x7e000000 (2016 MiB. 0 KiB)--------------------------------------------------------------------// <2> 这里显示了各个固件alloc走的内存块信息allocated.rgn[0].name = "U-Boot".addr = 0x71dd6140 - 0x80000000 (size: 0x0e229ec0)allocated.rgn[1].name = "STACK"  // 表明栈溢出.addr = 0x71bd6140 - 0x71dd6140 (size: 0x00200000)allocated.rgn[2].name = "FDT".addr = 0x08300000 - 0x08316204 (size: 0x00016204)allocated.rgn[3].name = "KERNEL"  // 表明内存块溢出.addr = 0x00280000 - 0x014ce204 (size: 0x0124e204)allocated.rgn[4].name = "RAMDISK".addr = 0x0a200000 - 0x0a3e6804 (size: 0x001e6804)// <3> malloc_r/f的大小malloc_r: 192 MiB, malloc_f: 16 KiBallocated.total = 0x0f874acc (248 MiB. 466 KiB)--------------------------------------------------------------------// <4> 这里是核心算法对上述<2>进行的信息整理,显示被占用走的内存块信息LMB.reserved[0].addr = 0x00280000 - 0x014ce204 (size: 0x0124e204)LMB.reserved[1].addr = 0x08300000 - 0x08316204 (size: 0x00016204)LMB.reserved[2].addr = 0x0a200000 - 0x0a3e6804 (size: 0x001e6804)LMB.reserved[3].addr = 0x71bd6140 - 0x80000000 (size: 0x0e429ec0)reserved.core.total = 0x0f874acc (248 MiB. 466 KiB)--------------------------------------------------------------------

wKgZO2kaoByAKD5mAAJLI4NkLSo384.png

bidram 内存信息表:

bidram_dump_all:--------------------------------------------------------------------// <1> 这里显示了U-Boot从前级loader获取的ddr的总容量信息,一共有2GBmemory.rgn[0].addr = 0x00000000 - 0x80000000 (size: 0x80000000)memory.total = 0x80000000 (2048 MiB. 0 KiB)--------------------------------------------------------------------// <2> 这里显示了被预留起来的各固件内存信息,这些空间对kernel不可见reserved.rgn[0].name = "ATF".addr = 0x00000000 - 0x00100000 (size: 0x00100000)reserved.rgn[1].name = "SHM".addr = 0x00100000 - 0x00200000 (size: 0x00100000)reserved.rgn[2].name = "OP-TEE".addr = 0x08400000 - 0x0a200000 (size: 0x01e00000)reserved.total = 0x02000000 (32 MiB. 0 KiB)--------------------------------------------------------------------// <3> 这里是核心算法对上述<2>进行的预留信息整理,例如:会对相邻块进行合并LMB.reserved[0].addr = 0x00000000 - 0x00200000 (size: 0x00200000)LMB.reserved[1].addr = 0x08400000 - 0x0a200000 (size: 0x01e00000)reserved.core.total = 0x02000000 (32 MiB. 0 KiB)--------------------------------------------------------------------
通过上述内存管理,调试中在出现问题时,可以结合分析表去分析问题,如:

wKgZO2kaoByAXx1tAADnSWIwWq8282.png


原文标题:Linux如何防止内存冲突?

文章出处:【微信公众号:Linux1024】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    88

    文章

    11817

    浏览量

    219558
  • 内存
    +关注

    关注

    9

    文章

    3234

    浏览量

    76518
  • bootloader
    +关注

    关注

    2

    文章

    245

    浏览量

    48293
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux内存管理是什么,Linux内存管理详解

    Linux内存管理 Linux内存管理是一个非常复杂的过程,主要分成两个大的部分:内核的内存管理和进程虚拟
    的头像 发表于 05-11 17:54 7461次阅读
    <b class='flag-5'>Linux</b>的<b class='flag-5'>内存</b>管理是什么,<b class='flag-5'>Linux</b>的<b class='flag-5'>内存</b>管理详解

    linux内存相关知识科普

    linux 内存组织结构和页面布局,内存碎片产生原因和优化算法。
    发表于 08-08 10:57 718次阅读

    走进Linux内存系统探寻内存管理的机制和奥秘

    Linux 内存是后台开发人员,需要深入了解的计算机资源。合理的使用内存,有助于提升机器的性能和稳定性。本文主要介绍Linux 内存组织结构
    的头像 发表于 01-05 09:47 2528次阅读

    关于Linux内存管理的详细介绍

    Linux内存管理是指对系统内存的分配、释放、映射、管理、交换、压缩等一系列操作的管理。在Linux中,内存被划分为多个区域,每个区域有不同
    发表于 03-06 09:28 1493次阅读

    Linux内存相关知识科普

    Linux 内存是后台开发人员,需要深入了解的计算机资源。合理的使用内存,有助于提升机器的性能和稳定性。本文主要介绍**Linu****x 内存组织结构和页面布局,
    发表于 07-25 14:43 1222次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内存</b>相关知识科普

    Linux内核的内存管理详解

    内存管理的主要工作就是对物理内存进行组织,然后对物理内存的分配和回收。但是Linux引入了虚拟地址的概念。
    发表于 08-31 14:46 1452次阅读
    <b class='flag-5'>Linux</b>内核的<b class='flag-5'>内存</b>管理详解

    请问如何对多中断使用防止冲突

    在STM32中,如何对多中断使用,防止冲突
    发表于 04-10 01:22

    Linux中的冲突问题及其应对策略

    Linux服务器系统是不存在冲突的,然而些许时候该系统的冲突、停滞问题的确存在。对于应用软件层面的冲突或者停滞问题,与内核层面有何不同呢?
    发表于 05-16 11:41 1066次阅读

    linux内存管理机制浅析

    本内容介绍了arm linux内存管理机制,详细说明了linux内核内存管理,linux虚拟内存
    发表于 12-19 14:09 73次下载
    <b class='flag-5'>linux</b><b class='flag-5'>内存</b>管理机制浅析

    linux内存管理

    linux内存管理
    发表于 10-24 11:12 3次下载
    <b class='flag-5'>linux</b><b class='flag-5'>内存</b>管理

    你知道linux内存管理基础及方法?

    linux内存管理采取的分页存取机制,会将内存中不经常使用的数据块交换到虚拟内存中。linux会不时地进行页面交换操作,以保持尽可能多的空
    发表于 04-28 17:12 1651次阅读

    一文解析Linux内存系统

    Linux 内存是后台开发人员,需要深入了解的计算机资源。合理的使用内存,有助于提升机器的性能和稳定性。本文主要介绍Linux 内存组织结构
    的头像 发表于 09-01 10:46 3195次阅读
    一文解析<b class='flag-5'>Linux</b><b class='flag-5'>内存</b>系统

    深入剖析Linux共享内存原理

    Linux系统中,每个进程都有独立的虚拟内存空间,也就是说不同的进程访问同一段虚拟内存地址所得到的数据是不一样的,这是因为不同进程相同的虚拟内存地址会映射到不同的物理
    的头像 发表于 10-30 09:52 3017次阅读
    深入剖析<b class='flag-5'>Linux</b>共享<b class='flag-5'>内存</b>原理

    Linux系统的共享内存的使用

    但有时候为了让不同进程之间进行通信,需要让不同进程共享相同的物理内存Linux通过 共享内存 来实现这个功能。下面先来介绍一下Linux系统的共享
    的头像 发表于 11-14 11:55 2206次阅读

    Linux 内存管理总结

    一、Linux内存管理概述 Linux内存管理是指对系统内存的分配、释放、映射、管理、交换、压缩等一系列操作的管理。在
    的头像 发表于 11-10 14:58 1457次阅读
    <b class='flag-5'>Linux</b> <b class='flag-5'>内存</b>管理总结