操作系统从MBR到加载内核的开机过程

计算机如何启动

本文参考了很多博客和教程。

文章目录

  • 计算机如何启动
    • bios
    • MBR
      • bootstrap代码
      • 分区表
    • 启动扇区
    • bootloader
  • linux 0.11早期
  • 多操作系统和系统分区
    • 分区工具fdisk和dd
  • 硬盘与文件系统与块设备
  • 写在最后

  1. boot大概
  2. MBR到GRUB详细
  3. [阮一峰]博客
  4. 西工大蔺学弟实验报告

操作系统从MBR到加载内核的开机过程_第1张图片

对于现代使用MBR启动的操作系统,总的来说,开机到加载操作系统内核一共有以下几个步骤

  1. BIOS检查硬件,并且检测可以启动的软/硬。
  2. BIOS最后的指令是中断int 13h,该中断会加载用于启动的软/硬盘的第一个扇区的代码,俗称MBR,MBR里面有446个字节的代码,64字节的分区表,2字节的签名(0x55 0xAA)用于表示这个设备是可用于启动的!!如果发现后面签名不对,则查找下一个启动盘的MBR。
  3. MBR会加找到启动软/硬盘的活动分区(分区),并且加载其中的代码,如果系统有bootloader,则加载bootloader。常见的bootloader有grub,lilo。
  4. 加载bootloader后,系统会提示选择哪个操作系统,对于装了多个操作系统的硬盘,bootloader会定位到正确的扇区加载内核镜像。
  5. 所谓的加载无非就是拷贝代码到ram,然后jmp到目的地址开始执行代码。

bios

  • bios是焊在板子上的rom代码,这段代码会获取硬件详细的参数(比如系统的CPU型号,系统时间),并且从设备中寻找可能启动的设备(硬盘或者软盘或者其他)。找到设备后,加载这个设备的第一个扇区的代码到内存0x7C00。

  • 开机上电那一刻,CPU会自动将内存地址映射到这个ROM芯片上,开机就去取bios代码了。

MBR

MBR一定是在硬盘的第一个扇区。

MBR包含三部分

  • bootstrap代码(446字节,用到的只有前面440字节)
  • 分区表(64字节)
  • 签名(2字节):通过这个值判断该硬盘是不是真的可用于启动

操作系统从MBR到加载内核的开机过程_第2张图片

bootstrap代码

  • 这部分代码主要是用于在分区表找到活动分区。bootstrap的工作流程如下图(这个有点小问题,从加载EBR(EBR)开始,后面结束条件应该是要么找到了活动分区,要么遍历完所有扩展分区了)
  • 注意每个分区表项信息的第一个字节就是表明当前分区是不是活动分区!!

操作系统从MBR到加载内核的开机过程_第3张图片

  • 从上面流程可以看出,这段代码总是先判断分区是扩展分区还是主分区。因为扩展分区变数大,甚至可能没有。在windows磁盘工具会发现,默认情况下,前面三个分区总是主分区。扩展分区都在后面。不会出现扩展分区在中间的这种情况。
  • strap代码总是找到第一个活动的分区,然后就加载这个分区的代码。所以如果有多个活动分区,后面的活动分区是不会被加载的。

分区表

  • 每个主分区信息占16字节
(1)第1个字节:如果为0x80,就表示该主分区是激活分区,控制权要转交给这个分区。四个主分区里面只能有一个是激活的。0x00表示非活动分区。

(2)第2-4个字节:主分区第一个扇区的物理位置(柱面、磁头、扇区号等等)。

(3)第5个字节:主分区类型。如果这里的值=5,意味着这个分区是扩展分区

(4)第6-8个字节:主分区最后一个扇区的物理位置。

(5)第9-12字节:该主分区第一个扇区的逻辑地址。

(6) 第13-16字节:主分区的扇区总数。
  • 分区类型有很多种,比如NTFS,FAT…

  • 一个活动分区通常叫做boot分区

