0%

HIT-OS 操作系统的启动

打开电源,计算机执行的第一条指令是什么

对于 X86 PC来说,执行以下几步:

  1. X86 PC刚开机时 CPU处于实模式
  2. 开机时,CS = 0xFFFF; IP = 0x0000
  3. 寻址0xFFFF0 (ROM BIOS映射区)
  4. 检查ROM, 键盘,显示器,软硬磁盘
  5. 将磁道0磁道0扇区读入0x7cc处
  6. 设置 cs = 0x07c0, ip = 0x0000

0x7c00处存放的代码

  • 就是从磁盘引导扇区(0磁道0扇区)读入的512个字节
    • 引导扇区就是启动设备的第一个扇区
    • 启动设备信息被设置在CMOS(用来存储时钟和硬件配置信息)中
    • 磁盘第一个扇区上存放着开机后执行的第一段我们可以控制的程序

主引导扇区代码(bootstrap)

首先将 0x7c0:0x000处的512个字节的内容移动到0x9000:0x0000处,然后跳转到go标号处继续执行;

jmpi go, INITSEG

读入setup模块后: ok_load_setup

read_it //读入system模块

这里boot扇区代码的执行完毕了,开始setup的四个扇区代码的执行


setup模块的执行

setup模块,即setup.s

  • 用来读取内存等信息,便于后续操作系统建立数据结构进行管理

  • system模块移动到零地址处

初始化GDT表

  • 建立一个GDT表,进行初始化,便于保护模式的地址转换

保护模式下地址翻译和中断处理

  • 此时的CS叫做选择子

将CPU切换到保护模式

1
2
mov ax, #0x0001 
mov cr0, ax

这两行代码切换到保护模式

CX=8进行查表

总结setup做了什么

  1. 读取硬件参数,为了建立操作系统打下基础
  2. 将system模块挪动到0地址处,将来操作系统核心代码一直存在那里
  3. 启动了保护模式
  4. 运用32位汇编指令jmpl 0, 8 跳转到0x0000处地址执行

system模块执行

  • system模块(目标代码)中的第一部分代码? head.s
  • system模块由很多文件编译而成,为什么是 head.s ?

makefile文件如下

编译出来后顺序:bootstrap -> setup -> head.s -> main.c -> ….

head.s

一段在保护模式下运行的代码

  • 又一次初始化了gdt表和idt表(之前是临时建立的gdt表为了执行jmpi 0, 8
  • 开启20号地址线,可以访问4G内存了
  • 设置系统栈
  • ……

三种汇编

after_page_tables(设置了页表之后)

看了这段太巧妙了叭,模拟函数调用原理,正常函数调用时候,会先将参数从后往前依次入栈,然后将下一条指令的地址入栈,当ret返回时,直接进入之前下一条指令的地址。当set_paging结束时直接跳转到 main函数执行,如果main函数意外返回,将进入L6处执行死循环。

进入main函数

mem_init()

求大佬赏个饭