凡亿专栏 | (0)学习嵌入式Linux之前,先看看这篇文章
(0)学习嵌入式Linux之前,先看看这篇文章

作者之前编写了一系列嵌入式Linux的开发文档:

b04cc30cca9048cc4f50974e55c853.jpg

        当编写到一定程度的时候,回过头再看看这些文档的内容,结合一部分网友的反馈,反思了一下。之前的文档,更多的是站在技术总结的角度去编写,而非入门初学的角度。这些文档似乎更适合有一定经验的开发者进行查阅,而非入门初学者进行手把手学习。这样就导致了,当一些入门初学者在阅读文档的时候,会遇到一些基本概念,而恰好这些基本概念作者一笔带过,导致初学者看不下去。于是,现在再补充一篇文章,站在作者理解的角度,尽量去描述一下嵌入式Linux开发过程中可能遇到的基本概念。

        鉴于作者本身的水平有限,同时也是在边学习边总结,因此这篇文章不会涉及太深入的技术细节,作者只是站在自己的理解角度去描述这些概念。由于每个人对概念的理解都可能会有所差异,如遇到描述错误或有所纰漏的地方,希望提出指正,感谢阅读。

        本文的目标是:引导初学者快速地在嵌入式Linux开发板运行一个helloworld程序。何谓快速,就是把一些开发过程中共同的东西都抽象出来,不会拘泥于细节,不会拘泥于具体的硬件开发板平台,也就是俗称的“开发套路”。而这些开发套路,对任何的嵌入式Linux开发板,基本上都是通用的,当熟悉了这些套路之后,开发者很快就可以上手其他嵌入式Linux开发板。


什么是嵌入式Linux开发平台

什么是嵌入式Linux开发平台?一句话高度概括:“它是一台电脑”。

5d8cb1c75358578dd1ad647171021a.jpg

        从宏观的角度去描述,嵌入式Linux开发平台跟我们平时用的个人电脑没有本质上的区别,因为在嵌入式Linux开发平台也有个人电脑上所描述的处理器CPU,内存,硬盘,显示器,网口,USB接口,耳机接口,等等。

        这些硬件在嵌入式Linux开发平台上,处理器有可能被叫作CPU或MPU;内存有可能被叫作SDRAM或DRAM或DDR;硬盘有可能被叫作NandFlash或NorFlash或eMMC;显示器有可能被叫作LCD屏幕。所以,本质上来说,嵌入式Linux开发平台,就是一台微电脑。但它的性能和功能没有我们用的个人电脑那么强大,麻雀虽小,五脏俱全。好了,点到即止,入门初学者暂时知道嵌入式Linux开发板是一台电脑就行。


u-boot,内核kernel,文件系统rootfs之间的关系

        我们回到公司后,每天都要做的事情就是打开电脑,流程基本上都是:按下开机键 --> 屏幕亮起 --> 看见windows系统的引导界面 --> 看见windows系统界面 --> 成功登陆windows系统 --> 打开我们的办公软件。

        而嵌入式Linux开发平台的开机过程也是类似:接通电源线,按下开机键 --> LCD屏幕亮起 --> u-boot引导内核 --> 内核加载硬件驱动程序和挂载文件系统 --> 进入文件系统 --> 运行应用程序。

        整个过程简单总结如下图所示:

988dfec5d7f65330c7dc4b4ed316f7.jpg

u-boot:它类似于我们个人电脑里面的BIOS,有计算机知识的人基本都知道BIOS是什么,如果不考虑其他强大的功能,入门初学者只需要知道u-boot是用来引导内核的,并传入合适的启动参数给内核。u-boot只要能成功引导内核,它就是一个合格的可用的u-boot。

内核kernel:入门初学者可以把它理解为我们的windows操作系统,但其实,内核是在整台电脑背后默默工作的。它的工作很多,如进行进程调度和管理(进程可以理解为我们平时用的应用程序,如QQ,微信,office办公软件),内存管理,驱动管理,等等。我们平时生活里面操作电脑时,看见的“我的电脑”,“C/D/E/F盘”,其实是文件系统,而不是操作系统内核。

文件系统rootfs:这个就可以简单理解为我们电脑里面的“我的电脑”,“C/D/E/F盘”了,在Linux的世界里面,一切皆文件。我们开发的时候与Linux系统进行交互,都是基于文件系统进行文件操作(如复制,粘贴,删除,新建,运行,等等)。

        总而言之,一个能成功运行的嵌入式Linux系统,上电后必须经历的过程是:u-boot引导内核,引导成功后,由内核加载文件系统。由于我们编写的应用程序是存在于文件系统里面的,因此,必须加载文件系统成功后才能运行应用程序。应用程序需要内核进行调度才能运行。看到这里,是不是觉得这个过程跟我们平时生活中使用的windows系统很相似?


