Skip to content

Latest commit

 

History

History
37 lines (30 loc) · 4.02 KB

操作系统启动过程.md

File metadata and controls

37 lines (30 loc) · 4.02 KB

这篇文章记录操作系统启动引导过程

操作系统的运行模式

80386开始,cpu有三种工作方式:实模式,保护模式和虚拟8086模式。实模式是早起intel cpu(80286及之前)的工作模式,20根地址线,可访问内存为1MB。没有内存保护和多任务等概念。当前系统都不在工作实模式下,但是开机时还是需要通过实模式加载和引导到保护模式的(因为开机启动时执行的BIOS指令是16位模式,工作在实模式下)。

操作系统启动过程简介

  1. cpu引脚中有一个是RESET,每次加电,处理器都会执行一个硬件初始化,将内部所有寄存器内容初始化到一个预置状态。对于Intel 8086,设置cs:ip为0xffff:0000,其他寄存器全为0,根据下面的实模式内存布局图可以看到该内存区域为BIOS入口地址(在Intel 8086中,BIOS ROM占据着整个内存空间顶端的64KB,物理地址范围是0xf0000~0xfffff), BIOS ROM中在物理地址0xffff0的地方,一般是一个跳转指令,比如jmp 0xf000:0xe05b,在这里,BIOS将执行一些工作,例如硬件的诊断、检测、和初始化,让硬件处于一个正常的默认的工作状态,最后要做的一件事情是从外存储设备读取数据进行加载,具体内容:从设置的系统引导设备顺序一一检查每个盘第一个扇区(512字节)的最后两个字节是否是0x55aa,如果是,则认定是一个启动区,否则继续检查下一个引导设备的第一个扇区,直到找到这样一个扇区为止。找到这样一个扇区后,中断程序将对应的512个字节数据拷贝到地址为0x7c00处(不纠结这个为啥0x7c00,历史就这么约定的),然后将对应的cs:ip 设置为 0x0000:7c00,注意在执行主引导记录程序时cs是0x0000,不是0x07c0,因此再编写汇编时,段起始地址是0。

实模式下内存布局

起始地址 结束地址 大小 用途
FFFF0 FFFFF 16B BIOS入口地址,此地址也属于BIOS区域
F0000 FFFEF 64KB-16B BIOS区域
C8000 EFFFF 160KB 映射硬件适配器的ROM或内存映射式I/O
C0000 C7FFF 32KB 显示器适配BIOS
B8000 BFFFF 32KB 用于文本模式显示适配器
B0000 B7FFF 32KB 用于黑白显示器适配器
A0000 AFFFF 64KB 用于彩色显示器适配器
9FC00 9FFFF 1KB EBDA,扩展BIOS区域
07E00 9FBFF 约608KB 可用区域
07C00 07DFF 512B MBR被BIOS加载到此处
00500 07BFF 约30KB 可用区域
00400 004FF 256B BIOS Data Area (BIOS数据区)
00000 003FF 1KB interrupt Vector Table(中断向量表)
  1. 步骤1中设置cs:ip后,接下来cpu就应该从0x7c00处执行代码,此部分代码数据就是我们在镜像中对应的前512个字节数据,这512个字节我们称之为MBR扇区,一般在MBR中实现操作系统代码的加载(完成操作系统代码从镜像文件到操作系统的拷贝)。在我们最开始的时候,我们只是在第一个扇区中执行了打印字符串功能(BIOS提供的中断程序能力)。
  2. 在MBR扇区中,执行数据拷贝,将镜像文件中的操作系统数据拷贝到内存中,然后再设置cs:ip,跳转到对应的操作系统代码起始点,此时进入操作系统代码执行
  3. 汇编语言中,关于标号不得不说的事情 在写主引导区程序时,关于标号,我常常会陷入迷惑中,不知道标号代表的是该指令对应的段地址,还是偏移地址,该偏移地址又是指啥 首先可以确定的是,肯定不是段地址,段地址对应了一个很大的范围,不能精确定位到某条指令; 其次该指令确实是代表的偏移地址,但是该偏移地址是多少就要分两种情况了:
  • 假如在程序头部声明了org 标号,指明了程序被装在到内存中的地址,那么标号代表的地址就是该指令的地址-第一个指令的地址+org表示的其实地址
  • 如果程序没有声明org标号,那么标号代表的地址就是该指令的地址-第一个指令的地址
  1. 由4引发的对$,$$符号的思考