操作系统启动流程
不同的操作系统在启动的过程中虽然会有不同的处理,但是核心的几个要点是都一样的。
本文图主要来自linux内核设计艺术
加电
①加电,CS=0xF000,IP=0XFFF0。实模式下寻址模式 cs左移4位+IP,所以cs:ip指向的是0xFFFF0。这个地址指令属于BIOS,会进行硬件检测、内存中中断向量表建立等
中断向量表有256个中断向量,每个向量4字节,cs和ip各占2个字节。指向相应的中断服务程序。
默认中断向量表在 0x0000 - 0x3FF,紧挨着的256字节构建BIOS数据区,并在其后的位置加载8KB左右中断服务程序。
加载完中断向量完成自检后,会执行0x19中断,将引导区加载0x7c00的位置。
引导程序
引导程序是存储在磁盘0面0道1扇区的位置512字节大小的代码,它的作用就是将后续几个扇区的代码加载到内存中。
读硬盘过程:
设置要读取的扇区数 将LBA地址存入0x1f3 ~ 0x1f6 向0x1f7端口写入读命令,0x20 检测硬盘状态准备好时开始读数据 从0x1f0端口读数据
按照约定引导程序必须以0x55,0xaa为结尾
引导程序要加载setup文件到0x9020,将自身复制到0x9000,将sysseg内核加载到0x10000处
以上为linux0.01的内存数据布局,当然如果自己实现系统也可以自己设置。
加载完成后 jmp到0x90200处执行setup代码。 boot代码在接下来的过程中会被覆盖掉
关中断
将内核代码移动到0x00000的位置,会覆盖掉中断向量表,所以需要关中断,废除16位的中断机制,后面会建立新的32位中断机制。
初始化GDT、IDT表
GDT用于保护模式下的寻址,IDT为保护模式下中断描述符表,这两个表的地址会放在专门的寄存器中保存。
打开A20
打开A20地址线,可以实现32位寻址。
in al,0x92 or al,0000_0010B out 0x92,al
只有20根地址线时,0xFFFFF + 1 = 0x00000 最高位溢出。打开A20就不会溢出了。
对8259A芯片重新编程
响应32位中断用的。
打开保护模式CR0
CR0寄存器第0位为PE保护模式使能,置为1是进入保护模式。
进入保护模式段选择器中保存的不再是段地址,而是段选择子,段选择子就是GDT表中每个元素下标号和特权级组成,后面会专门开一篇文章写保护模式的特权。
分页
分页实现已经写过相关文章了
进入main函数!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)