0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

i.MX6ULL开发板源码自制交叉编译器

武汉万象奥科 2021-12-29 19:05 次阅读

前言

文章基于HD-IMX6ULL-MB 系列开发板测试验证,该开发板由武汉芯路遥科技有限公司与武汉万象奥科电子有限公司合作推出。此开发板基于 NXP iMX6ULL 系列 Cortex-A7 高性能处理器设计,适用于快速开发一系列具有创新性的产品如人机界面工业 4.0 扫描仪、车载终端以及便携式医疗设备。

poYBAGHJb9-AGJjfAAFp4I2KTKg619.jpg


自己制作交叉编译器


早期(2009年以前)我们在做嵌入式系统开发时,第一件事就是自己制作交叉编译器。当时做交叉编译器 需要自己下载gcc、glibc、binutils等相关工具的源码,然后一个一个源码编译安装。制作交叉编译器的 过程中最痛苦的莫过于各个软件之间的版本依赖关系,如gcc 4.6.2 依赖 glibc 2.13,如果你选定 gcc 4.7 则可能编译制作失败,然后再尝试一个新的版本重新编译,直至找到一个合适的版本为止。


后来为了方便交叉编译器的制作,有很多组织或个人开始编写这些制作交叉编译器的脚本或框架,并测 试解决这些软件版本之间的依赖关系。当时最知名的莫过于基于 glibc crosstool 和 基于 uclibc

buildroot 了。在开始讲解如何制作交叉编译器之前,我们首先来了解一下 C运行库


1.嵌入式C运行库


1.1glibc库

glibc是gnu发布的libc库,也即c运行库。glibc是linux 系统中最底层的api(应用程序开发接口),几乎其它任何的运行库都会倚赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了 许多其它一些必要功能服务的实现,主要的如下:

string,字符串处理

signal,信号处理

dlfcn,管理共享库的动态加载

direct,文件目录操作

elf,共享库的动态加载器,也即interpreter

iconv,不同字符集的编码转换

inet,socket接口的实现

intl,国际化,也即gettext的实现

io

linuxthreads

locale,本地化

login,虚拟终端设备的管理,及系统的安全访问

malloc,动态内存的分配与管理

nis

stdlib,其它基本功能


gcc 是编译器,基本上 Linux 下所有的程序(包括内核)都是 gcc 编译的,libc 当然也是。gcc 和 libc 是互相依赖的两个软件,它们合作的方式类似 Linux 系统的 "自举"。先在一个可以运行的带有老 libc 和

gcc 的系统上,用老 gcc 编译出一个新版本的 gcc + 老 libc,再用这个新 gcc 编译出一个新 gcc + 新

libc,再用这套新的组合编译整个新系统。


1.2 uClibc库

PC上常用的标准库glibc是一个非常宠大而完整的库,但早期对于嵌入式系统来说,由于Flash和RAM的 存储空间有线,其体积显得过于大了一些。uClibc的出现就是为了解决这个问题,uClibc尽可能的兼容

Glibc,大多数应用程序可以在很小或完全不修改的情况下就可能使用uClibc替代glibc。通过uClibc来代 替Glibc,可以在不改变应用程序功能的前提下,大大减少发布文件的大小,无论应用程序以静态链接来 编译,还是以动态链接形式编译。


uClibc比一般用于Linux发行版的C库GNU C Library (glibc)要小得多,glibc目标是要支持最大范围的硬件和内核平台的所有C标准,而uClibc专注于嵌入式Linux.很多功能可以根据空间需求进行取舍。现在uClibc更多运行于标准的以及无MMU的Linux系统上,支持i386,x86 64,ARM (big/little endian), AVR32,Blackfin,h8300,m68k,MIPS (big/little endian), PowerPC,SuperH (big/little endian),

SPARC,和v850等处理器


由于当前嵌入式系统硬件性能的提升,用于存储程序的Flash空间和用于运行程序的RAM空间都有了大幅 提升,为了保证程序更大的兼容性,uClibc也逐步退出了历史的舞台了。



uClibc早期官网: uClibc最新官网:

https://www.uclibc.org/ h ttps://uclibc-ng.org/



1.3 eglibc库


EGLIBC(Embedded GLIBC,缩写为EGLIBC)是glibc的原创作组织FSF所新推出的glibc的一种变体, 目的在于将glibc用于嵌入式系统。它是GNU C 库(glibc)的一个分支,也采用GNU宽通用公共许可证

(LGPL)发布。它希望能应用于嵌入式系统,但它的源代码与可执行文件仍然保持与glibc一致。它的作 者宣称它不是glibc的一个分支,而是用来容纳glibc核心开发者拒绝采纳的patch。


