是什么让裸机工具链与众不同?

What makes bare-metal tool chains special?

当我想编译没有底层 OS 的二进制文件时,为什么需要裸机工具链?编译器有什么限制,除了缺少 functions/features 因为没有 OS/stdlibrary。任何 clang/gcc 都可以用作裸机编译器吗?我的目标是树莓派 2.

首先,您需要一个能够为目标处理器生成代码的编译器。使用 clang,通常需要向 select 目标处理器提供正确的命令行参数、浮点支持(或不支持)等。对于 gcc,您需要构建一个支持特定目标的版本。

其次,想一个像这样的简单程序:

int main()
{
}

您可以使用交叉编译器对其进行编译并获得目标文件。现在的问题是如何在您的裸机环境中执行 main() 。至少您需要一些代码,通常是汇编代码,当处理器重置时 运行s,设置堆栈指针,并调用 main()。没有其他图书馆的支持,其他一切都取决于你。您必须编写代码来执行特定于您的硬件的 I/O 等。

我正在开发一个针对 Linux 的工具链,但它也支持裸机开发。目前,该工具链针对 C/C++ 开发的 ARM、Mips、PowerPC 和 x86 目标。 Linux 目标得到完全支持,ARM 裸机目标支持即将到来。 "bare-metal" 在此上下文中的范围无处不在,从我上面描述的简单 main() 到支持许多 POSIX 函数,例如 pthread_create()、互斥支持等。它可以 运行 在 MMU 和非 MMU 环境中也是如此。您可能想查看 http://ellcc.org 处的代码,了解如何处理裸机。如果您想尝试一下,您还可以下载 Windows 和 Linux 的预构建二进制文件。

将 bare-metal 替换为独立的,没有 bare-metal 编译器之类的东西。

bare-metal 工作不需要独立的编译器。但是随后您需要使用正确的选项组合来使普通(交叉)编译器作为独立编译器工作。使用 gcc/clang 这当然是可能的。如果你知道自己在做什么,甚至都不难。

另一方面,大多数人在开始 bare-metal 工作时并不知道自己在做什么,而且人们总是会犯错误,然后部分 OS 编译器会潜入你的 bare-metal 工作把事情搞砸了。独立编译器不能这样做,因为它没有 OS 它依赖的部分。因此,您不会在内核中出现奇怪的行为或崩溃,而是会遇到编译器错误。

为 bare-metal 工作构建一个独立(交叉)编译器的总体过程有 3 个方面:

  1. 防止您犯错误,这些错误会让您彻夜难眠,试图了解问题所在。
  2. 如果您正在为不同的架构构建然后在其上进行开发,则可以为您提供具有最低要求的 cross-compiler(例如不需要目标 libc)。
  3. 为每个人提供一个通用的设置,相同的标准化headers,...所以同样的问题对每个人都有相同的解决方案。