揭开钢琴的盖子:操作系统好比一个架美丽的钢琴,我们可以用上面的琴键弹出优美的旋律。但是我们不能满足于只会弹奏,如果我们要更深入理解钢琴,必须打开钢琴的盖子,一探究竟。所以学习操作系统,不能停留上系统API的调用,需要能更好更高效的调用API,知道API的局限性与缺点,就必须打开操作系统的盖子,探究操作系统API下的底层原理。

从我们按下电源键使得计算机通电,计算机的各个部件是怎么运行起来的呢。我们现在使用的计算都遵循冯诺依曼结构,在我们探讨计算机的启动前,先弄明白我们的计算机的结构。

1. 冯诺依曼结构计算机的工作原理

  • 计算机的核心工作部件是CPU,CPU内部从上电开始反复执行着两个动作:1)取址;2)执行
  • 计算机根据一系列的操作指令来执行不同的动作,这些指令就是计算机程序。
  • 计算机运行的程序是以二进制的方式存在内存中,程序中的数据与指令不加区别的都存储在内存上。

2. 计算机的启动过程:

图1:从系统加电起所执行的程序

  1. X86 PC岁开机时,CPU处于实模式,这时候内存的计算方式是 段基址 << 4 + 段内偏移
  2. CPU的第一条指令是通过CS:IP来取得,而此时CS=0xFFFF,IP=0x0000。这是硬件设定好的。
  3. 所以最开始执行的指令地址就是0xFFFF0,这个内存地址映射在主板的BIOS ROM(只读存储区)中。
  4. ROM中的程序会检测RAM、键盘、显示器、软硬磁盘是否正确工作。同时会从地址0开始设置BIOS的中断向量表。
  5. ROM中的程序继续执行,将启动设备磁盘0磁道0扇区,一个512字节的扇区读到内存0x07c00处。0x07c00应试是一个历史遗留的问题,后续把system模块拷贝到地址开始处时,预留的空间将不够,所以bootset需要把0x07c00这一块操作系统引导与设置模块拷贝走。这算是一个历史包袱。
  6. 设置cs=0x07c0,ip=0x0000。
  7. ROM中的程序执行结束,转到0x07c00处开始执行。

启动设备是可以通过BIOS程序来设置的,信息写在CMOS中。CMOS(64B-128B)中存的还有实时钟,硬件配置信息等。(开始时按住Del键可以进入启动设置的配置界面,可以设置光盘启动或U盘启动等)。

图2:内核在磁盘上的分布情况

3. Bootsect.s做了哪些事

  1. 把0x7c00开始的512个字节,拷贝到0x90000处。(0x90000 - 0x90020)
  2. 设置栈ss = 0x9000,sp = 0xff00,这里把sp设置的够大,防止栈的区域把下面的操作系统代码覆盖了。
  3. 调用BIOS ox13中断,将第2-5个扇区拷贝到0x90020开始的内存处。如果出错,就反复读取。
  4. 获取磁盘的参数:磁道数等
  5. 打印字符串信息:system is loading
  6. 读入system部分(几百个扇区),读入到内存为0x10000处。(在0x90000的下面)
  7. 转到地址为0x90020的地址处执行,也就是开始执行setup部分的代码了。

4. Steup模块做了什么事

主要工作是完成操作系统启动前的设置工作。

  1. 读取光标的位置信息放在09000的头2个字节处。因为这时候bootsect模块的代码已经没有用了,可以覆盖了。
  2. 读出扩展内存的大小,放在接着的2个字节处。
  3. 获取显卡参数,硬盘参数等等。
  4. 将system模块的内容从0x10000处开始移到0x00000处,即内存的起始位置。之所以Load进来的时候为什么不一次性放在0x00000处,是因为0x00000处开始放的bios中断。现在bios中断已经不需要了,所以可以覆盖了。
  5. 这时候开始,BIOS的中断向量表已经被覆盖了,后面就不再需要BIOS的中断了。
  6. 设置中断向量表与全局描述符表的一部分内容。
  7. 把cr0的最后一位设置为1,也就是说从实模型进入保护模式。
  8. jmpi 0, 8。 cs = 8,取到的段基址其实是0x0000,那么这句话就是跳转到地址为0x00000的地方开始执行,也就是system模块的开始部分。

保护模式下地址翻译与中断处理的改变:

cp:ip的翻译过程是:从cs的前12位取出GDT的偏移量(这里是1),从gtd的对应表项中取得基地址,再和ip合并为一个完整的地址。
int n: n指明了IDT表中的序号。从IDT表中获取中断处理函数的入口地址。

5. system-head

System的第一部分就是head.s部分的代码,这部分代码实际处于绝对地址0处开始的地方。该部分的代码是在保护模式下执行的,所使用的是AT&T格式的汇编指令与之前使用的as86汇编指令不同。这部分的代码主要完成了下面几件事情。

  1. 初步始中断描述符中的256项门描述符。
  2. 检查A20地址线是否打开。关于A20地址线的解释
  3. 测试系统是否含有数据协处理器,并设置寄存器CR0对应的位。
  4. 初始化内存页目录表,为内存分页管理作好准备工作。页目录表放在了绝对物理地址为0开始处,也就是head.s程序物理内存位置,程序会被覆盖掉。80286当时24根地址线,寻址16M,所以页表要能寻址16MB。如果内存页大小为4k,那页表就有4K个表项,一个表项按4个字节算,那页表就需要16K个字节(4页)。这里只用到了1级页表,在后续的发展中出现了二级页表,3级页表。
  5. 最后跳转到system模块中的初始化程序init/main.c中继续执行。

