【问题标题】:What makes bare-metal tool chains special?是什么让裸机工具链与众不同?
【发布时间】:2015-02-14 10:10:48
【问题描述】:

当我想在没有底层操作系统的情况下编译二进制文件时,为什么需要裸机工具链?编译器有什么限制,除了缺少功能/特性,因为没有操作系统/标准库。任何 clang/gcc 都可以用作裸机编译器吗?我的目标是树莓派 2。

【问题讨论】:

    标签: gcc raspberry-pi clang bare-metal


    【解决方案1】:

    首先,您需要一个可以为目标处理器生成代码的编译器。使用 clang,通常需要提供适当的命令行参数来选择目标处理器、浮点支持(或缺乏)等。对于 gcc,您需要构建一个支持特定目标的版本。

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

    int main()
    {
    }
    

    你可以用你的交叉编译器编译它并为目标获取一个目标文件。现在的问题是如何在裸机环境中执行 main()。至少你需要一些代码,通常是汇编,在处理器复位时运行,设置堆栈指针,并调用 main()。在没有其他库支持的情况下,其他一切都取决于您。您必须编写代码来执行特定于您的硬件的 I/O 等操作。

    我正在开发一个以 Linux 为目标但也支持裸机开发的工具链。目前,该工具链针对 C/C++ 开发的 ARM、Mips、PowerPC 和 x86 目标。 Linux 目标得到全面支持,ARM 裸机目标支持也随之而来。在这种情况下,“裸机”的范围很广,从我上面描述的简单 main() 到支持许多 POSIX 函数,例如 pthread_create()、互斥体支持等。它也可以在 MMU 和非 MMU 环境中运行。您可能想查看http://ellcc.org 的代码,了解如何处理裸机。如果您想尝试一下,也可以下载适用于 Windows 和 Linux 的预构建二进制文件。

    【讨论】:

    【解决方案2】:

    用独立式替换裸机,没有裸机编译器之类的东西。

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

    另一方面,大多数人在开始裸机工作时不知道自己在做什么,而且人们总是会犯错误,然后编译器用于操作系统的部分内容会潜入您的裸机工作并搞砸事情向上。独立编译器无法做到这一点,因为它没有依赖的操作系统部分。因此,您不会在内核中出现奇怪的行为或崩溃,而是会遇到编译器错误。

    总体而言,为裸机工作构建一个独立(交叉)编译器有 3 件事可以说明:

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

    【讨论】:

    • 不,这与答案相矛盾。使用真正的独立编译器。
    • 最好给出gcc -nostdinc -nostdlib -ffreestanding失败的具体例子,以及如何构建你详细提到的编译器。相关:stackoverflow.com/questions/2681304/…
    • 假设你的 gcc 是用于带有硬浮点的 ARM,而你为没有 FPU 的 ARM 进行交叉编译,那么 libgcc.a 将包含一些使用硬浮点的代码,并且在你使用这些函数时会包含这些代码。您想要的是不使用 FPU 或软浮点的函数。
    • 当然,您必须瞄准正确的 ISA 版本。我想知道除此之外还有什么。
    猜你喜欢
    • 2011-09-09
    • 1970-01-01
    • 2014-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 2018-10-22
    • 1970-01-01
    相关资源
    最近更新 更多