2009年5月6日,因为与glibc核心开发者之间对程序发展方向的争议,Debian开发者宣布将要采用EGLIBC来取代glibc。Ubuntu自9.10后也采用了EGLIBC,Ark Linux也使用它。2014年初,官网上宣布,eglibc已经停止开发,因为现在的目标是在glibc上直接解决问题(goals are now being addressed directly in GLIBC),Debian开发者也恢复到使用glibc了。


1.4 newlib库


在做一些单片机的裸机程序开发时,有时候最想要的是实现一个printf打印函数,以便及时输出各种信 息。除去底层的设备驱动不说,printf本身的实现就有够麻烦,如果平时有保存相关的代码还好,不然就 很浪费时间。除此之外,还有一些诸如strlen、strcpy之类的函数,我们不愿意自己写,既麻烦而且效率 不高,如果能借助已有的代码或库就好了。


Newlib 就满足了这点需求,它是一个面向嵌入式系统的C运行库。最初是由Cygnus Solutions收集组装的一个源代码集合,取名为newlib,现在由Red Hat维护。对于与GNU兼容的嵌入式C运行库,Newlib 并不是唯一的选择,但是从成熟度来讲,newlib是最优秀的。newlib具有独特的体系结构,具有可移植 性强,具有可重入特性、功能完备等特点,使得它能够非常好地满足深度嵌入式系统的要求。


Newlib 库是一个开源的c函数库,包括libc和libm两部分。它支持ANSI C库标准,针对不同处理器架构进行优化,轻量级,适用于嵌入式系统。其特点如下:

支持printf和优化的字符串操作

支持malloc和free等内存操作

支持函数可重入功能(不过这种支持对内存有压力,总之是感觉弊大于利)

支持libm数学库(不过一般嵌入式用不到浮点数,而且用模拟的开销略大)

newlib的函数是分文件实现的,如果用不到,绝不加入链接,一般不会造成目标文件猛增的情况。

newlib C库一般在制作单片机裸机开发的交叉编译器时,使用得比较多。



2 Crosstool-ng制作交叉编译器


Crosstool早期是个很不错的交叉编译器制作工具,但是后来完善得不够好,于是有人弄出了个更好的

—— crosstool-ng(crosstool Next Generation)。其特点如下:

支持menuconfig(类似于Linux内核配置) 支持众多的架构

可选多种不同的C库等模块提供示例配置

支持多种主机编译环境:各种Linux发行版,Cygwin等。


接下来,我们学习了解一下如何使用 crosstool-ng 来制作一个ARM交叉编译器。


2.1 Crosstool-NG 编译与安装


