基本常识
-
BIOS: 是指主板硬件厂商, 在主板上烧写的固件程序,也就是说BIOS 是一段存储在主板上的程序, 当然,你可以联系厂商,索要他们的BIOS 各个版本的固件程序;
-
内存: 通常是一个长方形的内存条;
-
启动设备: 是指包含了一个
bootsect.s
文件的设备, 该文件是汇编代码,大小为 512 字节, 作用是负责引导操作系统的启动;(bootsect.s 通常存放在电脑的硬盘上,而当我们使用U盘给电脑装系统时,bootsect.s存放在U盘上;)
(所谓能够引导系统的启动设备,是指包含了启动文件bootsect.s 的设备, 该文件的大小512KB, 正常情况下在电脑硬盘上。
装系统时,会存在U盘中, 使用U盘装过系统的同学,应该体会到,会让你选择一个启动顺序,系统从哪个盘开始启动。)
- 引导扇区就是启动设备的第一个扇区, 启动设备信息被设置在CMOS中CMOS: (64B-128B)。用来存储实时钟和硬件配置信息。
打开电源开机后, 计算机执行的第一条指令从何而来?
计算机的本质, 取指执行 , 即取指令, 执行指令。
那么最初开机时, 指针IP 指在哪里? 执行的指令又是什么?
对于X86 机器而言:
- x86 PC 开机时,处于实模式;
- 此时, CS=0XFFFF, IP=0X0000;
- 寻址到 0XFFFF0 , 到达ROM BIOS 区域;
- BIOS 进行硬件检查, RAM, 键盘,显示器,内存,硬盘等;
- BIOS 将启动设备的0磁道,0扇区的内容读入到内存0X7C00处;
- 设置CS=0X07C0, IP=0X0000;
因此,开机后, 在执行完 BIOS 后, 硬盘上的第一个扇区上存放着第一个我们可以控制并修改的程序。
使用汇编语言编写 bootsect.s 的原因是为了实现对硬件精准的控制,
而c语言通过编译生成后的汇编, 会产生出一些意外的语句, 这在硬件启动过程中, 是不允许发生的。当然了, c语言和C++ 语言相比于其他语言的优势, 能够对内存实现更加精准的控制。
在汇编语言中:经常遇到表达说, 左移四位,注意这里所说的左移四位 指的的是二进制中左移4位, 即乘上了 2 4 2^4 24, 即乘上16倍。
而在汇编语言中, 由于通常数据表示成 16 进制, 故二进制左移四位即代表了十六进制中左移一位。
1. 操作系统启动的引导流程
首先, 先大体说一下, 系统启动时的总体顺序, 然后再依次介绍 bootsect.s
, setup.s
, system模块
这三个文件的作用。
1.1 整体顺序
当电源开启时, CPU主要完成两大任务, 将程序读入内存, 初始化硬件资源分配。
-
cpu 会执行主板中的BIOS 程序, BIOS 程序会将
bootsect.S
载入到内存中oX7c00
处。 -
boosect.S
的移动自身在内存中的位置,从oX7c00
移动到oX90000
处,然后开始执行。 -
boosect.S
执行过程中,并且将setup.s
载入到内存0x90200
,system
模块载入到内存0x10000
处。 -
setup.s
开始执行, 将system
模块从内存0x10000
处移动到0x0000
处, 并且从实模式切换到保护模式。 -
system
模块中,前两个依次执行head.s , main.c . 依次执行这两个文件。
图片2, 各个时间段文件的作用
1.2 实模式和保护模式的切换
注意, 其中 bootsect.S
, setup.s
是运行在实模式的机制下, 所以此时使用的是16位的汇编代码, 写成的;
当运行到system 模块时
, 此时便切换到了保护模式下, 此时head.s
是32 位的汇编;
所以,bootsect.s 和setup.s是实时模式下运行的16位代码程序,采用近似Intel语法,
而head.s使用GUN汇编格式(AT&T),并且运行到保护模式下。
操作系统的启动过程中, 涉及到汇编种类如下:
- 实模式下的 16位 汇编的 运行机制;
- 保护模式下的 32位汇编的运行机制;
- 保护模式下,内嵌汇编, 即在C语言中内嵌了汇编代码, 为了实现对部分硬件的精准控制。
注意:实模式和保护模式对应,实模式的寻址CS:IP(CS左移4位+IP), 和保护模式(32位汇编模式下)不同。
2. 三个模块文件的总览
所谓的三个重要模块,是指 bootsect.S
, setup.S
, system
模块,
而BIOS 文件是由硬件厂商固化在主板上的.
BIOS 的功能作用, BIOS 程序主要完成了以下功能任务:
- BIOS完成硬件自检. 开机以后,BIOS将对CPU、内存、显卡、键盘等设备进行初步检测,如果硬件自检成功后,开始将下一步。
- 时间段1: BIOS 将bootsect.s 读入到内存中. 检测出第一个能够引导系统的设备,比如硬盘或者U盘或者光驱(现在电脑多数没有了), 将其中的bootsect.s 读入到内存中
ox7c00
的地址处, 对应图片中的时间段1.
以下, bootsect.s
, setup.s
, system模块
运行顺序,结合这张图的时间轴理解:
2.1 bootsect.S
的作用
这里介绍重要的功能作用, 其他更加具体的作用,在分析该文件时,进行介绍。
-
将自身的位置移动,对应图中的时间段2: bootsect.S 刚开始由BIOS 载入内存中的时候, 是放在内存
ox7c00
的地址处, 现在在执行的过程中, 他将位置移动到0x90000
处, 将原来的位置腾出来, 给其他人使用。 -
时间段3:
bootsect.S
将setup.s
拷贝到内存中, 放在ox90200
处, 为什么呢, 因为bootsect.S
占用了512KB 的大小, 表示成十六进制是 2 ∗ 1 6 2 + 0 ∗ 1 6 1 + 0 ∗ 1 6 0 = 200 2 * 16^2 + 0 * 16^1 + 0 * 16^0 = 200 2∗162+0∗161+0∗160=200, 所以为了将setup.s
放在bootsect.S
的后面, 故放在往后移动的512 K个字节处。 -
bootsect.S
将system
模块读入到内存的0x10000
处, 时间段3。
2.2 setup.s
的作用
- 执行自身过程中, 从bootsect.s 中获取机器的硬件信息, 参数等,在时间段4。
- 将
sytem
模块从内存的0x10000
处移动到ox0000
处, 时间段5, - 从实模式切换到 保护模式, 开始执行
system
模块。此时所有的32位运行方式的设置启动被完成:IDT,GDT和LDT被加载,处理器和协处理器也确认,分页工作也设置完成。
2.3 system
模块的作用
system
模块中 包含了head.S
文件, 以及main.c
文件,
注意到, 当运行到 system
模块时, 此时已经切换到保护模式进行运行 ,因此,此时head.s
是32 位的汇编;
- head.S : 初始化一些GDB 表, 初始化一些页表, 然后调到
main
开始执行; main.c
:初始化硬件资源分配, main 的工作就是 xx_init: 内存、中断、设备、时钟、 CPU 等内容的初始化 … 如图3 中的各种初始化;
3. 依次介绍三个文件
后面的三篇文章, 依次介绍
bootsect.s
,setup.s
,system模块
中的,head.S
,main.c
文件。
4. . 操作系统的主体内容
在理解了操作系统的启动过程之后, 下面说明以下操作系统的主要内容。
1、进程管理
2、存储管理
3、文件管理
4、设备管理
5、系统调用
主要包含下面 五大基本成分;
内容可以参考这里出自于这里
或者表述成:
- 分段、分页、
- 建立中断、设备驱动、
- 内存管理、
- 进程管理、
- 文件系统、
- 用户态接口等等。