交叉编译环境
yz0001 人气:0
# arm裸机,linux开发,编译器,编译环境答疑解惑
***前言:***
***最近一直在跟着正点原子的i.mx6ull视频学习,打算研究一下嵌入式linux的开发,主要是道听途说单片机开发未来薪资不高,想着反正单片机学的也就半吊子,何不趁此时各大厂商(某点,某火,某山)纷纷推出免费视频,开始进行价格战的时候,从中渔翁得利,白嫖一把,于是入手一块某点的i.mx6ull开发板,开始疯狂折腾,得益于之前学习视频教程的不断锤炼,现在对视频教程已经产生了独特的青睐,既然有,那就干起来吧,但是刚从stm32转到i.mx6ull开发的学习,还是有很多的不适应,尤其是之前stm32用的最多的只是f1系列,f4系列只用过一次,还是疯狂套例程的智能浇花系统,并且从未接触过单片机端的实时操作系统。感觉易上手确实比较打怵,好在刚开始某点教程还算可以,现在跟着学到了中断相关的东西,因为Ubuntu虚拟机的问题耽误了好几天,于是想出种种办法应对让人又爱又恨Ubuntu,在此记录一下踩过的坑,知道的经验,因为我学的时候没人告诉我,视频就摆在那里,具体能吸收多少真的靠自己。虽然跟着视频教程,跟着开发指南进行的有条不紊,偶尔会碰到许多相关的问题,但都是比较容易解决,正因为如此,太过简单的学习反而容易遗漏许多内容,并且好多相关的概念与只是都是知其然而不知其所以然,本着给自己答疑解惑的目的,再次记录下众多相关的概念,以及整体的系统框架。由于本人才学到裸机中断相关的内容,理解如有差池,敬请谅解。***
## 1.开发环境问题
### 首先要确定的一点是Linux环境下编程相比于Windows下编程有什么好处??
由于我也是一直怀有这个疑问,故此这次我边查找资料边写,看看大家都是怎么说的,具体资料链接我也放在下面(尊重版权),大家可以自己查看,我也会结合自己理解进行扩展
- 1.大部分人不经常在Linux编程,但会在Linux下完成编译,调试运行,可能是为了适配各种大厂要在Linux服务器下部署程序
- 2.因为你的程序要运行在Linux下,不想跨平台开发
- 3.目前大多数服务器都是Linux的,要想做开发,基本离不开Linux,此时适应一下Linux开发,理所当然,windows服务器贵的离谱
- 4.shell编程很方便,Linux稳定
- 5.可以了解更多的技术细节,就像编译的四个步骤,windows下没人会注意这些
- 6.使用集成IDE昂贵的费用,虽然好用,架不住贵
- 7.命令行操作确实简便快捷(结合自身体验回答一下,将近一个月的ARM学习过程:开始是windows下vscode编写程序,拖到Ubuntu虚拟机进行编译,编译完Ubuntu虚拟机进行烧写,这样如果改动一点程序,就要来回拖一遍,感觉非常不爽。于是转向Ubuntu虚拟机下的vscode编写程序,编译,烧写一步到位,但是电脑本身性能限制虚拟机性能,感觉有点不如windows流畅,终于有一天Ubuntu虚拟机开机启动不了,重装以后程序丢了,辛辛苦苦配置的环境也丢了,花了两天重新配环境,中间踩了好多坑,但我觉得如果是Ubuntu原生系统,肯定是没有问题的。于是开始转向另一种方案,windows下vscode编写,git提交到远端服务器,虚拟机中断pull下来代码进行编译烧写,因为vscode自带集成终端,所以很容易通过快捷键直接切换,完成上传,这样只需要再vscode与linux终端之间进行操作,全程只涉及一次鼠标,感觉确实非常流畅,但受制于github的访问速度,上传需要2~3秒,不过换成国内的码云效果明显提升,1s内完成,相当快捷。尤其是习惯了Linux的命令以后确实不想用windows的命令了,所以我的windows电脑命令行最常用的就是git bash 连带vscode的集成终端也摒弃了cmd换成了git bash 不得不说有时候命令行确实方便,这也就是为什么那么多人偏爱shell脚本的原因)
- 8.在linux环境下学习操作系统,系统底层调用,网络底层,c语言这些平时windows封装好的东西,一开始可能会比较难以上手,但是一但你熟悉了,效果应该是比在windows环境下更好的(这是看的别人的一条回答,但自己对编译器这一堆的了解真的是来自于Linux下的瞎折腾).
- 9.有时候确实省心,依赖于强大的包管理工具,比如安装常用编程工具,重启网卡,配置与查看ip等等......
- 10.广泛的开源社区,开放的内核以及开源的思想
- 11.最后我总结得到嵌入式Linux开发要在Linux进行的原因是开发工具多,支持广,开源,不收费,历史渊源,总结下来就是“随大流”,娱乐,办公等常用windows,但软件,嵌入式是真的常用Linux。
[知乎问答:为什么要在Linux下编程](https://www.zhihu.com/question/29404530)
https://www.zhihu.com/question/29404530
[嵌入式中为什么要用Linux操作系统](https://blog.csdn.net/memoryjs/articlehttps://img.qb5200.com/download-x/details/7912146)
https://blog.csdn.net/memoryjs/articlehttps://img.qb5200.com/download-x/details/7912146
[为什么学习Linux开发](https://tutorial.linux.doc.embedfire.com/zh_CN/latest/linux_basis/why_learning_linux.html)
https://tutorial.linux.doc.embedfire.com/zh_CN/latest/linux_basis/why_learning_linux.html
### 目前我了解到的嵌入式linux教程基本都是基于Ubuntu的,这就让我产生了疑惑,windows不香嘛,为什么要安装完虚拟机再在虚拟机上进行开发???
由此,我了解到了交叉编译,即在一种平台上编译编译另一种平台的代码,英文名称 cross compile,既然牵扯到两个平台,我们就要知道一共有几种平台,按照大类可分为两种,即精简指令集(RISC)与复杂指令集(CISC),再往下细讲就是常见的x86属于复杂指令集,ARM属于精简指令集,其他的几种平台(或者说成是架构,以下内容架构与平台概念相同)还有MIPS、PowerPC等等,其他的由于我暂时没有听到过,在此先不提及,以免给大家带来困惑。
具体大家有兴趣可以参考这篇博客
[CPU架构的分类](https://blog.csdn.net/lele52141/articlehttps://img.qb5200.com/download-x/details/5732962)
https://blog.csdn.net/lele52141/articlehttps://img.qb5200.com/download-x/details/5732962
### 为什么会有交叉编译,交叉编译的重点与难点在哪里??
由于技术水平有限,在一张博客里面截取一张进行展示
![](https://img2020.cnblogs.com/other/1617275/202003/1617275-20200322105027320-1504131500.png)
![](https://img2020.cnblogs.com/other/1617275/202003/1617275-20200322105027516-301617100.png)
交叉编译的难点在于:
1.不同架构的机器位数不同,即32位还是64位
2.不同架构的机器是大端系统,还是小端系统
3.不同架构的机器是否为四字节对齐访问
4.不同架构的机器是否支持MMU,即内存管理单元
5.不同架构的机器所支持的库以及开发环境都不相同
### 基于以上介绍,我们对应的措施是什么??
我们的电脑属于x86架构,而最终要运行的程序要运行在ARM架构上,所以这就用到了交叉编译,但无论是Windows系统的主机电脑还是虚拟机中的Ubuntu都是x86的架构,所以至少在裸机开发阶段,交叉编译是我们绕不过去的坎。其实,对于stm32的开发,在keil里完成的也是交叉编译的工作,只不过keil做的比较封闭,我们注意不到这些细节。(其次,名字也比较高大上,大家一般不会往这上面去想,类似的比如我们在单片机中死循环不断读取传感器数值的方法叫做轮询,好多东西并不是不知道,而是没有和专业的名字对应起来)
### 知道了是交叉编译,工作如何完成??
当然是选择合适的工具啦(ps:我们都不是linus,系统不让用自己做一个linux,版本管理工具不好用自己写一个git),我们的目标就是什么没有找什么,什么不会搜什么,但是名字是关键,它叫做“交叉编译工具链”。这个一会再说。
首先说一下,编译器,我们最常见的就是gcc编译器,类似的c语言程序都是gcc编译之后才可以运行的。编译的步骤现在我都可以直接背出来了,这个必须记住,这对于我们来说就像语言的语法,极其重要,不然之后的交叉编译工作就能无法完成(因为开始ARM裸机开发,别人给你灌输的最多的就是编译,编译,再编译)。
四个步骤:预处理,编译,汇编,链接。预处理主要是宏定义,头文件展开展开等,编译主要是检查语法错误生成汇编文件,汇编主要是生成目标文件,链接是将目标文件链接到一起生成可执行文件。(以上过程全部为我默写出来,嘻嘻)。这是C语言的编译过程,也是大多数程序的编译过程。
二对应到编译ARM的程序上,也是这个过程,只不过用到的工具不同
### 介绍了这么多,都有哪些交叉编译工具呢??
也可以叫做交叉编译工具链,在此我们进行谷歌搜索
![](https://img2020.cnblogs.com/other/1617275/202003/1617275-20200322105027729-1550275154.png)
接下来结合我自己理解,展开介绍
首先肯定的是交叉编译工具链是一套工具的集合,而不是单独的一个工具,类似于我们上面提到的编译的四个过程,都有对应的工具,(对应的工具完成对应的任务,自古如是),这也就是为什么我们要记下编译的具体步骤。
正点原子给我们推荐的是 `arm-linux-gnueabihf`这一套工具链这也是
```
#我们使用交叉编译链时,常常会看到这样的名字:
arm-none-linux-gnueabi-gcc
arm-cortex_a8-linux-gnueabi-gcc
mips-malta-linux-gnu-gcc
#这些交叉编译链的命名规则似乎是通用的,有一定的规则:
arch-core-kernel-system
arch: 用于哪个目标平台。
core: 使用的是哪个CPU Core,如Cortex A8,但是这一组命名好像比较灵活,在其它厂家提供的交叉编译链中,有以厂家名称命名的,也有以开发板命名的,或者直接是none或cross的。
kernel: 所运行的OS,见过的有Linux,uclinux,bare(无OS)。
systen:交叉编译链所选择的库函数和目标映像的规范,如gnu,gnueabi 等。其中gnu等价于glibc+oabi;gnueabi等价于glibc+eabi。
```
知道了这些交叉编译工具链,我们想到了,要在windows下开发选择Windows系统下的交叉编译工具链,要在Linux开发选择Linux下的交叉编译工具链不就可以了,事实上也的确如此
[什么是交叉编译](https://blog.csdn.net/whatday/articlehttps://img.qb5200.com/download-x/details/73930604)
https://blog.csdn.net/whatday/articlehttps://img.qb5200.com/download-x/details/73930604
理论介绍部分到此结束,之后介绍一下,我在正点原子的基础上自己折腾的一整套编写,编译流程
[Linaro交叉编译器下载服务器](https://releases.linaro.org/)
https://releases.linaro.org/
[Linaro交叉编译器官方下载](https://www.linaro.orghttps://img.qb5200.com/download-x/downloads/)
https://www.linaro.orghttps://img.qb5200.com/download-x/downloads/
了解更多技术文章,欢迎关注我的个人公众号
![](https://img2020.cnblogs.com/other/1617275/202003/1617275-20200322105027941-601500634.jpg)
加载全部内容