启动扇区

  • MBR找到第一个活动分区后,会加载活动分区的代码。通常这段代码所在位置也是活动分区的第一个扇区,即512KB,这段代码通常被称为boot代码(boot.bin),这个扇区的最后两个字节也是0x55aa
  • 一个扇区实在是太小了,也放不下多少代码,所以boot.bin的下一步是加载一个叫做loader.bin的代码。现代操作系统中grub是一个典型的loader
  • loader负责加载完整的内核镜像

bootloader

  • 注意,grub是一个linux的软件,其实际上是一个bootloader。这个loader所在的文件系统必须是fat类型。

  • bootloader有很多,grub只是其中的一个

操作系统从MBR到加载内核的开机过程_第4张图片

当MBR将权限交给boot.bin之后,实际上boot.bin可以直接就是内核代码本身。但是因为可能有多个操作系统,这个boot.bin需要加载一个叫做loader的程序,它会在同一个分区下寻找loader,然后告诉CPU去执行它。这时候CPU需要自己去文件系统里查找这个loader所在的扇区,然后加载到内存。

一般的bootloader工作流程如下

操作系统从MBR到加载内核的开机过程_第5张图片

  • bootloader会去找到内核镜像,并且把内核镜像加载到内存中开始执行。
  • 注意,CPU从bootloader开始就已经处于保护模式了!!!

那么bootloader是怎么加载内核的呢?如下图所示
操作系统从MBR到加载内核的开机过程_第6张图片

linux 0.11早期

linux 0.11的源码在赵炯先生的网站可找到。在boot目录下一共有三个汇编文件分别是bootsect.s, setup.s, head.s。其中bootsect.s就是处于第一个扇区的440字节的代码(MBR), setup.s可以看作是bootloader,而head.s则是linux kernel的前部分。这里没有使用到grub。

多操作系统和系统分区

  • 每个分区要使用,就必须安装文件系统在分区上。而且只有安装了文件系统才能被挂载到目录下。

一个硬盘最多只能有四个主分区。由于分区表只有446字节,所以个数限制:主分区+逻辑分区不超过4,逻辑分区不超过1个

实际上,并没有逻辑分区这种分区类型。硬盘的分区类型只有主分区和扩展分区,所有的扩展分区组合成了一个逻辑分区

  • 在不使用扩展分区时(4个分区的分区类型均不为5,4个分区都是主分区),分区表中的‘开始扇区’的值,就是对应分区的开始扇区,而这个扇区中存放的往往就是boot程序,将这个扇区加载到内存即可。所谓的boot程序有可能就是一个bootloader,或者直接是操作系统内核代码。

  • 当某个分区的分区类型为扩展分区时,属性‘开始扇区’就指向EBR(Extended Boot Record)所在的位置,EBR是一个与MBR结构相同的扇区。逻辑分区可以有任意个逻辑分区,这些逻辑分区使用一个类似链表的结构串起来。

    操作系统从MBR到加载内核的开机过程_第7张图片

分区工具fdisk和dd

  • fdisk可以管理分区(添加分区,删除分区),是交互式的应用。使用fdisk分区的过程实际上就是通过fdisk修改了分区表中的相关字段,可以通过xxd命令查看镜像文件的16进制内容来验证这一点。 fdisk不仅可以对物理硬盘分区,也可以对

  • dd可以用于创建硬盘镜像

dd if=/dev/zero of=a.img bs=512 count=2880 
  • mkfs.fat 用于将一个磁盘设备格式化(安装操作系统)
  • 为什么使用dd而不是cp制作镜像

硬盘与文件系统与块设备

  • 这个等学了之后再写(文件系统真的没学好)

写在最后

  • 文中的图都是我从参考资料搬运过来的。如果有侵犯请告诉我。
  • 有关bootloader(grub)在硬盘上的安装位置(和MBR的位置关系),以及如何使用grub的链式启动的知识之后再补上
  • 上面讲的全是使用MBR的启动方式,实际上,由于现代的硬盘随便就是好几个T,已经不能使用MBR格式来分区管理了。所以现代很多操作系统都是使用EFI/GPT格式的启动方式。

你可能感兴趣的:(linux)