开发者怎样跟嵌入式Linux开发板进行交互?

        我们平时在使用windows操作系统时,比如,想打开一个应用程序,只需要用鼠标双击桌面上的应用程序图标,应用程序就开始运行起来。但在嵌入式Linux开发平台里面,开发者用得最多的就是命令行,就是那个看上去黑色的操作界面(某种程度上,使用命令行操作也可以显得很有x格)。

        如果你想在windows的电脑上新建一个文件夹,你可以使用鼠标“右键”--> “新建文件夹”,但在嵌入式Linux上,你需要使用mkdir 命令。如果你想在windows的电脑上查看某个文件夹里面的内容,可以双击打开这个文件夹,但在嵌入式Linux上,你需要使用ls -al命令。

        所以,命令行是开发者与嵌入式Linux板卡交互的桥梁,开发者想让嵌入式Linux板卡进行某些动作,必须使用命令行。但是,这些基本的命令,我们不需要花太多的时间刻意去学习,只需要大概学习一遍,然后在开发的过程中就会不断熟悉。在嵌入式Linux开发里面,通常20%的常用命令就可以满足大部分的工作内容了。


嵌入式Linux开发,需要掌握的基本技能

        不管你的工作岗位是嵌入式Linux系统工程师,还是嵌入式Linux驱动工程师,还是嵌入式Linux应用工程师,有些通用的基本技能(如安装虚拟机,安装和配置Linux发行版操作系统,安装交叉编译工具,安装开发IDE,等等),是必须要掌握的,一旦这些技能掌握了以后,在很多开发场合都能得心应手地面对工作。

        在描述这些安装的细节之前,先描述一些基本的概念:

虚拟机:顾名思义,它是一台虚拟的机器。我们现在有一部分开发者是在windows系统下进行开发工作的,如果完全摒弃掉windows转为Linux系统,可能会无所适从。因此,使用虚拟机安装Linux发行版(如ubuntu,Debian,等)无疑是一种折中的选择。虚拟机其实就是在现在windows系统上,再虚拟多一台电脑设备,这台虚拟出来的电脑,可以安装ubuntu系统。

交叉编译工具:可以简单地理解为一个编译器。其实这个工具链里面还包含了汇编器,链接器,反汇编工具,调试器,等等。我们在进行MCU开发时所使用的MDK,IAR这类工具,就是编辑器,编译器,链接器,调试器的大集合,所以,这类工具对开发者很友好。而在嵌入式Linux的环境里,都拆开为一个个具体的工具,因此在环境搭建的时候,嵌入式Linux通常比单片机要复杂很多。为什么要交叉编译?交叉编译这个概念不太难理解,简单地说,就是我们的芯片设备是ARM平台或者其他平台,而我们的Linux发行版(如ubuntu)是x86或者x64平台的,在这些平台上对程序进行编译等一系列工作,就需要交叉编译器,这样编译出来的可执行程序才能在我们的ARM平台上运行。

Linux发行版:可以通俗理解为我们平时用的台式电脑或笔记本电脑里面安装的Linux系统,这类系统有很多,如ubuntu,Debian,CentOS,RedHat,等等。这类系统都是基于Linux内核的操作系统,跟我们的嵌入式Linux内核都差不多,但功能比嵌入式Linux强大得多。一般在开发过程中,我们可以称这类系统为宿主机或Host PC。

        理解完以上概念之后,不管你现在的工作岗位是系统移植,驱动开发,应用开发,都需要进行以下的基本工作。根据这些步骤,多操作几遍就会很容易熟悉。

(1)嵌入式Linux开发环境搭建-(1)安装VMware Workstation虚拟机

之所以安装虚拟机,是为了方便以前使用windows的开发者。如果电脑硬件性能足够,使用虚拟机是有好处的,它不会对我们原有的操作系统进行破坏,初学者可以方便地在虚拟机里面学习,备份也很方便。如果已经熟悉了虚拟机软件的安装,跟我们平时windows安装软件一样,比较简单。

(2)嵌入式Linux开发环境搭建-(2)VMware虚拟机下安装Ubuntu16.04.2 LTS

