操作系统系列(4):按下电脑开机键后,究竟发生了什么?

版权声明:本文为博主原创文章,未经博主允许不得转载,博客地址: https://blog.csdn.net/qq_31601743/article/details/91513886

引言

安装完操作系统后,整个操作系统在硬盘中的分布分为boot模块的1个扇区、setup模块的4个扇区,system模块(操作系统代码)的n个扇区。一个扇区为512字节,并且操作系统是从硬盘中0磁道0扇区开始往后分布的。

操作系统系列(4):按下电脑开机键后,究竟发生了什么?

1.按下电脑开机键

如图所示,计算机内部有一个叫ROM BIOS的东西,它是一个固件(就是即使计算机断电之后,里面存放的东西还是在的),里面存放着最低级、最直接的硬件控制的代码,ROM BIOS 包含了控制键盘、显示屏幕,磁盘驱动器,串行通讯设备和很多其它功能的代码。

1.按下电脑开机键后,CPU上电后,ROM BIOS里面的代码映射到内存中的0xFFFF0处,此时,内存中有了ROM BIOS固件中的代码,我们称内存中存放ROM BIOS代码的区域叫ROM BIOS代码映射区。

操作系统系列(4):按下电脑开机键后,究竟发生了什么?

2.然后,PC指针指向0xFFFF0处的ROM BIOS代码映射区,开始顺序往下执行该区域代码,该区域代码包括检查内存、键盘、显示器、软硬磁盘等设备是否能正常工作,若不能,此时计算机会发出警报,然后开不了机。若能,则继续往下执行该区域的代码。

操作系统系列(4):按下电脑开机键后,究竟发生了什么?

3.将硬盘中0磁道0扇区的内容读入到0x7c00处。即boot模块的代码读入到内存中的0x7c00处,然后把PC指针指向0x7c00,该段代码逻辑是ROM BIOS厂家固定好的,已经写在ROM BIOS固件中了。

操作系统系列(4):按下电脑开机键后,究竟发生了什么?

操作系统系列(4):按下电脑开机键后,究竟发生了什么?

总结:

打开电源,执行ROM BIOS中的代码,该代码功能

1)检查RAM、键盘、显示器、软硬磁盘等硬件设备。

2)将磁盘的0磁道0扇区(boot模块)读入0x7c00处。

3)设置PC指针为0x7c00,即将执行boot模块代码。

然后,操作系统的故事开始了,首先执行的是boot模块代码

2.执行boot模块代码

该模块起到引导的作用。

1.执行Code1转移指令:将0x7c00开始的512个字节(即boot模块代码)复制到0x90000~0x90200。(就是相当于把自己复制粘贴到别的内存区域,为什么要这样做?请思考,接下来会讲)。

操作系统系列(4):按下电脑开机键后,究竟发生了什么?

2.将PC指针指向上面转移指令的下一条指令,继续执行后面的代码。执行Code2:在电脑屏幕上显示“操作系统正在启动”的标志。

操作系统系列(4):按下电脑开机键后,究竟发生了什么?

3.执行Code3读入setup模块:

将setup模块的4个扇区(4*512个字节)从硬盘上读进内存0x90200~0x90A00处

操作系统系列(4):按下电脑开机键后,究竟发生了什么?

操作系统系列(4):按下电脑开机键后,究竟发生了什么?

4.执行Code4读入system模块(操作系统模块):

将system模块的n个扇区从硬盘上读进内存,内存开始位置为0x0000。

操作系统系列(4):按下电脑开机键后,究竟发生了什么?

该图就解释了为什么boot模块代码的Code1要把自己整个Boot模块代码从0x7c00复制粘贴到0x90000~0x90200内存区域

因为boot模块的Code4是读入操作系统模块代码,操作系统模块代码有可能很长,如上图所示,若boot模块代码还处于0x7c00处,那么操作系统模块的代码会把boot模块代码覆盖掉,然后boot代码执行完Code4之后就无法继续执行了,会造成错误,因此得把boot模块自己移到离0x0000比较远的地方。

执行boot代码的功能

1)把boot模块拷贝自己到离0x0000内存地址较远的位置。

2)在屏幕显示“加载操作系统”标志。

3)读入setup模块。

4)读入system模块。

执行完boot模块后,然后执行setup模块代码。。。

3.执行setup模块代码

执行完boot模块代码后,紧接着PC指针指向0x90200地址,执行Setup模块代码。

操作系统系列(4):按下电脑开机键后,究竟发生了什么?

Setup模块完成操作系统启动前的设置。

设置一些system模块(操作系统模块)所需要的参数,供system模块中的函数使用。放到内存地址为0x90000处开始,覆盖boot模块。

操作系统系列(4):按下电脑开机键后,究竟发生了什么?

然后,PC指针跳转到0x0000,开始执行system模块。

4.执行system模块代码

开始进入main函数执行操作系统代码。

//Linux操作系统,在init/main.c中
void main(void)
{
   mem_init();
   trap_init();
   blk_dev_init();
   chr_dev_init();
   tty_init();
   time_init();
   sched_init();
   buffer_init();
   hd_init();
   floppy_init();
   sti();
   move_to_user_mode();
   if(!fork()){ini(); }
}
 

可以看出,main的工作就是对内存、中断、设备、时钟、CPU等内容的初始化....

初始化完成之后,我们就正式进入操作系统了,也就可以在操作系统之上为所欲为了....

原创不易,多多支持,欢迎交流!

IT界的泥石流与你一同成长

欢迎关注我们微信公众号:IT界的泥石流

猜你喜欢

转载自blog.csdn.net/qq_31601743/article/details/91513886