您的位置:首页 > 其它

操作系统学习笔记--系统启动流程

2016-08-03 21:17 357 查看

本次是在学习清华大学 os课后,做的一些笔记,大部分都是引用了老师的原话,只是做了简单的修改!!!

粗略版

我们知道,操作系统是放在磁盘上的,而电脑的指令只能再cpu里执行,cpu在掉电的时候所有的内容都要清空。那到底是什么让操作系统加载到我们的cpu上面,供我们的使用的呢??电脑执行的第一条指令是从哪里来的呢??

答案就是,电脑cpu分为两部分,一部分为RAM 随机访问存储,还有一个ROM只读存储。

电脑在上电之后,cpu的ROM 只读存储 里头还会有一些我们原来写入的一些内容。我们的系统初始化代码就从那里开始执行。大小大约1M左右,这就是我们熟知的BIOS固件。



ROM就是上图从下到上的1M的内容,里面就含有BIOS。电脑一上电,cpu就开始执行他。

我们还要知道,电脑一上电怎么就能够找到BIOS的起始位置呢??

我们要求,在系统CPU完成初始化之后,它处于实模式下。 在实模式下,它的地址计算把段寄存器左移四位,然后加上它的当前指令指针,这两个加在一起作为我们当前访问第一条指定位置。即



PC就是第一条指令的起始位置。

还有一条限制是说,在加电的时候 ,它处于实模式

这个时候地址总线,并不是像我们现在用到通常系统是32位,它只有20位的地址可用,那在这20位地址里头,我们用的区域就是2的二十次方,这个时候就只有1M。这就解释了为什么放的区域就只能放在最底下1M里头一小块。

这块代码它为了从磁盘上读数据,那这个时候必须提供相应的服务,如果没有这些服务,你是没有办法访问到磁盘设备的。

为了做到这件事情,在BIOS里头 它需要提供这样一些功能,分别为:

1. 基本的输入输出

2. 然后系统的配置信息

3. 开机自检程序

4. 系统自启动程序

* 基本输入 输出

在屏幕上显示基本的信息,从磁盘上读写扇区,知道我的内存有多大,从键盘上读用户的输入。当然在这里BIOS只能提供最简单,最基本的输入 输出功能。并且它的使用也受到很大的限制,比如说在我们的英特尔的CPU上,它受到一条限制,就是你只能是在实模式下工作。那如果说我们的操作系统是工作在保护模式下,那这些就都不可以用了。

* 然后系统的配置

我们都知道系统在刚开始的时候,你需要有配置,到底是从硬盘启动 ,从网络启动,还是说从光盘启动。

这些启动是在你加电的时候,由你的BIOS的设置来完成。依据这些设置,系统执行它的启动程序。就是把硬盘里的加载程序和操作系统内容先后加载到cpu当中当中来。

具体的过程 我们可以这样来看

在BIOS初始化完成之后,BIOS它就会从磁盘上把引导散区的程序(

这个引导散区是只有长度512字节) 读取到cpu的指定位置0x7C00。然后cpu就跳转到该固定位置,把控制权转到从磁盘上读进来的这个程序,我们称他为 “加载程序”。加载程序里头我们又可以做进一步的事情。(更长的它没有这个能力。在BIOS程序,它不允许你能读更多内容)。

这加载程序能干什么呢???

它能将操作系统的代码读到内存里头来,并且能把控制权交给操作系统,来继续执行操作系统功能。



如上图所示,把加载程序放在了cpu地址为0X7C00上面了(位于BIOS下面,所以不能大)。操作系统放在了BIOS的上面。

这个时候有个问题 ,你既然能从磁盘上读数据,那为啥我不直接从BIOS里头直接把操作系统的内核映像读进来呢???

实际上,首先我们磁盘上是有文件系统的,文件系统是多种多样的。我们在机器出厂的时候,不可以说我直接限制死你,你只能用某一种文件系统。为了增加这种灵活性,但是我在BIOS又不可能加上认识所有文件系统代码。

那怎么办? 我就在里有一个基本约定

我不需要认识格式,我也能从里头读到你的第一块。我只读第一块。

读了这块之后 ,这块的加载程序里头,我们会用加载程序来识别你磁盘上文件系统。这时候,我就能够认识磁盘上文件系统,我就可以读到我内核的镜像,并且把它加载到内存当中来。这就是我们这里看到,用加载程序读到操作系统来。有了这个过程之后,我们再把相应的控制权转到读进来的操作系统内核代码上,我们操作系统就可以开始运行的。

略详细版

其实在cpu初始化完成后,BIOS并不是直接去读磁盘扇区的加载程序的。

比如说我们在最早的时候,电脑磁盘里只有一个分区,cpu和BIOS都初始化完成之后就直接到分区里找文件系统了。但是对于我们现在来说,所有的计算机,或者大多数的计算机里头都不止一个分区,可能会有几个分区。每个分区上会装不同的系统。那这个时候就在前边加上一个主引导记录。

