【问题标题】:Dynamic allocation in uClinuxuClinux中的动态分配
【发布时间】:2012-06-07 15:42:20
【问题描述】:

我是嵌入式开发的新手,我发现传统 Linux 和 uClinux 之间的最大区别是 uClinux 缺少 MMU。

来自this article

如果没有 VM,每个进程都必须位于内存中可以运行的位置。在最简单的情况下,这个内存区域必须是连续的。一般来说,它不能扩展,因为它上面和下面可能还有其他进程。这意味着 uClinux 中的进程无法像传统 Linux 进程那样在运行时增加其可用内存的大小。

对我来说,这听起来像是所有数据都必须驻留在堆栈上,而且堆分配是不可能的,这意味着 malloc() 和/或“new”是不可能的......这准确吗?也许有一些技术/库允许管理“静态堆”(即可以请求“动态”分配的基于堆栈的区域)?

还是我想多了?还是过度简化?

【问题讨论】:

  • 在启动程序之前仍然可以选择设置适当的大小。即使在虚拟内存系统中,大小也仅限于最大地址空间,例如 32 位系统上的 2 或 4GB。这里的限制(物理内存)只是由所有程序共享。
  • @BoPersson - 什么“合适的大小”?
  • 在加载其他程序之前,您必须保留程序所需的空间。不同之处在于它们都共享相同的地址空间,因此它们的总大小将相加。使用虚拟内存,地址空间独立于其他程序。这里不是。

标签: c++ c virtual-memory uclinux mmu


【解决方案1】:

在普通 Linux 下,程序员不需要处理物理资源。内核负责这一点,用户空间进程只能看到自己的地址空间。随着堆栈的增长,或者 malloc 类型的请求的产生,内核会将空闲内存映射到进程的虚拟地址空间。

在uClinux中,程序员必须更关心物理内存。 MMU 和 VM 不可用,所有地址空间都与内核共享。加载用户空间程序时,会为进程分配用于文本、堆栈和变量的物理内存页。进程的程序计数器、堆栈指针和数据/bss 表指针设置为物理内存地址。堆分配(通过 malloc 类型调用)来自同一个池。

您不必摆脱程序中的堆分配。您将需要关注一些新问题。由于堆栈不能通过虚拟内存增长,因此您必须在链接期间正确调整其大小以防止堆栈溢出。内存碎片成为一个问题,因为没有 MMU 来整合较小的空闲页面。错误指针变得更加危险,因为它们现在可能导致对物理内存中任何位置的意外写入。

【讨论】:

  • 一些 SOC 有一个 MPU(内存保护单元)而不是 MMU。因此,MPU 可以防止程序在内核的内存空间中写入内容。
【解决方案2】:

我使用 uCLinux 已经有一段时间了(在它被集成到主树之前),但我认为 malloc 仍然可以作为 c 库的一部分使用。由于堆不是孤立的,因此在内存中执行非常糟糕的事情 (tm) 的可能性要高得多,但这是可能的。

【讨论】:

    【解决方案3】:

    是的,你可以在 uclinux 上的用户空间应用程序中使用 malloc,但是你必须增加用户空间应用程序的堆栈大小(在运行程序之前导致堆栈大小是静态的),这样当 malloc 运行时它会得到它需要的空间。 例如arm-cortex上的uclinux arm 工具链提供命令来查找和更改用户应用程序二进制文件使用的堆栈大小,然后您可以将其传输到嵌入式系统并运行 ----- > arm-uclinuxeabi-flthdr

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-05
      • 2019-06-25
      • 2020-03-12
      相关资源
      最近更新 更多