首先我们到 Crosstool-NG 的官方站点(https://crosstool-ng.github.io/)下载其软件源码压缩包,并解压缩源码。


pYYBAGHJb-CAY87nAACVjyWb6kY38.jpeg


接下来进入到源码路径下,开始Linux系统下源码安装的三部曲: ./configuremakemake install

。 这里在configure 时通过 --prefix 选项指定将编译生成的文件安装到当前路径下即可。在进行

./configure 时可能会提示 help2man、 libtool 找不到,这可能是系统没有安装或者安装的版本过低导致的,直接使用 sudo apt install 命令安装相关系统命令即可。


pYYBAGHJb9-AKAtZAAE9SAMHxTA64.jpeg


上面命令成功编译安装之后,可执行程序将会放到 install 文件夹下,接下来我们可以测试 ct-ng 命令是否能够成功执行。接下来我们将会使用该程序来制作交叉编译器。


poYBAGHJb9-ADMJYAACYV30bvr024.jpeg


2.2 交叉编译器配置


在Crosstool-NG的安装路径下,有很多参考的交叉编译器示例配置,我们没有必要所有的选项都自己从

0开始配置,可以在某个示例配置的基础上来修改。


pYYBAGHJb-CAG8TMAADPdzPD1g002.jpeg


因为i.MX6ULL是ARM CortexA7核的处理器,但在上面的示例配置中并没有该架构的相关配置,这样我们在 A8的基础上来进行修改,这两种架构大致都差不多。我们将ARM CortexA8的示例配置拷贝一份并命名为 .config, 接下来的 ct-ng menuconfig 将会默认读取该配置文件。


poYBAGHJb-CARu20AAAvAcLcFAw25.jpeg


接下来使用 export 命令导出 ct-ng 命令所在的路径,如果是使用 SecureCRT 远程登录到Linux服务器上操作的话,还需要 export TERM=vt100 命令配置TERM环境变量,否则接下来的配置可能不能输入。接下来再执行 ct-ng menuconfig 对交叉编译器制作进行配置。


poYBAGHJb-CAQ3N_AABHzdysINI63.jpeg


下面是Crosstool-NG的配置界面,我们接下来需要在这里进行修改。在配置的过程中,上、下方向键 用来选择相应选项,TAB用来选择底下的 或 :在 Paths and misc options 选项中,我们主要要修改如下几个选项,修改指定下载的软件包存放路径${PWD}/tarballs 和 交叉编译器的安装路径 /opt/xtools/cortexA7:在 Target options 选项中,我们主要修改 “ Floating point” 选项,因为 iMX6ULL处理器带有 FPU,这里为了保持兼容性,选择 softfp (FPU)。在 Toolchain options 选项中,如果想拷贝该交叉编译器给别的机器使用,则可以选中"Build Static Toolchain",另外修改 "Tuple's vendor string" 选项中指定交叉编译器名称。在 Operating System 选项中,因为我们移植的Linux内核目标版本为 5.10.x, 所以这里内核的版本选择要跟开发板上移植的版本保持一致,否则今后编译Linux内核时可能会出现兼容性问题。在这里, crosstool-NG的默认内核版本较低,这里需要修改配置为我们想要的版本。下面的这些选项配置,依赖Paths and misc options 菜单中的 [*] Try features marked as EXPERIMENTAL选项。"Source of linux" 选择 (Custom location)"Custom source location" 里设置 Linux路径为 (${PWD}/tarballs/linux-5.10.tar.xz) ,接下来我们将会手动下载相应的Linux内核源码压缩包到这里;"Version of linux" 里选择 (newer than anything below) ;在 C-library 选项中,C library 选择 (glibc) ,其他使用默认剩余的其它选项,我们就不作任何修改采用默认配置。关于 C compiler 编译器里的相关选项,大家也可以了解一下。配置完成后回到主菜单,使用 Tab键 切换到 < Exit > ,然后选择保存退出即可。交叉编译器配置完成之后,接下来我们就准备开始交叉编译器的编译过程。2.3 交叉编译器编译在前面的配置中,我们计划将交叉编译器安装到系统的 /opt/xtools 路径下,这里我们首先需要使用root 权限创建这个文件夹,并给所有其他用户 写 权限。CrossTool-NG在编译过程中,会下载制作交叉编译器所需要的软件源码包,但有些软件包的下载地址可 能已经失效,这时我们可以自己找到相关软件的相应版本软件包,然后手动下载到指定的压缩包存放路 径下,如前面配置中指定的 ${PWD}/tarballs 。下面是一些已知的失效文件,我们提前手动下载好,其它所需要的软件包将会在开始编译后自动下载。接下来我们就开始交叉编译的编译制作过程,这个过程的时间依赖PC的性能。我的Linux服务器处理器 是Intel(R) Xeon(R) CPU E31235 @ 3.20GHz,4核8线程,所以我这里使用 ct-ng build.8 命令用8个进程同时编译。交叉编译器编译完成之后,我们可以使用下面命令查看制作好的交叉编译器相关版本信息:2.4 交叉编译器测试接下来我们使用制作好的交叉编译器,交叉编译之前写好的 hello.c 测试程序,并放到 ARM 开发板上运行测试。需要注意的是因为新制作的交叉编译器跟开发板上运行的C运行库版本不一致,这里必须加上 -static 进行静态链接,这样编译生成的程序才能在开发板上运行。ARM 开发板上下载运行测试:版权声明本文档所有内容文字资料由凌云实验室郭工编著,主要用于凌云嵌入式Linux教学内部使用,版权归属 作者个人所有。任何媒体、网站、或个人未经本人协议授权不得转载、链接、转帖或以其他方式复制发布/发表。已经授权的媒体、网站,在下载使用时必须注明来源,违者本人将依法追究责任。Copyright (C)2021 凌云物网智科实验室·郭工Author: GuoWenxue guowenxue@gmail.com

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux系统
    +关注

    关注

    4

    文章

    567

    浏览量

    26903
  • 嵌入式开发
    +关注

    关注

    18

    文章

    975

    浏览量

    46952
  • 开发板
    +关注

    关注

    25

    文章

    4418

    浏览量

    93920
收藏 人收藏

    评论

    相关推荐

    QT开发学习笔记1(安装交叉编译器

    QT安装交叉编译器
    的头像 发表于 02-18 10:02 342次阅读
    QT<b class='flag-5'>开发</b>学习笔记1(安装<b class='flag-5'>交叉</b><b class='flag-5'>编译器</b>)

    【米尔-TIAM62开发板-接替335x-试用评测】OPENCV和NCNN交叉编译

    目录 1. 前言 2. OPENCV交叉编译 3. NCNN交叉编译 4. OPENCV和NCNN移植 1. 前言 介绍了OpenCV和NCNN库的
    发表于 12-16 23:16

    i.MX6ULL——ElfBoard ELF1板卡 初次编译uboot的方法

    在下面章节有讲解,本章节主要演示编译流程,ELF1开发板的配置文件为imx6ull_elf1_defconfig。 三、 编译 如果曾经编译
    发表于 11-16 09:34

    基于i.MX6ULL的掉电检测设计与软件测试

    基于i.MX6ULL的掉电检测设计与软件测试基于i.MX6ULL平台设计实现掉电检测功能,首先选择一路IO,利用IO电平变化触发中断,在编写驱动时捕获该路GPIO的中断,然后在中断响应函数中发
    的头像 发表于 11-09 10:40 465次阅读
    基于<b class='flag-5'>i.MX6ULL</b>的掉电检测设计与软件测试

    i.MX6ULL——ElfBoard ELF1板卡 网络更新镜像

    ; setenv serverip 192.168.2.101//设置服务IP(虚拟机的IP) => saveenv//保存 4.ELF 1开发板与虚拟机进行网络测试: =>
    发表于 11-03 09:49

    让NPU跑起来迅为RK3588开发板设置交叉编译器

    让NPU跑起来迅为RK3588开发板设置交叉编译器编译器下载地址是网盘资料“iTOP-3588 开发板\\\\02_【iTOP-RK3588
    发表于 09-14 09:42

    飞凌OKMX6ULL开发板开箱试用体验

    OKMX6ULL-C开发板采用核心板+底板结构,基于NXP公司的i.MX6ULL低功耗处理器设计,运行主频800MHz,ARM Cortex-A7架构。独特的电源管理架构相比ARM9系列核心板功耗
    的头像 发表于 08-15 10:33 481次阅读
    飞凌OKMX6<b class='flag-5'>ULL</b><b class='flag-5'>开发板</b>开箱试用体验

    已知的HAB漏洞是否会影响i.MX6ULL版本1.1?

    我有一个 NXP iMX6ULL rev 1.1,发现i.MX6ULL 的 HAB 机制中存在两个已知漏洞。但是,我所指的文档并未指定芯片版本。因此,我不确定这些漏洞是否会影响我的设备。你能帮我澄清一下吗?
    发表于 06-02 09:07

    线程边界路由i.mx6ull otbr-agent处于非活动状态是什么原因造成的?怎么解决?

    我关注 https://github.com/nxp-imx/meta-matter “如何在目标上设置 OpenThread 边界路由”以在 i.mx6ull(定制,非 EVK)上运行线程边界
    发表于 05-31 06:37

    米尔瑞萨RZ/G2L开发板 安装交叉编译器

    米尔瑞萨RZ/G2L开发板安装交叉编译器
    的头像 发表于 05-26 22:05 1702次阅读
    米尔瑞萨RZ/G2L<b class='flag-5'>开发板</b> 安装<b class='flag-5'>交叉</b><b class='flag-5'>编译器</b>

    如何在i.MX6ULL上为PF1510配置i2c?

    我们计划将 PF1510 与 i.MX6ULL 处理一起使用。我看到这个设备树示例: https://github.com/Freescale/linux-fslc/blob
    发表于 05-17 14:02

    如何使用Linux版本在i.mx6ull上启用USB网络共享?

    我从 lf-5.10-y 分支为 i.mx6ull evk 构建了 Linux。我将我的 android 手机连接到 usb otg 端口并在我的手机上启用网络共享。但是我没有看到 USB0 接口
    发表于 05-09 08:06

    I.MX6ULL的SPI延迟问题如何解决?

    我们使用 NXP 的 I.MX6ULL 处理和 TCAN4550 进行 CANFD 通信。我们在传输 CAN 数据时面临 SPI 延迟问题。CAN 数据传输/接收是根据 SPI 中断发生的。我们
    发表于 05-05 10:29

    i.MX6ULL u-boot中一些U盘访问失败怎么解决?

    :49:03 +0000) CPU:i.MX6ULL rev1.1 792 MHz(以 396 MHz 运行) CPU:工业温度等级(-40C 至 105C)在 50C 复位原因:POR 型号:i.MX6
    发表于 05-05 09:00