📂 操作系统 - Operating System / Chapter I 操作系统概论 / Section 1 操作系统概论

操作系统的启动

2025-09-05
  • 计算机的工作

    • 冯诺依曼存储程序思想:将一套程序(函数)存储在内存中,然后取指执行
  • 操作系统的启动

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