一、操作系统定义
- 管理计算机硬件的程序
- 计算机硬件和应用软件之间的一层软件
- 提供接口给上层应用软件,使应用软件使用计算机硬件
- 操作系统管理:CPU管理、内存管理、终端管理、磁盘管理、文件管理
- 计算机:冯·诺依曼存储程序思想
- 程序放入内存(存储器)中
- 指针 PC/IP 指向程序地址
- 取指、执行...取指、执行(计算机运行本质)
二、计算机开机过程(x86结构):
1.bootsect.s(汇编语言)
选择汇编语言的原因:
汇编语言每一条指令都能完整、绝对控制变成机器指令,即不会产生无法预知的错误
- CPU刚开机时处于实模式(实模式下寻址方式:CS左移4位+IP:CS<<4+IP)
- 开机时,CS = 0xFFFF,IP = 0x0000(硬件自动设置)
- 寻址:CS:IP = 0xFFFF:0x0000 = 0xFFFF0 (ROM BIOS映射区:固化在内存中,BIOS 程序存放在断电后内容不会丢失的只读内存中)
- 硬件检查:RAM、键盘、磁盘、显示器...
- BIOS映射区将启动盘分批分段读入内存
- 将磁盘0磁道、0扇区(引导扇区:bootsect扇区)读入 0x7c00 处
- PC = CS:IP = 0x07c0:0x0000 = 0x7c00,即执行bootsect
- bootsect.s首先将程序从0x7c00处移到0x90000处(PC=CS:IP=0x9000:0x0000=0x90000)
- 执行13号中断(int 0x13),将bootsect后4个扇区setup加载到内存中(setup的起始地址为0x90200)
- 读入setup扇区后,执行13号中断加载system模块(OS代码)到内存、10号中断加载logo
- system模块加载完毕后,跳转到setup扇区起始地址,执行setup.s程序(控制权交给setup.s)
bootsect.s的作用:
- 将bootsect.s程序移到0x90000处
- 加载setup扇区到内存
- 显示开机logo(人机交互)
- PC跳转到setup扇区所在内存(0x90200处),控制权交给setup.s
2.setup.s
- setup.s通过 int 0x15 获取硬件参数,如物理内存大小
- 获取内存大小放入ax中,ax赋值给 [2](间接寻址)
内存地址 | 长度 | 名称 |
---|---|---|
0x90000 | 2 | 光标位置 |
0x90002 | 2 | 内存大小 |
0x9000C | 2 | 显卡参数 |
0x901FC | 2 | 根设备号 |
- setup.s将 CS(DS):IP(SI) = 0x9000:0x0000 = 0x90000位置的代码,即OS(system模块)移动到0地址(OS代码一直停留在此处)
为什么要将bootsect.s从0x7C00移动到0x90000?
- 防止OS代码过长,setup.s移动OS代码到0地址处时,可能破快0x7C00处的bootsect.s代码,所以要移动到0x90000处
- setup.s在最后执行 jmpi 0,8,即进入OS(0地址处)
保护模式:CS变为执行GDT表(地址变为32位),不再左移4位,变为选择子(即GDT表的索引);GDT表中为8的索引存放地址+IP =内存(0x0000)
- setup初始化部分GDT表 (寻址方式以字节(8位)为单位,8个字节1个内存)
- setup初始化GDT表 ----> 进入保护模式 ---->执行jumpi 0,8(寻址变为32位)
setup工作总结:
- 读取硬件参数(内存、光标......)
- OS代码移动到0地址处(一直在此处,直到关机)
- 进入保护模式(PE = 1)
- 运用高级指令(32位寻址),跳转到0地址处执行system模块
O通过 makefile 控制代码执行顺序,即加你个OS代码变为镜像
3.system模块(OS代码):
- system模块第一个为head.s(head.s为32位汇编代码、bootsect.s和setup.s为16位编码),其次为main.c
- head.s ---->main.c(通过栈实现函数跳转)
- head.s用来初始化GDT表
- os的main.c主要进行各种硬件初始化
4.系统启动过程总结:
- BIOS找到bootsect.s读入、执行...
- bootsect.s:
- 加载setup.s到内存
- 显示logo
- 加载system模块
- 控制权交给setup.s
- setup.s:
- 获取硬件信息
- 将system模块移到0地址处
- 初始化部分GDT表,进入保护模式(变为32位寻址方式)
- 控制权交给system模块head.s
- system模块:
- head.s
- 初始化GDT表
- 初始化IDT表
- 跳转到main.c
- main.c(一直执行,永不返回):
- 初始化各种硬件参数
启动盘:读入内存,初始化关键数据化结构!!!