设为首页 加入收藏

TOP

掌握嵌入式Linux编程2工具链(二)
2023-07-23 13:24:55 】 浏览:115
Tags:Linux 编程
上是很诱人的。
这在一定程度上是可行的,但很可能主机发行版比目标版更经常地收到更新,或者为目标版编写代码的不同工程师对主机开发库的版本略有不同。随着时间的推移,开发系统和目标系统将出现分歧,你将违反工具链应该在项目的整个生命周期内保持不变的原则。如果你能确保主机和目标构建环境是同步的,你就能使这种方法发挥作用。然而,更好的方法是保持主机和目标的分离,而交叉工具链就是这样做的方法。

然而,有一个支持本地开发的反驳理由。交叉开发会造成交叉编译你的目标所需的所有库和工具的负担。我们将在后面的 "交叉编译的艺术 "一节中看到,交叉开发并不总是简单的,因为许多开源包并不是被设计成以这种方式构建的。集成构建工具,包括Buildroot和Yocto项目,通过封装规则来帮助你交叉编译一系列你在典型的嵌入式系统中需要的软件包,但是如果你想编译大量的额外软件包,那么最好是原生编译它们。例如,使用交叉编译器为Raspberry Pi或BeagleBone构建一个Debian发行版将是非常困难的。相反,它们是被本地编译的。

从头开始创建一个本地构建环境并不容易。首先,你仍然需要交叉编译器来在目标上创建本地构建环境,然后用它来构建软件包。然后,为了在合理的时间内进行本地构建,你将需要一个由配置良好的目标板组成的构建农场,或者你可以使用Quick EMUlator(QEMU)来模拟目标。

CPU架构

工具链必须根据目标CPU的能力来构建,这包括以下内容:

  • CPU架构: ARM、无互锁流水线阶段的微处理器(MIPS Microprocessor without Interlocked Pipelined Stages)、x86_64,等等。
  • Big-或little-endian操作: 有些CPU可以在两种模式下运行,但每种模式下的机器代码是不同的。
  • 浮点支持: 并非所有版本的嵌入式处理器都实现了硬件浮点单元,在这种情况下,工具链必须被配置为调用软件浮点库。
  • 应用二进制接口(Application Binary Interface): 用于在函数调用之间传递参数的调用惯例。

在许多体系结构中,ABI在整个处理器系列中是不变的。值得注意的例外是ARM。ARM 架构在 2000 年代末过渡到扩展应用二进制接口 (EABI),导致以Extended Application Binary Interface前的 ABI 被命名为旧应用二进制接口 (OABI Old Application Binary Interface )。虽然OABI现在已经过时了,但你会继续看到对EABI的引用。从那时起,根据浮点参数的传递方式,EABI已经一分为二。
最初的EABI使用通用(整数)寄存器,而较新的Extended Application Binary Interface Hard-Float(EABIHF)使用浮点寄存器。EABIHF的浮点运算速度明显更快,因为它不需要在整数和浮点寄存器之间进行复制,但它与没有浮点单元的CPU不兼容。因此,你必须在两个不兼容的ABI之间做出选择;你不能混合两者,因此你必须在这个阶段做出决定。
GNU在工具链中的每个工具的名称上使用了一个前缀,它标识了可以生成的各种组合。它由一个用破折号隔开的三或四个组件组成,如下面所述:

  • CPU: 这是CPU架构,如ARM、MIPS或x86_64。如果CPU有两种endian模式,可以通过添加el来区分小端模式或eb来区分大端模式。很好的例子是小字节的MIPS,mipsel,和大字节的ARM,armeb。
  • 供应商: 这标识了工具链的提供者。例子包括buildroot、poky,或者只是未知。有时它被完全忽略了。
  • 内核: 对于我们的目的,它总是linux。
  • 作业系统: 用户空间组件的名称,可能是gnu或musl。ABI也可以附加在这里,所以对于ARM工具链,你可以看到gnueabi、gnueabihf、musleabi或musleabihf。

你可以通过使用gcc的-dumpmachine选项找到构建工具链时使用的元组。例如,你可以在主机上看到以下内容:


$ gcc -dumpmachine

x86_64-linux-gnu

这个元组表示CPU为x86_64,内核为linux,用户空间为gnu。

重要提示:

当一个本地编译器安装在机器上时,通常会在工具链中创建没有前缀的工具链接,这样你就可以用gcc命令调用C编译器。
下面是一个使用交叉编译器的例子:


$ mipsel-unknown-linux-gnu-gcc -dumpmachine

mipsel-unknown-linux-gnu-表示小-endian MIPS的CPU,未知的供应商,linux的内核,和gnu的用户空间。

选择C库

Unix操作系统的编程接口是由C语言定义的,现在由POSIX标准定义。C库是该接口的实现;它是Linux程序进入内核的门户,如下图所示。即使你用其他语言编写程序,也许是Java或Python,各自的运行时支持库最终都要调用C库,如图所示:

每当C库需要内核的服务时,它将使用内核的系统调用接口在用户空间和内核空间之间转换。可以绕过C库,直接进行内核系统调用,但是这很麻烦,几乎没有必要。
有几个C库可以选择。主要的选择有以下几种:

那么,该选择哪一个呢?我的建议是,只有当你使用uClinux时才使用uClibc-ng。如果你的存储空间或内存非常有限,那么musl libc是一个不错的选择,否则就使用glibc:

你对C库的选择可能会限制你对工具链的选择,因为并不是所有预置的工具链都支持所有的C库。

寻找工具链

对于你的交叉开发工具链,你有三个选择:你可以找到符合你需求的现成的工具链;你可以使个由嵌入式构建工具生成的工具链,这在第6章,选择构建系统中有所涉及;或者你可以

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 2/9/9
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇MRS-MRS相同功能代码管理应用笔记 下一篇物联网操作系统Zephyr入门教程4调..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目