head.s程序执行结束后,已经正式完成了内存页目录页表的设置,并重新设置了内核实际使用的中断描述符表idt和全局描述符表gtd。另外还为软盘驱动开辟了1kb的缓冲区。此时system模块在内存中的详细映像如下图所示:

图3:System内存中的映像示意图

6. 总体执行线路

整体上可以分类6个阶段,头2个阶段为boostset,中间3个阶段为setup,最后一个阶段为system的head模块。

图4:启动引导的整个过程中,内核在内存中的位置以及移动后的位置情况

7. 参考资料

[1] 《Linux内核完全剖析基于0.12内核》 赵炯著。
[2] 网易云课堂,哈尔滨工业大学《操作系统之应用》 李治军。

计算机加电后操作系统启动过程相关推荐

  1. 计算机加电启动操作引导自举,在计算机加电启动过程中,加电自检程序、 操作系统、引导程序、自举装入程序,这四个的执行顺序为...

    在计算机加电启动过程中四个程序的执行顺序应该为: 1.加电自检程序: 2.自举装入程序: 3.引导程序: 4.操作系统. 复位启动: "复位"是用硬件控制的方式对CPU进行复位操作 ...

  2. linux系统启动过程详解-开机加电后发生了什么 --linux内核剖析(零)

    本文参考了如下文章 深入理解linux启动过程 mbr (主引导记录(Master Boot Record)) 电脑从开机加电到操作系统main函数之前执行的过程 详解linux系统的启动过程及系统初 ...

  3. 操作系统启动过程——硬件自检+系统引导+系统加载+系统登录

    以下的内容都是在网上搜集并整理的,希望有问题的朋友在提问之前能先在这里看一看,不要浪费了众多为网络奉献的众多网友的心血! 电脑及操作系统的启动过程是一个很复杂的过程,对于我们大多数只是希望把电脑玩的更 ...

  4. 计算机启动操作系统的过程,操作系统启动过程

    操作系统启动过程简单分为四部分,从BIOS自检.系统引导.启动内核.初始化系统.其中每个部分又分为多个子部分,操作系统的建立是一个相对比较复杂的事情.以下以Linux2.6.32版本为基础,介绍操作系 ...

  5. 浅谈-LINUX 操作系统启动过程

    LINUX 操作系统启动过程 通过一段时间的学习已经对linux有了一定的了解,接下来就开始研究一下linux 操作系统的启动过程吧.当然这是为了让大家比较容易发现linux启动过程中容易发生问题的地 ...

  6. 学习笔记:操作系统启动过程

    学习笔记:操作系统启动过程 参考资料: 1.<操作系统真象还原>郑钢 2.<操作系统引导探究> 谢煜波 操作系统启动过程 按下电源后: 电源键连接的电信号线发送一个电信号给主板 ...

  7. CPU加电后第一条指令

    当我们按下电源开关时,电源就开始向主板和其它设备供电,此时电压还不太稳定,主板上的控制芯片组会向CPU发出并保持一个RESET(重置)信号,让 CPU内部自动恢复到初始状态,但CPU在此刻不会马上执行 ...

  8. 计算机启动过程从电路,pc 启动过程 -- 加载MBR之前的过程,即加电到bios启动过程...

    文章1 微机启动深究 引言 对于经常使用电脑的用户(来CFAN的都应该包括在这一行列吧)来说,每天当你按下Power Button等待电脑进入系统开始一天正常工作的时候,你有没有想过在这一段时间内电脑 ...

  9. 计算机加电自动开机后又关机,电脑一通电自动开机,随后自动关机

    一般来说PWRON After PWR-Fail设置为OFF后就可以解决问题了. 注意:设置完毕后,按F10保存,输入Y 回车即可. 自动关机故障排除方法: 1.有可能是BIOS的设置问题,进入BIO ...

最新文章

  1. imagick API 中文说明
  2. 鄂维南院士:科学与智能——机器学习的新前沿、应用数学时代的曙光
  3. linux增加自定义path和manpath
  4. 多少线程太多? [关闭]
  5. 实现自己的连接池(一)
  6. python笔记之变量(variable)
  7. 数据结构与算法--实现Singleton模式
  8. Python 加密解密
  9. MFC 常见窗口操作
  10. 《电路分析导论(原书第12版)》一2.8 导体和绝缘体
  11. 如何在矩池云上安装java
  12. 国土空间规划数据汇交标准_国土空间规划数据治理指南来了
  13. Hive 使用SQL统计出每个用户的累积访问次数
  14. 中国互联网的那些事——二十年回顾
  15. word自动生成目录和调整页码字体的方法
  16. 创业公司一年工作总结
  17. 在出境通关中如何应用智能智慧护照阅读器技术呢
  18. [Excel]vlookup的内在逻辑以及模糊检索
  19. 双评价技术指南2020_2020年双11 千元以下人体工学椅选购指南,不交智商税
  20. MySQL联合索引原理解析

热门文章

  1. 安波副教授:分布式人工智能进展与趋势
  2. 六条规则让你的ML模型部署的更快
  3. CCAI 2020 | 黄铁军:“仿真主义”下的人工智能发展之路
  4. GPU端吊打RegNet、EfficientNet的强悍担当:GENet
  5. 「SAP技术」SAP WM 如何根据TR号码查询TO号码?
  6. 如何看待清华北大毕业生流失去国外?
  7. 神经正切核,深度学习理论研究的最新热点?
  8. 人工智能不是单纯的经验和总结
  9. Kubernetes的未来是虚拟机?
  10. Python 之 Pandas (六)合并