印象系列-linux内核启动过程

·  阅读 647

其实我在大学的时候已经思考过这样的问题,软件运行在操作系统上,但操作系统本身又如何在一堆硬件中完成启动?在思考这样的问题时,我当时的脑子只能停留在这样的一个场景:用手指按下电脑的开机键,然后。。。电脑。。。就这么启动了。。。

原谅我当时的困惑,我根本无法用专业知识去描述这个过程。好在,或许我现在可以尝试延续这么一个过程,去分析按下电源键后发生的事情。

在理解这么一个过程时,有必要先了解几个名词:CPU、寄存器、内存、存储盘(硬盘、软盘)、内核、中断、指令、Bios、Boot。大家对CPU和内存、存储器应该比较熟悉,这里先做简要介绍。

CPU:计算机的大脑,所有的运算几乎在这里进行,我们这里举例机器在一个单核的CPU上进行,那么CPU每单位时间就只能执行一条指令,我们所说的CPU执行速度快是指CPU执行频率高,好比说每一秒CPU可以连续执行多少亿条指令。

存储器:这里特指磁盘,也就是常说的电脑硬盘,磁盘是一种机械结构,可以理解为由很多扇区组成,每个扇区可容纳固定的字节数,这种结构和存储方式决定了磁盘是一种非易失性存储器,能在断电下保存大量数据,是电脑保存数据的主要场所。但读写速度有限,特别是随机读写状况下。

内存:一种易失性存储器,断电后数据就丢失了,但存储速度非常快,和磁盘相比至少是10万级别的速度优势。所有的代码想被执行,首先都需要从磁盘加载进内存空间中,是计算机进程运行的重要空间。

好了,以上三种部件可以先在脑海里构建一个运行流程了:所有的执行代码放在磁盘,磁盘的数据在运行时会被加载进内存空间,最后CPU会从内存空间读取指令实现处理。这是最笼统的基本印象了。

那么从笼统的印象加点专业性,那么就还需要去了解上文提及的其它几个概念了。

寄存器:寄存器也是一种存储介质,只不过寄存器的存储速度非常快,快的能匹配CPU的读取速度。刚刚说了,CPU处理频率很高,动不动就一秒钟上亿次运算,如果中间所有的数据都需要从内存读取的话,内存也吃不消,只能让CPU放慢速度,等数据送到CPU来才继续处理,这样的结果可想而知,漫长的等待只会让你的电脑慢的像狗一样。而寄存器就存放着CPU会高频使用的数据,比如保存一些执行地址、临时变量、还有操作系统相关的核心数据等。

指令:CPU执行的最小单位,一般来说,任何语言编写的代码程序会被编译为一条条顺序执行的指令,我们通常说的CPU处理速度,往往就是根据指令的单位处理条数来表示的。

中断:中断这个概念其实也很抽象,个人认为,中断就是一个突然的触发,被触发的对象收到中断请求后将执行对应的操作。比如说显示器显示一个数字,其实就是受到了键盘主动发过去的一个中断请求;还有就是从磁盘读数据,其实就是磁盘驱动器受到了CPU发出的一个读的中断请求,磁盘受到中断后就得忙起来开始去对应位置读数据了。这里例子中的中断特指硬中断,硬件的操作基本上都是通过中断来实现的。

Bios:启动操作系统的核心程序,一般是固化到计算机主板中,也就是说,这个程序一开始就已经设定好并写死了,计算机开机后其实就是直接执行这个程序块。

Boot:引导启动程序,实际上是真正引导机器启动操作系统的核心程序,一般保存在软盘或硬盘的固定位置,将被Bios程序读取到内存,并以指令形式传递到CPU执行。

内核:内核非常抽象,很多人一听到内核除了知道是个操作系统核心外就没有其它认识了。其实可以这样理解,内核就是操作系统的一个很大的程序,这个程序和各种底层硬件打交道,还开放了接口给上层的用户程序去访问。基本上脏活累活都是内核在统一管理,所以内核的技术含量也比较高,十分复杂。

那么,电脑上电后发生了什么事情?刚刚介绍了Bios这么一个概念,它是启动操作系统的程序,目前来说,厂家出厂后都已经规定好这个Bios程序将会做什么事情,因为Bios写死在主板的固定位置,所以硬件一上电就直接在固定位置读取这个程序,Bios程序将变成一条条指令传达到CPU执行,这些指令告诉CPU,将在软盘(或硬盘)的固定位置读取引导启动程序(Boot)。好了,这个时候Bios的任务其实差不多完成,因为Boot程序将接管接下来的引导操作。

在这里,我们以Linux0.11版本为例来描述这个引导过程,对于其他不同操作系统来说同样具有代表性。引导程序将事先保存在硬盘的固定位置,可抽象成如下图表示:


图中表示Linux内核在磁盘上所占扇区的情况,假设磁盘拥有1.44Mb,即2880个扇区,其中Boot程序占用第一个扇区,setup模块占用随后4个扇区,内核程序(即system模块)大约占用240个扇区,剩下扇区将用于构建文件系统。

在Linux0.11内核启动过程中,电脑上电后,Bios直接去磁盘把Boot程序加载到内存某固定位置处并执行,而在Boot程序执行期间,将会把磁盘第二个扇区开始处的4个扇区的setup模块和system模块也加载到内存某固定位置并交付给CPU执行。setup模块是干嘛的?setup模块的指令利用中断过程读取机器的系统数据,比如确定下这台机器有多少内存啊、显示器版本怎样啊、当前显示器的光标位置放在第几行几列啊,硬盘大小情况啊,然后把这些数据存放到内存的某个地方,后面的内核启动过程将从对应位置读取这些数据从而了解当前的硬件环境,做好初始化工作。最后,setup程序将跳转到system模块的执行位置,CPU将在这里进行内核程序的真正启动过程。

好了,上面就是从机器上电到启动内核的整个过程。当然,文中目的只为灌输整个启动流程的基本印象,省去了大量细节的描述,这些细节涉及到具体的硬件操作和代码执行逻辑,如果要探讨这个过程,三言两语道不清,但不妨碍我们先掰开第一个窗,让这个过程不那么神秘。总之,我们需要认清一个事实,就是从机器上电一开始,很多引导程序必须事先按照协定放在某个位置处,机器也将在上电后从固定位置读取并交由CPU开始执行,整个流程下来完成一些列的初始化操作,最终才跳转到内核程序执行!








分类:
后端
分类:
后端
收藏成功!
已添加到「」, 点击更改