-
计算机的工作
- 冯诺依曼存储程序思想:将一套程序(函数)存储在内存中,然后取指执行
-
操作系统的启动
- x86PC刚开机时,硬件自动配置一些内容
- CPU处于实模式(实模式下CS«4+IP)
- CS(代码段寄存器)=0xFFFF,IP(指令指针寄存器)=0x0000
- 寻址0xFFFF0(ROM-BIOS映射区,Read Only Memory-Basic Input Output System,一片固化的区域)
- 找到了ROM-BIOS,开始取指执行内存中的第一段程序
- 检查RAM、外设、主板、软硬磁盘等,如果重要硬件出问题那操作系统也跑不起来
- 将磁盘0磁道0扇区(操作系统的引导扇区)(一个扇区512KB)读入0x7C00处
- 设置CS=0x07C0,IP=0x0000(物理地址0x7C00)
- 执行引导扇区内的程序bootsect.s模块(.s后缀文件是汇编语言)
- 段间跳转(start标签)
- 将CS:IP从0x07C0:0x0000处移动到0x9000:0x0000处(物理地址0x90000)
- 段间跳转后的初始化(go标签)
- 统一设置所有段寄存器(DS、ES、SS)与CS相同(0x9000)
- 设置堆栈指针SP为0xFF00(在0x9000段内)
- 加载setup(load setup标签)
- 使用BIOS INT 0x13中断读取setup模块(从第2个扇区开始读取4个扇区),如果出现错误,则先复位磁盘,然后重新读取,成功后跳转到ok_load_setup模块
- 获取磁盘参数并显示信息(ok_load_setup标签)
- 获取磁盘参数信息
- 在显示器上显示引导信息(Loading System…)
- 加载Linux内核(system模块)
- 引导扇区工作完成,跳转到setup程序(物理地址0x90200)
- 段间跳转(start标签)
- 进入setup.s模块
- 初始化设置(start标签):
- 设置DS段寄存器指向0x9000(与bootsect相同的内存区域)
- 获取当前光标位置保存到0x90000处
- 使用INT 15h AH=88h获取扩展内存大小(1MB以上内存)
- 获取硬件信息,结果存入0x90002处
- 使用cli关闭中断
- 内存重定位(do_move标签内循环)
- 将0x10000~0x8FFFF的内核映像(system模块)移动到0x00000开始的位置,使用rep movsw指令,每次移动64KB(0x1000段),循环直到所有内核数据移动完成
- 切换到保护模式
- 开启A20地址线
- 通过8042键盘控制器开启A20地址线
- 早期PC中默认关闭A20以实现兼容性,保护模式需要开启它
- 检查状态寄存器的第1位(输入缓冲区满标志),等待8042控制器就绪(empty_8042)
- 初始化8259中断控制器
- 切换到保护模式
- 调整CR0寄存器,PE位(bit 0)置1,令CPU进入保护模式
- 初始化GDT、LDT表
- 开启A20地址线
- 初始化设置(start标签):
- 进入head.s模块
- 设置段寄存器、设置堆栈
- 初始化IDT(中断描述符表)
- 检查A20是否开启
- 跳转到页表初始化(after_page_tables部分)
- after_page_tables:在页表设置完成后从汇编语言过渡到C语言,然后开始main函数
- 进入main函数
- 执行各种内存、中断、时钟等的初始化(mem_init()、trap_init()、blk_dev_init()等)
- 然后进入有关fork()的循环,直到关机都一直循环
- x86PC刚开机时,硬件自动配置一些内容
操作系统 - Operating System
/
Chapter I 操作系统概论
/
Section 1 操作系统概论