0%

计算机是如何启动的?

“pull oneself up by one’s bootstraps”

why boot?

reboot,在我刚接触linux的时候学到了这个命令。boot,意味启动,原意为靴子。

靴子跟启动是怎么联系起来的呢?

boot实际上是bootstrap(鞋子背带)的缩写。

“pull oneself up by one’s bootstraps”最初来自于《The Surprising Adventures of Baron Munchausen》这本书里的一个故事:主人公Baron Munchausen不小心掉进了一片沼泽,他通过自己的bootstraps将自己拉了出来。事实上在19世纪初美国就有”pull oneself over a fence by one’s bootstraps”的语言,意思是“做荒谬不可能完成的事情”。

计算机的启动时一个矛盾的过程:必须先运行程序,才能启动计算机,但是计算机不启动的话就无法运行程序。

早期的时候,工程师们想尽各种办法,把一段程序先装进内存,然后计算机才能正常启动。这个过程被比喻为为拉鞋带(bootstrap)。

启动

BIOS

无论是在可视化界面中进行点击,还是在命令行中输入命令来执行程序,实际上在一个已经运行中的操作系统中执行程序。那么在开机加电的一瞬间,内存中是没有程序的,更不用说操作系统,所以我们不可能从软件的角度去执行BIOS,那么就只能从硬件的角度去分析。

CPU硬件逻辑设计为加电瞬间将代码段寄存器(CS)的值设置为0xFFFF,偏移量(IP)的值置为0x0000,这样CS:IP就指向了0xFFFF0这个地址上,这也是BIOS程序第一条指令所在的位置。

上述过程是一个纯硬件完成的动作,如果这个地址没有可执行的代码,那么计算机将什么也不做并陷入死机,反之如果有可执行的代码,则将从这个代码开始沿着后续的程序一直执行下去。

上世纪70年代,只读内存ROM(read-only memory)被发明出来,开机程序被刷入ROM芯片中

计算机通电以后,干的第一件事情就是去读取它。

这块芯片中的程序被称为 基本输出输入系统(basic input/output system),也就是简称后的BIOS。

BIOS程序被固化在计算机主机板上的一块很小的ROM芯片里。通常,不同的主机板所用的BIOS也有所不同,就启动部分而言,各种类型的BIOS的基本原理大致相似。随着BIOS程序的执行,屏幕上会显示显卡的信息、内存的信息……说明BIOS程序在检测显卡、内存……这期间,有一项对启动(boot)操作系统至关重要的工作,那就是BIOS在内存中建立中断向量表和中断服务程序。

中断向量是指早期的微机系统中将由硬件产生的中断标识码(中断源的识别标志,可用来形成相应的中断服务程序的入口地址或存放中断服务程序的首地址)。中断是指在计算机执行程序的过程中,当出现异常情况或者特殊请求时,计算机停止现行的程序的运行,转而对这些异常处理或者特殊请求的处理,处理结束后再返回到现行程序的中断处,继续执行原程序。

中断向量表中有256个中断向量,每个中断向量占4个字节,其中两个字节是代码段寄存器(CS)的值,两个字节是偏移量(IP)的值,每个中断向量都指向一个具体的中断服务程序。现在,可以先将中断理解为一种技术手段,在这一点上与C语言的函数调用有些类似。

BIOS被读取之后干了这么几件事

  1. 硬件自检

    BIOS先对计算机硬件进行检查以确保其能满足计算机的运行条件,称为 硬件自检POST(Power-On Self-Test)。

  2. 基于启动顺序移交控制权

    在硬件自检后,BIOS需要将控制权交给下一阶段的启动程序。

    交给谁,交到哪。BIOS需要一个外部存储设备的排序,排在前的设备就是优先转交控制权的设备。这种排序被称为 启动顺序(Boot Sequence)

主引导记录

BIOS按照启动顺序将控制权移交给排在第一位的存储设备。

计算器去读取这个设备的第一个扇区(最前面的512个字节)。如果这512个字节的最后两个字节是0x55与0xAA,则表示这个设备可以用于启动,如果不是则控制权顺序移交至下一位。

这512个字节,称为 主引导记录(Master boot record),是采用MBR分区表的硬盘的第一个扇区。

主引导记录的主要作用是:告诉计算机到硬盘的哪一个位置去寻找操作系统。

主引导记录分为三部分

  • 1-446字节:调用操作系统的机械码
  • 447-510字节:分区表(Partition table)
  • 511-512字节:主引导签名(0x55,0xAA)

分区表的作用是将硬盘分成若干个区,分区表的长度为64个字节,其又分成四项,每项16个字节。一个硬盘最多分为四个一级区,也叫做主分区。

每个分区是16个字节,由六个部分组成:

  • 1字节:如果为0x80,则表明该分区是激活分区,控制权将交由该分区。四个主分区中只能有一个是激活的
  • 2-4字节:主分区第一个扇区的物理位置(柱面,磁头,扇区号等等)
  • 5字节:主分区类型
  • 6-8字节:主分区最后一个扇区的物理位置。
  • 9-12字节:该主分区第一个扇区的逻辑地址
  • 13-16字节:主分区的扇区总数

由四个字节决定了扇区总数,一个字节八个bit,也就是扇区的总数最多是2的32次方(4294967296),按照每个扇区是512个字节,即最多存储2199023255552个字节,也就是2147483648kb,2097152mb,2048GB,2TB。

硬盘启动

计算机的控制权将交由硬盘的某个分区,又可分成三种情况

  • 卷引导记录VBR(Volume boot record)

    四个主分区只有一个分区是激活的,计算机会读取激活分区的第一个扇区,称为卷引导记录VBR。

    卷引导记录的作用是告诉计算机,操作系统在这个分区的位置,然后计算机就会去加载操作系统。

  • 扩展分区与逻辑分区

    当四个主分区不足时,我们需要更多的分区。但是分区表仅有四项,因此规定有且仅有一个区可以被定义为 扩展分区(Extended partition)。

    扩展分区中又分成多个区,这种区称为逻辑分区(logical partition)。

    计算机先读取扩展分区的第一个扇区,扩展引导记录EBR(extended boot record)。其内有一张64字节的分区表,但是最多只有两项(即两个逻辑分区)。

    再读取第二个逻辑分区的第一个扇区从其的分区表中找出第三个逻辑分区的位置,以此类推知道某个逻辑分区的分区表只包含它自身。

  • 启动管理器(boot loader)

    在计算机读取主引导记录前446字节的机械码之后,不再将控制权移交给某一个分区,而是运行启动管理器,由用户选择启动哪一个操作系统。

操作系统

控制权交由操作系统后,操作系统的内核首先被载入内存。

如Linux,内核载入成功后,运行/sbin/init,其根据配置文件产生init进程,pid为1。然后init线程加载系统的各个模块,直至执行/bin/login,跳出登陆界面,由用户输入账号密码。

参考

计算机是如何启动的? - 阮一峰的网络日志 (ruanyifeng.com)