目录
前言:
对于Linux的实现从硬件到软件做一个全面的总结
一、ARM芯片的简要介绍
二、Linux的编译环境搭建
2.1什么叫交叉编译环境
2.2什么是编译
2.2编译软件命名规则
2.3编译软件制作
2.4编译环境搭建
2.5编译小工具
三、Linux系统需要什么
3.1BootLoader
3.1.1为什么需要BootLoader
3.1.2BootLoader是怎么工作的
3.2内核镜像
3.3根文件系统
四、Linux应用程序编写
五、Linux内核的研究
一直接触到各种芯片架构,但是在网上具体看架构到底是什么,怎么理解,就有点看不懂了,就是介绍指令集这些,RISC(精简指令集),CISC(复杂指令集),下面写下来,免得以后自己忘记了。
就从一个加法汇编指令入手,一个加法运算。
先来看看CPU的基本组成部分,反正不管什么架构的芯片,大概架构都是这样。而ARM、X86他们区别是什么,说简单点就是指令集不同,指令集不同就意味着下面的译码器,寄存器等等都不一样。下面这个图,新手看肯定直接懵逼,我第一次之前看着也是感觉看着都明白,但是组合在一起就不懂了,如果可以找到一个人,边讲解这个图,一边在一个ARM芯片上单步运行,实时查看寄存器的变化,顺便讲解寻址之类的。通过这样一个实操,能很快就明白这些内容,明白这些对以后学习操作系统很用帮助,因为很多操作系统中的内容需要结合硬件才能理解。
ADD 操作数,被操作数。
执行a = b+c这条语句。
1、这个语句转化为汇编需要如下:
把b取出来到缓存寄存起——>把c取出来到缓存寄存起——>操作缓存寄存起将二者相加在放入缓存寄存器——>在储存大储存器(如果是全局变量,要是局部变量,可能就放在缓存了)
这里面就涉及到部分架构的问题了,都知道ARM一共有37个寄存起。有通用寄存起,有特殊寄存起。对应了上图中的缓存寄存起,条件寄存起,程序寄存起,除此还有堆栈(SP)寄存起,链接寄存起(LD)。在搭配上指令,指令是什么,ADD,也是一个32位的数子(也有16位的)。如果真想搞清楚这些,建议看看这本书《编码:隐匿在计算机软硬件背后的语言》,我不知道有没有书能把计算机讲的比这个更清楚的,但是这本书是一本初高中水平就能看懂的书籍。当然不清楚这个指令是如何实现的也没关系,只需要知道他能操作两个数相加就行了。
这也是架构的基础,在深入就是细节了,说实话,我对这些也不是特别清楚,也记不住那么多,但是有了上面对架构了解的基础,就可以随时翻阅架构手册去找相应的内容来看。
交叉编译环境对应的是本地编译环境,什么是本地编译环境,用VS写个上位机软件,在本电脑运行,这是本地编译。交叉编译环境是什么,可以理解为异地编译环境,就是在电脑上编译需要在ARM芯片运行的软件,为什么要这么干,因为电脑的算力强。要是你ARM芯片算力够强,同时也有对应的编译软件,也能在ARM上搭建编译环境,但是咱没听说过有这么干的。交叉编译英文名叫 cross compile,用英文来说,我觉得形容还挺到位,但是翻译成交叉编译,我以前反正是挺奇怪为什么叫这么个名字。
编译就是compile和link,就是编译器和链接器。编译器把所有c文件变成单个的二进制文件obj,然后在用链接器把这些所有的二进制文件链接到一起变成一个可执行的二进制文件。具体的原理可以有空看看编译原理这本书,反正我是看了两页就看不下去了,以后有需要再看吧。但是呢可以看看格式,二进制文件的格式,这对理解Linux也是很有帮助的
平常买的开发板,编译软件包都是厂家直接给的,而且叫的名也不一样,所以这个编译软件是怎么来的。参考本链接
看看这个编译软件的名字arm-xscale-linux-gnueabi-,这些代表什么呢
ARM:芯片架构,也有其他的。
xscale:这个其实是在制作编译软件时候作者随便取的,有的开发板就用开发板信号命名,有的用厂商,要是我们自己制作,也可以起自己的名字
linux:就是linux系统,
gnueabi:这个也是我们看到又时候不同的ARM也不一样,反正这些代表工具链,有几个选择,具体也没搞清楚,可以参考上面的链接文章。
方法很多,这儿就Mark下这一种,详细的就百度看,知道又这么个东西就行了,需要用的时候再研究
crosstool-ng的主页:http://crosstool-ng.org/
编译环境,说白了也是一堆软件包,平常调用软件包,怎么调用,把路径写出来加上软件名,就行了。这样不方便,所以就把这些编译环境软件包的路径添加到环境变量,这样我们调用的时候就只需要软件名称,比如arm-xscale-linux-gnueabi-gcc,这就是为啥要添加环境变量。
上面说了,编译环境是一堆软件包,咱们也不能真的一个个调用这些软件包啊,要是单个文件还行,要是涉及到成千上百怎么办,所以需要用make,统一写Makefile,Makefile的编写又是需要学的一套知识,当然先学会用,有空再学怎么写,先知道为什么需要这么个工具。
介绍完这些,就能理解为什么在观看Linux编译环境搭建教程视频时候,需要这么操作。
这个基本都知道BootLoader,内核镜像、根文件系统。
为什么需要BootLoader,我们会回答为linux系统运行做准备。那做什么准备呢,什么初始化ram,准备堆栈,为c语言运行做准备。
那为什么裸机程序就不需要呢,裸机程序中,最开始运行的.s文件,其实压根就不是BootLoader,这个单词有个loader,load是有个转移数据的行为在里面的呀,而裸机的.s其实只是做了准备堆栈跟BootLoader能扯上,实际上根本不是一回事,裸机当然也有bootloader,只是写程序的人根本就不需要用到而已,这个后面介绍。
还是看这个图,裸机程序都是直接放在储存器里面的,程序一上电是直接运行的,没有从外部搬运的过程。
操作系统呢,操作系统的程序最开始在哪,可能在硬盘,在emmc,在TF卡,在flash等等,所以BootLoader是干什么的,是把内核软件loader进上图中的存储器,也就是我们常说的内存条。
这就是为什么操作系统需要启动时间,裸机程序不需要时间的原因。两人赛跑你的终点是人家的起点。
所以自己组装电脑,什么都能省,硬盘不能省,买读写速度快点的,会直接提升人的使用体验,我们说的电脑卡,大部分原因就是硬盘读写速度慢,因为硬盘的读写速度远远小于CPU的速度。
BootLoader最开始也是跟内核软件一样在EMMC、TF卡、硬盘里面。BootLoader是怎么进入内存来搬运系统内核呢,芯片内部有一段ROM,储存着一段出厂固化程序,这部分程序是一次性烧写的,当然也很小执行不了复杂的操作。由这段程序先把BootLoader搬运到内存后,再由BootLoader来搬运系统内核。等内核搬运完毕,BootLoader的任务完成就可以被覆盖或者擦除了,这个时候芯片运行有内核接管了。
具体BootLoader干了什么,可以研究一下U-boot这就又是大篇幅,网上资料多,暂且不表。
上一节中写道裸机也有BootLoader,只是是在下载程序时候使用,平常使用串口下载工具下载裸机程序的时候,其实也是先通过ROM下载一段BootLoader,在用BootLoader来把真正的应用程序下载到芯片的flash里面,过程其实跟上面差不多。
经过上面的说明,现在可以明白BootLoader其实就是一段裸机程序。主要任务是搬运内核,当然也与一些初始化外设,堆栈的作用。
从官网或者镜像站下载内核源码,然后进行裁剪,生成我们需要的内核。这个没有什么有疑惑的地
万物皆文件
如果用C++、C#、python随便一个写过上位机软件,会发现,Linux的应用软件很接近。不需要操作硬件,只需要调用各种接口,其实比裸机的应用程序编写要简单了,当然肯定还是不明白背后的逻辑是什么,但没关系,照葫芦画瓢就行。所以我觉得正确的linux入门方式觉得是先搞明白应用程序怎么写,再去研究内核,而不是用应用程序写了一个helloworld就直接研究驱动,研究内核。我学生时代就是这么搞的,钻进内核出不来了,直接整放弃了。
我是在搞明白FreeRTOS的内核以后,回头想之前看到Linux,才豁然开朗,以前看不明白的一些也想通了,所以研究linux,可以试试先学会一个RTOS。我是适合这样,我觉得没有上过专业操作系统课的人最好这么学,墙裂推荐野火的freertos教程,跟着操作一遍,要不了一个星期就能明白,这个时候再去看linux或者鸿蒙的liteos都很快上手,磨刀不误砍柴工。
(待补充......)