前言
先大概概括一下当按下电源的一瞬间之后发生的事把,先是启动电源,然后是初始化北桥,以及核心的硬件设备,然后将程序(BIOS)载入内存中,读取南桥CMOS中的数据, 建立SMBIOS,接着就是我们所熟悉的开机自检,所有硬件设备,寄存器都没问题的后,就通过bootloader加载我们的内核,在initrd的协助下,加载我们所系统所需要的所有文件系统,模块或者说是驱动。所有的东东加载完毕后linux就会 启动我们系统的第一个进程-------init。它是所有进程的祖宗。
上面只是一个大概的流程,接下啦,我们就详细讲讲完整的开机流程。在讲流程之中,会穿插讲一些比较重要并且基础的概念。比如BIOS.CMOS,SMBIOS等等。好了,话不多说,开始。
BIOS和CMOS
当用户一按下电源键,CPU就会先被激活,毕竟这玩意是计算机的大脑,没这玩意儿,电脑就是一堆会电人的废铁。然后CPU回去寻找BIOS,接着BIOS会先在Flash Memory中执行,加载CMOS中用户所喜好的设置值,然后BIOS才会将自己家压缩到计算机的主存储器中。此时,若用户按下[DEL]或F1 F2之类的一般PC的BIOS设置键,就可以进入BIOS所提供的设置选项,从而看到所有的设置值,或是当用户进去操作系统后,操作 系统就可以参考内存中的BIOS资料,访问每一个硬件的地址。
BIOS全名为基本输入输出系统,是系统哦,操作系统本质上来说还是一个运行在硬件之上的软件,所以加载它之前首先要做的就是确保每个硬件都没问题,并且得到初始化,BIOS就是干这些活的。BIOS本质来说只是一个烧录在主板上的程序,程序本身的职责是干活,但是它干活 的时候的一些数据呀,配置呀怎么办?你不能一股脑的存在程序里,毕竟你还得和通过与用户交互,然后保存用户所定义的配置。而CMOS这玩意儿就是用来让BIOS存储用户设置的地方,它在南桥的一个特殊的区块里面,在BIOS选项中可以设置的值都是存储在这一区域中的。主板上的纽扣电池就是为了CMOS保存资料提供电源的。当BIOS激活时回去先确认CMOS中的资料是否正确,如果正确,便会将之前用户存储在CMOS的资料,加上已存在或找到的硬件信息,整合成为一个表格,写到内存中,这也就是最开始提到的SMBIOS。如果发生错误,则会自动以默认值取代CMOS提供的资料。(利用这个原理,可以修改CMOS数据,使其发生错误,用默认数据替代CMOS中的资料,可以达到清除开机密码的目的~)SMBIOS是个不大的空间,主要的角色是扮演如何让主板或系统厂商将x86架构的系统通过BIOS呈现在 用户面前,并且提供给BIOS的开发人员足够的信息,让BIOS和一些自定义的硬件去沟通.
Power On
从 用户按下电源开关的那一瞬间 到 BIOS POST阶段,称为Power On阶段 ,也就是所谓的激活电源阶段。
在Ppwer On阶段,BIOS的主要工作是检查主机上某些硬件的状态及存储在CMOS中的设置,看可能有哪些例行工作是要进行或无法执行的,因此,用户无法在屏幕上看到BIOS所显示的信息(要 等硬件确认后才会激活VGA)。所以当由于某些情况而造成无法开机时,在屏幕上是看不到任何信息的,唯一可以抽丝剥茧排除问题的方式只有两种:看PORT 80信息,以及听哔哔的报警声。
power on虽然是一瞬间就完成的事,不过在这个过程中发生了不少事情,比如初始话BIOS,各种数据区,检查CMOS,各种硬件设备的控制器,输入输出设备,显示信息,比如cpu信息等,是否进入设置 模式信息(就是按什么键进入BIOS设置),初始化实时时钟的时间日期。巴拉巴拉,为后面的POST做准备。上面提到的BIOS加载SMOS相关的东东也是在这阶段啦~
bootloader
前期主板上的,最基本上的事情已经结束,当设置完成,硬件驱动成功及硬件 检测都没问题之后,BIOS就将加载操作系统的主控制权交给硬盘内的主引导扇区(MBR),让藏摄与MBR中的开机管理程序可以将指针带到系统信心的地方。将bootloader这玩意儿之前,我们还是得简单说明一下MBR这玩意儿。MBR就是我们硬盘最前面 的第一个扇区,一个扇区是512字节,MBR被分为三个部分前446字节,保存着bootloader核心程序,446字节呀,多么小的空间,在这么小的地方放一个加载整个操作系统的核心程序,想想都觉得厉害。接下来的64字节使我们的分区表,每16放一个分区的信息,比如从那个位置分区开始,那个地方结束 ,分区 的文件系统类型巴拉巴拉的~当然我所说的这种比较老的东东~新的东东暂且不提,毕竟对于说明开机流程没啥用~第三部分是固定的两个 字节,内容是55aa,类似标记结束的东东。bootloader负责加载我们linux的内核,但是内核保存在文件系统中,而且加载内核的时候我们还希望能给内核传递一些参数,如果我们有好几个系统,我们也希望bootloader提供给我们一个选单,以便打开的我们所选择的系统,想想都好复杂。。。。。。所以再牛逼的程序员都不可能把这么多功能的提示信息放在小的可怜的446字节中,446字节多小?446个字母所站的空间,223个汉子所占的空间。好吧,既然bootloader要完成的工作这么多,而mbr也就那么小,怎么办?或许我们可以搞一个更大的空间来保存所有程序,但是程序相关的配置文件呢?程序可以死亡,复制。但是配置文件我们却希望一直存在。说了这么多,最后的结果是bootloader被分为两个阶段,我们称为stage1和stage2,stage1里放最核心的程序,最后再跳转到stage2,stage2放在一个固定的文件系统内,stage1可以固定的跳转到某个固定的位置,加载stage2,stage2这个程序没有大小限制,就可以有很多功能了,我们上面所提到的功能都是stage2提供的,当然,还有另一个问题,bootloader的配置文件必须得以文件的形式保存在文件系统的目录下,但是,系统加载目录里面的文件时,必须得有文件系统的驱动才可以呀~如果文件系统都是ext系列,我们就不用管那么多,一个驱动就可以搞定,然后就可以轻松加愉快的加载我们的配置文件。但是,事实上的情况是,文件系统总类繁多,我们不能总是把bootloader存储的文件系统一直只是一种文件系统,为了提供更多文件系统类型的支持,我们就在stage1和stage2中间加了一个被称为stage1.5的阶段,当安装bootloader的时候,就会根据我们boot文件所处的文件系统类型,把相关的驱动写在一个固定的存储空间内。好,bootloader所有的阶段都出现了,我们在总结并发展一下~bios加电自检结束后会根据用户选得第一启动设备,假如是硬盘,就把硬盘前32KB加载到内存,前512字节是MBR,其中前446字节是bootloader的第一阶段,主要的任务就是跳转到第二扇区的程序,第二扇区到后面一拖的某个地方(小于32KB)就是stage1.5安装的位置,因为stage1.5里有启动文件所在文件系统的驱动,所以会在某个目录下找到stage2的阶段,并加载stage2与配置文件。那个我们经常看到的选择系统的界面就是stage2提供的~还记得吗?bootloader的主要作用是什么呢?对!虽然这么绕,其实它的作用依然没变,为加载内核服务!
加载内核
当GRUB加载kernel时,kernel会先在内存中制造一个rootfs当作临时的空间供系统使用,接下来kernel便会将initrd当作一个系统将其挂载到rootfs上并激活,initrd主要在开机时为加载内核提供一些核心的模块。这个initrd是个什么东东呢?这玩意儿是在我们安装系统时,根据操作系统以及内核所生成的一个压缩文件。里面包括加载内核和操作系统所必须的核心驱动,以及加载操作性的所有过程都是由initrd里面 的一个叫做init的脚本文件提供,initrd被挂载在rootfs上后,会根据init脚本一步一步的加载操作系统,如果我们把initrd打开会发现里面有一个核心的目录树,比如/dev中存在 的 是一些设备文件,当initrd加载时,这些设备文件便可以开始运行。/lib目录里面存放许多的模块,也就是驱动程序,都是开机所必须加载的模块。在 kernel加载initrd之后,initrd将会加载这些必要的开机模块,以顺利进入硬盘中的操作系统。以及保存开机后所有进程,硬件相关信息的目录等等。总结一下就是,要加载内核和整个操作系统之前,你得有整个文件系统的驱动把?你得启动所有的硬盘设备把?所有硬件设备的信息得有保存的地方把?而所有的操作都是由运行的程序执行了,所以程序的信息也得有地方保存把?所以initrd就是为了加载内核,加载整个操作系统提供必要的环境的~
切入实体操作系统
当所有 系统环境该有的文件系统基础建设及设备等相关文件都建立完成后,initrd最后的工作就是要通过iinit脚本文件做转换操作,将所有的一切交给存在硬盘中的实体操作系统。切换文件系统 的过程很简单,其实也复杂 ,大概过程是这样,linux是目录树结构,根是起点,所有在某个目录下建一个目录/sysroot然后把完整的文件系统文件全一股脑的放进去,当然是有规矩的放。所有东西放完之后,会把/sysroot切换为实体操作系统的主目录也就是根。完成后再把之前initrd存在内存中的资料清空。然后一个完整的操作系统就诞生啦~操作系统是诞生了,但是诞生之后可是空无一物的。我们需要一个类似女娲的东东--------所有进程的祖宗init进程,来生成所有 需要 用的进程~下次我么再分享,整个操作系统加载完之后是如何初始话整个环境以及生成各种进程的~
转载于:https://blog.51cto.com/xiaofengfeng/1875357