X86架构操作系统的启动
刚看完b站操作系统(哈工大李治军老师)老师的课前三章,趁热打铁做个简单的笔记,不会讨论太多具体内部的代码主要是理解。学习这三章需要汇编的一点基础,我看的是b站小甲鱼的汇编到内存访问章节就够理解了。
1、操作系统的一些知识
- 操作系统开机时进入实模式
- 硬件上操作主要是:寻址ROM BIOS的映射区,检查RAM,键盘,显示器,软硬磁盘
- 启动设备信息被设置在CMOS中 存储着实时钟和硬件配置信息
2、bootsect.s
bootsect读取磁盘第一个扇区,也被称为操作系统的引导扇区,执行汇编程序bootsect.s 主要功能是将操作系统载入内存中,它在结尾会跳到第二个扇区读取setup.s
3、setup.s
执行setup.s为硬件启动作准备:
- 将硬件参数载入,显示开机界面
- 完成OS启动前的这些设置后,进入保护模式(从16位机进入到保护模式32位)
- 保护模式下主要是地址翻译(gdt表全局描述符表)硬件来做和中断处理函数入口(idt也是个表)
- 在steup结尾使用jumpi 0,8 这个32位的指令(查表寻址),转跳到了内存0x0000处,也就是之前bootsect执行后存放操作系统的起始地址(system模块)
4、操作系统编译相关知识
- system是由许多文件编译而成,makefile就是用来编译的脚本语言
- 我们通常把这些由多个文件(bootset.s、setup.s、system模块)操作系统编译而成的文件称为image(镜像),image开机后就会初始化产生shell(平时我们用的操作系统界面(桌面))
- makefile将相互依赖的各种文件链接起来最终形成了镜像文件,当然包括system它的第一个文件——重要的head.s
可以看出来内存中操作系统是这样的,蓝色部分是system
5、head.s
-
从这里开始除了使用16位的x86汇编,还使用32位的(GNU),还有内嵌汇编(GCC(主要是处理C文件))
-
刚进入head,就是初始化,需要跳转到C函数,这里需要提到函数调用函数的原理(C中函数调用函数,使用的就是栈,涉及汇编知识,b栈小甲鱼的汇编内存访问章节有讲到函数调用函数的具体栈操作)
-
在汇编的一系列压栈操作后进入了main函数(并且main函数不会再返回了,返回的话会导致死机)也就是说以后不出意外一直是c了……吧?不得不说到这里看到c觉得从未有过的亲切感
-
在main函数中是许多的初始化函数,和嵌入式驱动程序的初始化函数差不多
-
mem_init()是其中的一个较为重要的初始化函数(内存初始化函数)
其中mam_map数组的一些解析:>>=12每次右移4k(一页),每一页置为0(置为0的是内存中没有使用的,前面放的是操作系统)
这个数组有多长就看之前读的硬件参数是多长了。
我觉得它这里应该是硬盘的内存,不确定,有知道的大佬能告诉一下最好 -
最后,老师还说了这句话,我觉得听精辟的,返璞归真:
操作系统的启动实际上只做了两件事情
1、将操作系统读入内存
2、初始化