目录
概述
BIOS 自检
系统引导
启动内核
初始化系统
OS 最耗时的启动部分
现有优化措施
优化措施建议
概述
学习过计算机组成原理我们知道计算机组成的结构, 计算机是由硬件和软件组成的, 仅有一个含硬件的裸机是无法运行程序也无法实现人机交互; 另一方面, 软件也必须运行在硬件之上才能实现其价值. 由此可见, 硬件和软件是相互依存, 密不可分的. 为了能较好的管理计算机系统的硬件资源, 我们需要使用操作系统. 那么操作系统是如何将软件和硬件联系起来的呢? 我们管理的硬件在哪里呢? 这也就是操作系统的主要功能, 分别是处理机分配(进程管理), 存储管理, 设备管理, 软件资源管理.
你肯定也会想操作系统又是由什么运行启动的, 在计算机组成原理中, 我们知道 CPU 是运行程序的核心, 操作系统也可以看做一个程序的运行, 如果从开机加载到内存中执行的过程就是系统的启动. 启动操作系统的时候离不开 CPU, 也离不开指令代码, 下面就来看一下操作系统是如何启动的.
操作系统的启动英文称作 "boot" . 这个词是 Bootstrap 的缩写, 意思是鞋带(靴子上的那种). 之所以将操作系统启动称为 boot, 源自于一个英文的成语 "pull oneself up by one's bootstraps", 直译过来就是用自己的鞋带把自己提起来. 操作系统启动的过程正是这样一个极度纠结的过程. 硬件是在软件的控制下执行的, 而当刚上电的时候, 存储设备上的软件又需要由硬件载入到内存中去执行. 可是没有软件的控制, 谁来指挥硬件去载入软件? 因此, 就产生了一个类似于鸡生蛋, 蛋生鸡一样的问题. 硬件需要软件控制, 软件又依赖硬件载入. 就好像要用自己的鞋带把自己提起来一样. 早期的工程师们在这一问题上消耗了大量的精力. 所以, 他们后来将" 启动 "这一纠结的过程称为"boot" .
接下来让我们一起看看操作系统启动的流程:
P. 操作系统启动流程图
BIOS 程序首先将存储设备的引导记录 (Boot Record) 载入内存, 并执行引导记录中的引导程序(Boot);
引导程序会将存储设备中的操作系统内核载入内存, 并进入内核的入口点开始执行;
加载内核及驱动程序;
后操作系统内核完成系统的初始化, 并允许用户与操作系统进行交互.
BIOS 自检
BIOS 是固化到 ROM 存储器上的, 储存的是 BIOS 代码, 即计算机最重要的基本输入输出的程序, 开机后自检程序和系统自启动程序. 如果磁盘只有一个分区, 则不需要 MBR 引导.
1.CPU 加电之后, 会把 CPU 所有寄存器的值设为默认值, 除了 CS 寄存器的值改为 0xFFFF, 其他寄存器的值都为 0, 这样根据 CS 和 IP 的值就可以找到指令的物理地址 0xFFFF:0x0000, 也就是 0xFFFF0(Linux 系统);
2. 这时 CPU 就开始执行在这个位置开始执行, 这里存放的一条无条件跳转指令 JMP, 跳转到 BIOS 的真正启动代码处;
3. 接着执行 BIOS 程序, 其中 POST(Power-On Self-Test)加电自检程序是执行的第一个例行程序, 主要是对 CPU, 内存, 显卡, 外设等硬件设备 (包括中断向量, 设置寄存器) 进行检测和初始化. BIOS 自检阶段如果报错, 系统就无法正常启动起来. 若正常启动, 则 BIOS 开始从显卡代码存放地址加载显卡, 并在屏幕上显示最初信息;
4. 引导程序执行一段小程序用来枚举本地设备并对其初始化. 以硬盘启动为例, BIOS 此时去读取硬盘驱动器的第一个扇区 (MBR,512 字节, MBR(Master Boot Record) 是位于磁盘最前边的一段引导 (Loader) 代码. 它负责磁盘操作系统 (DOS) 对磁盘进行读写时分区合法性的判别, 分区引导信息的定位, 它由磁盘操作系统 (DOS) 在对硬盘进行初始化时产生的.), 然后执行里面的代码. 实际上这里 BIOS 不需关心启动 MBR 的内容, 它只是负责读取 MBR 并执行. 此后将系统启动的控制权移交到 MBR 部分的代码.
P.MBR 区域
系统引导
由于不同的作业系统它们的档案系统格式不相同, 因此我们必须要以一个开机管理程序来处理核心档案加载 (load) 的问题, 这个开机管理程序就被称为系统引导 (Boot Loader), 这个 Boot Loader 在开机装置的第一个磁区(sector) 里, 也就是 MBR.
系统引导指的是将操作系统内核装入内存并启动系统的过程. 系统引导通常是由一个被称为启动引导程序 (Boot loader could be more aptly called the kernel loader. The task at this stage is to load the Linux kernel.) 完成的, 它位于系统 ROM 中, 用来完成定位内核代码在外存的具体位置, 按照要求正确装入内核至内存并最终使内核运行起来的整个系统启动过程. 该过程中, 启动引导程序要完成初始引导, 内核初始化, 全系统初始化.
Stage1.(在 ROM 中)初始化硬件设备, 包括 watchdog timer, 中断, 时钟, 内存等. 为加载 stage2 到 RAM 做准备;
Stage2.(在 RAM 中)初始化该阶段硬件设备, 读取并载入内核, 为内核设置参数, 设置内核函数地址对应到 CPU 指令寄存器, 跳转至内核函数入口.
以 grub(GRand Unified Bootloader, 一个 GNU 项目的多操作系统启动程序, 用于在有多个操作系统的机器上, 在刚开机的时候选择一个操作系统进行引导)为例, BIOS 加载 MBR 中的 grub 代码后就把 CPU 交给了 grub,grub 的工作就是一步一步的加载自身代码, 从而识别文件系统, 然后就能够将文件系统中的内核镜像文件加载到内存中, 并将 CPU 控制权转交给操作系统内核. 如此, BIOS 和 grub 的工作分别构成了 stage 1 和 stage 2.
P. 系统引导载入内核
启动内核
当控制权从 boot loader 转到内核时, 内核立即初始化系统中各设备并做相关的配置工作, 其中包括 CPU,I/O, 存储设备等.
操作系统内核是指大多数操作系统的核心部分. 它由操作系统中用于管理存储器, 文件, 外设和系统资源的那些部分组成. 操作系统内核通常运行进程, 并提供进程间的通信.
因为内核需要直接与硬件交互管理各个硬件, 从而利用硬件的功能为用户进程提供服务. 启动操作系统, 我们就需要将内核代码在计算机结构上运行起来, 一个程序要能够运行, 其代码必须能够被 CPU 直接访问, 所以不能在磁盘上, 因为 CPU 无法直接访问磁盘; 另一方面, 内存 RAM 是易失性存储器, 掉电后会丢失全部数据, 所以不可能将内核代码保存在内存中.
内核文件有可能放置的位置只能是 CPU 能够直接访问的非易失性存储器 --ROM 或 FLASH 中.
但同时存在如下几个问题:
1.CPU 直接访问的非易失性存储器的存储空间一般会映射到 CPU 寻址空间的某个区域, 这是在硬件设计上决定的. 而这个区域的大小是有限的, 如果功能较简单的操作系统能够放在其中, 但对于内核文件较大的普通操作系统而言是不够的.
2. 如果操作系统内核在 CPU 加电后直接启动, 意味着一个计算机硬件上只能启动一个操作系统, 这样的限制并不是我们所希望的.
3. 把特定硬件相关的代码全部放在操作系统中也不利于操作系统的移植工作.
基于上述问题, 设计员一般都会将硬件初始化的相关工作放在 boot loader 程序中来完成. 这样做的好处就是将硬件初始化的相关工作从操作系统中抽出放在 boot loader 中实现, 则将硬件启动和软件启动分离开来, boot loader 主要负责硬件的初始化工作, 而当初始化完毕后对操作系统启动做准备. 因此, 对非易失性存储器要求不高. 同时, 它可以加载内存中已有的内存镜像, 从而实现多个操作系统的运行.
初始化系统
Kernel 启动, 并进行完硬件检测与驱动程序加载之后, 主机的硬件已经准备就绪了, 这时 kernel 会主动呼叫第一个程序, 就是 systemd(Linux 下的一种 init 软件).systemd 最主要的功能就是准备软件执行的环境, 包括系统的主机名称, 网络, 语言, 档案格式以及其他服务的启动等.
执行过程:
1. 执行系统初始化脚本(/etc/rc.d/rc.sysinit), 对系统进行基本的配置, 以读写方式挂载根文件系统及其它文件系统. 当脚本执行完后, 系统就可以顺利工作了, 只是还需要启动系统所需要的各种服务, 这样主机才可以提供相关的网络和主机功能, 因此便会执行下面的脚本;
2. 执行 / etc/rc.d/rc 脚本. 该文件定义了服务启动的顺序是先 K 后 S,rc.sysinit 通过分析 / etc/inittab 文件来确定系统的启动级别, 然后才去执行 / etc/rc.d/rc*.d 下的文件;
3. 执行用户自定义引导程序 / etc/rc.d/rc.local. 一般来说, 自定义的程序只需要将命令放在 rc.local 里面就可以了, 这个 shell 脚本就是保留给用户自定义启动内容的;
4. 完成了系统所有的启动任务后, Linux 会启动终端或 X-Windows 来等待用户登录. tty1,tty2,tty3... 这表示在运行等级 1,2,3,4 的时候, 都会执行 "/sbin/mingetty", 而且执行了 6 个, 所以 Linux 会有 6 个纯文本终端, mingetty 就是启动终端的命令.
至此, 操作系统就启动完成了, 进入用户登录页面, 加载用户程序.
P.Linux 系统启动流程图
最耗时的启动过程
由操作系统启动过程分析我们知道, BIOS 自检过程会对 CPU, 内存, 显卡, 外设等硬件设备 (包括中断向量, 设置寄存器) 进行检测和初始化, 所以 CPU, 内存, 外设这些硬件设备的性能好坏会对操作系统启动造成影响. 除了硬件对启动造成影响, 软件过多也会对降低操作系统的启动速度.
例如, 我们安装了打印机, 扫描仪, USB 硬盘等设备后, 由于 USB 接口速度较慢, 因此相应设备会对电脑启动速度有较明显的影响; 如果设置了网卡, 网络会自动获取 IP 地址, 系统在启动时就会不断在网络中搜索服务器.
而最耗时的部分应该是操作系统自启动软件程序时, 当软件过多或者插件过多时, 操作系统启动变慢.
现有的优化措施
1. 对用户软件和安装的插件进行优化处理, 删除不必要的软件和插件;
2. 对硬件性能做更进一步优化, 加快数据计算, 读写和传输速率.
优化建议
对个人用户的软件和插件进行优化;
由于硬件方面优化程度已经接近极限, 所以不建议优化硬件了;
减少外部设备的接入或安装;
断开操作系统启动后不需要的驱动或设备.
参考文献
1. 作者: 法拉利轮子
来源: http://www.bubuko.com/infodetail-2987873.html