- 计算机启动时操作系统做的详细工作
操作系统启动之后,pc指针首先指向BIOS区,检测RAM,键盘,显示器,软硬磁盘是否正常运作,之后会把磁盘0磁道0扇区的256字节的引导启动代码放到内存0x7c00处,PC ( PCurr指针 )指该内存地址处开始运行。
该引导代码用汇编而不是用C语言,因为C语言的代码编译之后,它的内存位置是人为不可控的(比如自动分配栈),而汇编可以。
引导启动代码的第一步是:
(1)把256字节的代码从0x7c00处移动到0x9000处。然后从0x9000处开始运行。
(2)运行一开始读磁盘0磁道0扇区后面的4个setup扇区,把这4个扇区读到0x90200地址处。
(3)接下来的代码不读磁盘了,而是用13号中断在屏幕上显示加载系统的图片和文字。
(4)最后再把磁盘前5个扇区之后的内容读到内存
(5)程序跳到setup程序的地址去执行
(6)setup程序首先通过15号中断获得内存的大小等硬件参数。然后把从0x9000处所有的操作系统代码移到0地址处。(在物理内存中,操作系统就存放在低地址中)
(7)set up的最后代码是一条高级指令,它会把cr寄存器的最后一位置1,这样寻址方式从以前的模式转变为保护模式,此时会改变计算机的寻址模式,寻址不再是cs左移4位加上ip地址,而是cs寄存器指向gdt表,找到基地址,然后加上ip寄存器的偏移地址来寻址,这样可以查找更大的空间,以前是寻址空间2的16次方,现在是2的32次方。
(8)接下来跳到system模块去执行,也就是前5个扇区之后的代码处去执行。
注意,磁盘上的程序一次是boot–setup–system程序,最终转变到内存中也要是这样的顺序,boot将setup的程序拿到内存,setup将system的程序拿到内存。system程序的开始一定是是head.s文件
(9)head.s文件会初始化idt和gdt表,这两个表格是寻址用的,以方便保护模式下使用,该模式下很多汇编指令改变,比如mov des sor 变成mov sor des,32位汇编代码和16位汇编代码不同。整个启动过程用了16位汇编,32位汇编,内嵌汇编三种。
(10)最后跳到main()函数去执行,在main函数里面进行各个模块的初始化工作。前面第6步获得的物理内存大小参数就可以传到一些初始化函数中进行使用 其中mem_init() 方法具体内容是在给内存分页,建立memo_map数据结构.