这个主引导记录是说,我要从哪个文件系统里去读我的这个加载程序。在主引导记录执行完,然后我就进到当前某一个分区里头,分区里头又有该分区的引导扇区,通过这个活动分区的引导扇区,再来加载我们刚才说到的加载程序。可以参考下面这张图。第一个框是在cpu上面执行的,其他三个是在磁盘上面执行的。



那我们具体说起来,有这样几个过程!!!

cpu初始化,找到自己的第一条指令!!!

首先我们在前面已经说过,CPU加电完成它的初始化,到一个确定的状态去读第一条指令。我们需要知道CPU初始化之后,它的代码段段寄存器和当前指令指针寄存器这两个的内容,算出来它的第一条指令在内存当中的什么地方。

因为它是实模式,所以是CS和IP都是16位的,CS左移四位和IP加在一起算出我的位置。这个时候 我放到内存当中的BIOS的位置,只能是在最底下的一兆,原因在于这时候它是20位的地址。有了这个之后我们就直接进到BIOS里执行。

进入BIOS,进行BIOS的初始化!!!

首先第一个是硬件自检

也就是说我们有可能加电起来之后,你的内存出错, 那整个后边就没法做。

我们说在计算机系统里头它的加电自检,它上来之后是看最关键的这几个部分是不是在工作。这就相当于在自检的时候关键的内存 显卡这几部分是否存在,如果存在的话 ,它的工作状态是什么样子。

然后完成设备每一个这些关键性的接口卡里头它自己的初始化程序。这些初始化程序完成之后,那我就认为关键的设备是可以的了。

然后是使用系统配置表,找到指定外部设备的系统(比如,U盘,磁盘等)

我们说我们现在的系统,很多都是可以即插即用的。如果说我想从一个USB接口的光驱里启动,那你怎么启得来???

这时候, 在这个BIOS里的自检,现在是能够做到系统的自检!!! 我们说在BIOS里有一个系统配置表,这个配置表就是我们这里所说的 ESCD ,就是扩展系统配置数据。那用这个数据 我就能知道,我当前系统里都有些什么样的设备。每次加电之后有可能你会插上新的卡或者说拔掉已有的卡,这个数据会因为这些操作而发生改变。每次加电的时候这个数据都必须审阅,可能会修改一次。做完之后,我就把控制权转到我们从磁盘读到cpu的数据里头。读进去的数据就是我们说的主引导记录。

主引导记录MBR格式



由于有的电脑不止一个分区,所以上面我们说的,读入到cpu的数据,就是我们需要的主引导记录。我们说主引导记录有512字节,但是在这 ,你只能说我可以用到的是446字节。

那其他部分是什么??原因是当我的电脑后边有多个分区的时候,要把这些分区的状态也要存到这512字节里头。由上图可以看到,每个分区的信息占用16个字节,所以硬盘分区表里最多只能有4个分区。

所以这样的话,你就只有446个字节的内容来执行你的启动代码。而这个启动代码是用来检查我分区表是否正确,然后还要加载并跳转到你的活动分区的引导记录上去。

前面的是启动代码446字节,中间的你的硬盘分区表16*4=64字节。最后是一个结束标志,这个结束标是55AA,有了这个之后 ,它才认为这是一个合法的主引导记录。

分区引导扇区格式



那有了以上主引导的操作之后,它就会跳到你活动分区的引导扇区上去。

从上图可以看出,

先是跳转指令,跳转指令平台相关了, 你的CPU不同,这个地方这条指令肯定也是不一样的。

然后是文件卷的信息。

再之后是我的启动代码,这个地方的启动代码就需要认识你的格式说,我这个加载程序不是存在在512字节里头的,存在别处的。它在哪?那就靠你这里的代码来约定说我放在哪。而这里的代码实际上是我们存在硬盘上的或者说你的软盘上的,因此我是可以改动的,那改动完了之后,我就可以把我的加载程序放在任意的地方,只要我在这标识出来我上哪去认识它就可以。

最后是结束标志,这个结束标志跟刚才那个主引导记录是一样的,也是55AA。有了这个之后 ,它才认为这是一个合法的分区引导。

加载程序(bootloader) ,开始加载我的操作系统到我的cpu里面的



从上面分区的启动代码,就找到了我的加载程序。

接下来我们说加载程序的细化

我们说加载程序它首先不是直接去加载你的内核,而是去文件系统当中读一个启动配置文件。依据配置文件的配置(参数)去加载内核,依据这个,就选择你启动的模式,比如说我是在正常启动,还是说我是在安全模式启动,还是说我是在一个调试状态下启动我的系统。

那这些区别都会读出来之后,它导致我在加载内核的时候的一些内核会不一样,或者说我加载的时候的参数会不一样。

这个启动配置文件,在不同的操作系统里它是会不一样的,比如说Windows和Linux都有自己的格式。

为了能让不同的硬件平台有相同的启动流程,所以产生了BIOS。

BIOS也再不断改进,相继变成 BIOS-MBR,BIOS-GPT,UEFI。这些资料有时间wiki一下,就不细讲了!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  操作系统