虚拟机安装完之后,就相当于有一台电脑给我们使用了。我们可以在这台电脑上面安装ubuntu系统作为开发时的Host PC。如果有多台物理电脑的开发者,可以不使用虚拟机,直接在物理电脑上安装ubuntu系统,安装方法跟博客里面的差不多,大同小异,多摸索几遍就知道了。

(3)嵌入式Linux开发环境搭建-(3)配置Ubuntu16.04.2 LTS 系统

ubuntu系统安装完后,是不能直接就进行开发的。需要对系统进行一定的配置,才能进行嵌入式Linux开发。这些通用的配置包括,配置网络环境,便于我们的windows,ubuntu,开发板三者可以相互ping通。安装FTP服务,NFS服务,我们使用这些服务进行三者之间的文件传输。作者本人用得比较多的文件传输方式是:windows与ubuntu之间,使用Filezilla工具基于FTP协议传输文件。而开发板跟ubuntu之间,使用NFS网络文件系统,让开发板挂载ubuntu系统指定的文件夹(相当于开发板跟ubuntu之间的共享文件夹)进行文件传输。

(4)嵌入式Linux开发环境搭建-(4)安装交叉编译工具链

配置完ubuntu系统后,因为我们的Host PC是x86或x64平台的,要在这种平台上编译程序并运行于开发板的ARM平台,那么就要进行交叉编译工作。交叉编译是使用交叉编译工具链进行的。这些交叉编译工具链,不需要自己去网上查找,开发板的厂家一般会提供他们优化好的交叉编译工具链,初学者一开始不需要纠结交叉编译工具链是如何制作的,只需要先学会使用,先完成自己的入门学习,有时间再回头深入研究交叉编译工具链的制作过程。

(5)嵌入式Linux开发环境搭建-(5)安装和配置Qt Creator开发工具

当以上工作都准备就绪以后,基本上已经能够进行嵌入式Linux开发工作了。在Linux的开发环境里面,也有一些好用的开发IDE,类似于单片机开发的MDK,IAR这类编译器。作者本人在开发嵌入式Linux应用程序的时候,主要使用Qt Creator这个IDE。网上有很多关于Qt Creator的安装介绍,在这里就不再详细描述了。如果初学者的工作是进行驱动开发或者系统移植,可以使用Notepad  这类编辑器,修改完代码后,再进行交叉编译。

(6)嵌入式Linux应用程序开发-(1)第一个嵌入式QT应用程序

完成以上环节搭建工作后,就可以开始进行应用程序开发了,以上搭建的环境,已经适合驱动程序开发,应用程序开发,系统移植等等。当然了,在实际的开发过程中,肯定会根据实际的开发情况再进行环境的改变,但套路都是一样的,都是安装某些工具包,然后修改ubuntu的配置文件,使ubuntu系统适合我们进行嵌入式Linux开发。


如何把应用程序放到开发板运行?

        在进行单片机开发或调试的时候,我们通常使用仿真器(如J-link)连接单片机和电脑,使用MDK或IAR这类软件编辑完代码后,点击编译按钮就可以编译生成 .hex 或 .bin 文件。然后通过下载按钮,下载到单片机运行,单片机每次重新上电,都会运行我们之前下载到单片机的程序。

        而嵌入式Linux的应用程序开发,跟单片机的开发有很大区别。嵌入式Linux应用程序开发,可以使用已经配置好交叉编译工具链的Qt Creator工具,进行编辑,交叉编译等工作,同样也可以很方便地编译出应用程序的可执行文件。这个可执行文件因为是交叉编译生成的,因此只能运行在嵌入式Linux开发板。

        前面提到,嵌入式Linux开发板跟ubuntu系统是通过NFS网络文件系统的方式进行文件传输的,相当于ubuntu系统中有一个共享文件夹,用来跟Linux开发板共同进行文件传输。那么,如何创建这个共享文件夹呢?

        假设,我们要把应用程序的可执行文件,从ubuntu复制到开发板的指定目录,我们使用ubuntu的目录 /opt/share 和开发板的 /mnt 目录进行文件共享。就可以使用mount命令,直接把开发板的 /mnt 目录和 ubuntu的 /opt/share目录共享起来。以后我们要在ubuntu和开发板之间传文件,ubuntu系统只要把文件复制到 /opt/share 目录,我们的Linux开发板的/mnt目录就会出现这个文件,同理,我们把开发板里面的文件放到Linux开发板的/mnt目录,在ubuntu系统的/opt/share目录也会出现这个文件。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表凡亿课堂立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。
相关阅读
进入分区查看更多精彩内容>
精彩评论

暂无评论