操作系统是怎么一步步启动起来的?

开发 前端
既然普通程序是被操作系统加载运行起来的,那么操作系统又是被谁加载到内存运行起来的?

大家好,我是小风哥,今天来聊聊操作系统是如何启动起来的。

和我们写的helloworld程序一样,操作系统本身也是一个程序,被编译后作为文件保存在磁盘上。

图片图片

我们的程序是被操作系统加载到内存运行的,在前一篇文章《程序是怎么一步步运行起来的》中有过讲解:

图片图片

既然普通程序是被操作系统加载运行起来的,那么操作系统又是被谁加载到内存运行起来的?

图片图片

想知道问题的答案,我们要从内存说起。

内存只有在加电后写入数据才能保存信息:

图片图片

内存断电后这些信息就丢失了:

图片图片

当计算机启动时内存中一片荒芜,显然CPU不能执行来自内存中的指令:

图片图片

那么在你按下开机按键时CPU执行来自哪里的指令呢?答案是来自ROM或其它非易失性内存:

图片图片

这些存储设备中保存了一小段指令,计算机启动时CPU会执行这一小段程序。

CPU怎么知道这段程序保存在哪里呢?答案是CPU会从一个提前设置好的位置开始执行指令,在IA-32架构在CPU会从0xffff0这个位置开始执行这段程序。

这一小段程序就是我们熟悉的BIOS(Basic Input/Output System),更现代的是UEFI(Unified Extensible Firmware Interface)。

图片图片

BIOS这段程序有什么作用呢?这段程序用来检查硬件,各个硬件是否能正常工作等,CPU、内存、硬盘等,也就是所谓的自检,如果恰好你拆过机器忘记把内存条装回去,那么这一小段程序就会检测出系统中没有安装内存并给出告警提示。

图片图片

BIOS程序除了检查硬件之外在最后一步有一项重要的工作就是识别出操作系统保存在了哪里,也就是找到所谓的启动设备,这一般都是磁盘。

找到启动设备后开始把磁盘前512字节的数据拷贝到内存,这512字节就是所谓的MBR:

图片图片

其中包含了:

  • 一段程序,这段程序的目的是加载其它程序,因此也被称之为boot loader
  • 磁盘分区表,识别磁盘的各个分区

此时BIOS执行完毕,CPU开始执行MBR中的这段boot loader程序:

图片图片

这段程序的目的是根据磁盘分区表加载一个更大的boot loader。

图片图片

这个更大的boot loader功能更加强大复杂,如果你安装的是多操作系统,那么当这个更大的boot loader开始执行时会给你一个选项,在这里可以用户可以选择启动哪个操作系统。

图片图片

在这里可以看到MBR中的boot loader程序加载了一个更大的boot loader程序,也因此这两个boot loader分别被称之为First stage boot loader和second stage boot loader,也就是一阶段引导程序和二阶段引导程序。

图片图片

你可能会有疑问,为什么要有多阶段引导程序呢?为什么不能一阶段引导程序直接加载操作系统呢?

原因就在于MBR这个512字节的引导程序功能过于简陋,只能把磁盘中一段连续的数据copy到内存,加载操作系统这种多文件组成的大型程序需要解析文件结构,因此需要另一段功能更为强大的程序也就是二阶段引导程序的帮助。

二阶引导最终识别出操作系统所在的位置并把操作系统加载到内存中。

图片图片

此时CPU才开始真正执行操作系统,操作系统和我们写的程序一样也有一个初始化的过程,这个过程的最后会创建出一系列用户态进程,此时操作系统系统启动完毕可以接受用户的输入。

图片图片

当然在现代使用UEFI的现代系统中就不需要MBR中的一阶引导程序了。

以上就是操作系统启动的基本过程。

责任编辑:武晓燕 来源: 码农的荒岛求生
相关推荐

2024-08-30 08:30:29

CPU操作系统寄存器

2024-11-11 10:28:33

操作系统Unix系统

2022-02-24 08:30:24

操作系统CPU程序

2024-08-06 09:29:54

程序机器指令字符串

2024-09-30 09:56:59

2017-01-19 21:08:33

iOS路由构建

2018-07-13 15:36:52

2019-03-05 14:09:27

Docker存储容器

2019-07-09 15:23:22

Docker存储驱动

2018-12-24 10:04:06

Docker存储驱动

2010-03-04 16:28:17

Android核心代码

2017-12-25 11:50:57

LinuxArch Linux

2016-11-02 18:54:01

javascript

2024-06-27 08:30:36

内存扩容堆区

2011-05-10 10:28:55

2020-12-24 11:19:55

JavaMapHashMap

2018-06-11 15:30:12

2018-04-23 14:23:12

2019-04-01 10:15:02

2017-01-06 15:13:25

LinuxVim源代码
点赞
收藏

51CTO技术栈公众号