在低 ram 嵌入式系统中使用 Busybox 有什么意义

What's the point of using Busybox in a low ram embedded system

我正在努力将 linux 引入具有 16 Mb SDRAM 和 64 Mb 闪存的定制 Cortex-M7 板。该平台没有 MMU、没有共享库、FLAT 可执行文件。

我在使用非常简单的 init.d shell 脚本启动 Busybox 系统时遇到问题。通过执行简单的 shell 命令,如“[”或 "printf",系统 运行 内存不足。事实证明,每次执行这些命令之一时,系统都需要加载完整的、唯一的 busybox 可执行文件(在我的系统上为 650 Kb)。

所以问题是:如果系统总是需要为busybox 中执行的每个命令在内存中加载一个巨大的可执行文件,那么这有多方便?我不明白在以极快的速度退出 ram 的同时节省几兆字节的廉价和充足的存储空间,但也许我忽略了一些东西。

我的平台是 Busybox 的用例吗?如果没有,有没有什么可以方便地在各自的可执行文件上构建 linux 系统实用程序?

提前致谢!

编辑:

Busybox,根据他们自己的说法,“在编写时考虑了大小优化和有限资源”,因此成为嵌入式系统中一种无可置疑的事实标准。但是他们的声明与上述 RAM(而非存储)受限系统的问题有何关系?我相信这值得澄清。

跟进,系统详情:

内核已经为 XIP 编译,从 64 Mb 外部闪存执行。整个 read/write ext3 根文件系统(包括 busybox 二进制文件)现在驻留在微型 SD 卡上。 Busybox 可执行文件使用 FLAT 格式 ("bFLT") 并启用加载到 RAM 位,每次运行并发命令时,该位似乎都会在不同的内存块上产生新的加载,直到它耗尽合适的块。将 busybox(整个 /bin、/sbin)放在 XIP 文件系统上的建议非常棒,它肯定会提高执行速度(当然,这个新文件系统需要驻留在 64 Mb 外部闪存上)。我从来没有尝试过 "bFLT" 在这样的文件系统上执行(也不知道它是否有效),但我会做我的 research/testing。

TL-DR; Linux 拥有庞大的基础架构和各种可用的 rootfs 或引导文件系统。选择是由于适应不同的系统限制和最终用户功能。 Busybox 是目标系统的不错选择,但如果系统工程师不花时间去理解它,任何软件都可能被误用。


Is my platform an use case for Busybox?

如果您花时间最小化内核大小和 busybox 本身,它就是。您不太可能需要当前 busybox.

中的所有功能

if not, is there anything to conveniently build linux system utilities each on their own executable?

请参阅下面的 klibc 信息。您还可以构建 dash with musl, with buildroot and busybox. Many filesystem builders support shared libraries or static binaries. However, there are many goals,例如文件系统构建器可能针对的包管理和实时更新。

更多详情

您可以在 busybox 之外配置功能。这个想法是需要所有配置的功能。因此,您需要将它们全部保存在内存中。对于 busybox,lsmkdirprintf 等都是相同的二进制文件。因此,如果您 运行 一个 shell 脚本,则一次代码加载就是所有代码加载。另一方面,您有许多单独的二进制文件,每个二进制文件都将占用额外的内存。您需要最小化 Linux 以获得更多 RAM,并且您可以从 busybox 中提取功能以使其更小。 Busybox 就像一个巨大的共享图书馆;或更准确地说 shared process。所有代码页都相同。

a custom Cortex-M7 board with 16 Mb of SDRAM and 64 Mb of Flash

...

one and only busybox executable (650 Kb on my system)

显然 650KB 远小于 16MB。您没有说其他 RAM 的用途。另一个好的替代方法是查看 klibc toolsuite。不清楚的是 FLASH 是否为 NAND/NOR 以及您是否启用了 XIP。通常,busybox 对于 XIP 闪存会更好,而 klibc 对于 SDRAM 会更好(并且更受限制),闪存中有一些文件系统。

参见:Busybox 常见问题解答中的 Memory used by relocatable code, PIC, and static linking。它被设计为 运行 来自只读存储器,这可能是一个很大的收获,具体取决于系统结构。它可能提供比 klibc 更丰富的功能集,因为该项目的目标只是启动一些其他挂载设备(硬盘驱动器、SSD 等)。

Klibc 没有 busybox 那样多的文档。它可以是共享库或静态链接。每个二进制文件将仅使用静态链接任务所需的 RAM,但这将占用更多闪存 space。带有 klibc 的二进制文件是,

 1. dash    2. chroot     3. dd      4.  dmesg  5.  mkdir  6.  mkfifo
 7. mknode  8. pivot_root 9. unmount 10. true   11. false  12. sleep
 13. ln    14. ls        15. mv      16. nuke   17. minips 18. cat
 19. uname 20. halt      21. kill    22. cpio   23. sync   24. readlink
 25. gzip  26. losetup

那就是 IT! 没有网络,没有媒体播放器等。您可以编写代码来使用 klibc,但它是一个非常受限的库,可能没有那些功能你需要。通常它会仅限于磁盘任务。例如,探测 USB 以供外部设备启动非常好。

Busybox 可以做的更多。大多数 klibc 静态二进制文件都在 100kB 以下;典型值为 10-30kB。 Dash 和 gzip 更大。但是,我认为您需要从内核中删除配置项,因为 650KB << 16MB,即使没有 XIP,busybox 也是这个系统的不错选择。

我还应该注意 Linux 对 MMU 系统的代码确实 'demand page loading'。即使您没有交换,代码也可以从 RAM 中踢出并在以后因页面错误重新加载。您的系统没有 MMU,因此在这种情况下 busybox 的性能不会那么好。使用 mmu 和 'demand page loading' 它会做得更好。

对于严格的约束,您始终可以完整地编写代码 library free binary。这避免了您可能不需要的 libgcc 启动和支持基础结构。通常,这仅适用于测试内核与 initrd 问题以及 script/binary 在许多不同的库环境中必须 运行。

另请参阅:

  • AXFS - xip 只读文件系统。
  • CrafFs - 另一个 xip 文件系统。
  • XIP kernel - 内核可能很大。如果可能,将其从 RAM 中取出。如果没有,请使用 EMBEDDED 选项进行配置。
  • nommu.org - 关于github
  • 的一些信息
  • elf2flt - Mike Frysingers 更新到 binutils 2.27-2.31.1
  • fdpic gcc - mickael-guene 2016 年的笔记。

XIP 只能与 ROM、NOR 闪存和可能的 SPI-NOR MTD 一起使用。

BusyBox 的要点是你只需要在内存中有一个(共享的)可执行文件。

您写道:

It turns out that everytime one of these commands are executed the system needs to load the FULL, one and only busybox executable (650 Kb on my system).

这不完全正确。对于第一个命令,可执行文件确实加载到内存中。但是,如果您是 运行 多个命令(即多个 BusyBox 实例),则可执行文件不会多次加载到内存中。很大一部分二进制文件(简单地说:所有只读数据,例如可执行代码和常量数据)将被重用。每个额外的进程只需要一些额外的内存来完成它自己的任务。

因此,如果 BusyBox 的单个实例消耗 640 kB 内存,则 10 个实例加起来可能只使用 1 MB 内存,而 10 个 200 kB 的唯一可执行文件将使用 2 MB。

我建议对您的系统进行一些实际测试并检查实际内存消耗。但请注意,pstop 等工具可能有点误导或难以理解。已经有很多关于它的文章,如果您想了解更多,一个好的起点是 here.