最近在读LMOS的《操作系统实战 45 讲》,觉得不错,并且想额外多加点注释 ^_^。毕竟OS的知识体系相当庞大,很多地方缺少先修知识会觉得一头雾水。
PC的启动流程
开机最先执行的代码是在计算机的固件中存储的,通常位于BIOS(基本输入/输出系统)或UEFI(统一可扩展固件接口)中。当计算机上电时,CPU从一个预定义的内存地址开始执行。这个地址通常指向固件(BIOS/UEFI)中的一个位置,这里包含了执行硬件初始化和启动引导程序所需的指令。
BIOS或UEFI的第一个任务是执行加电自检(Power-On Self-Test,POST),以检查计算机硬件的基本功能和完整性。然后,BIOS或UEFI将继续识别和初始化硬件设备,如CPU、内存、显卡、磁盘驱动器等。
完成硬件初始化后,BIOS/UEFI会从可启动设备(如硬盘、U盘、光盘等)中搜索引导加载程序。找到引导加载程序后,执行权将交给引导加载程序(如GRUB、GRUB2或Windows Boot Manager),开始加载操作系统。
graph TDA[POST] --> B[BIOS Initialization]B --> C[Search and Load Bootloader]C --> D[Bootloader: GRUB, GRUB2, Windows Boot Manager]D --> E[Load OS Kernel]E --> F[Initialize OS]F --> G[Launch User Space Processes]
加电自检(Power-On Self-Test, POST)
当计算机上电后,BIOS(基本输入/输出系统)会执行POST,以检查计算机硬件的基本功能和完整性。
BIOS初始化
BIOS会初始化和识别计算机上的硬件设备,如CPU、内存、显卡、磁盘驱动器等。
寻找并加载引导加载程序
BIOS会按照预定的顺序,从可启动设备(如硬盘、U盘、光盘等)中寻找引导加载程序。这些设备的主引导记录(MBR)或者UEFI分区通常包含引导加载程序。
引导加载程序(如GRUB、GRUB2或Windows Boot Manager)
引导加载程序负责加载操作系统内核。它可能会显示一个菜单,让用户选择要加载哪个操作系统(如果有多个操作系统可供选择)。
加载操作系统内核
引导加载程序将内核映像加载到内存中,并将执行权交给内核。这个过程可能涉及解压缩内核映像、设置内存分页等。
初始化操作系统
操作系统内核开始运行,初始化各种内核数据结构、设备驱动程序和系统服务。最后,它会启动用户空间进程,如init(Linux)或smss.exe(Windows)。
启动用户空间进程
操作系统将继续启动其他用户空间进程,如登录管理器、桌面环境等,为用户提供可交互的图形界面或命令行界面。
加载引导程序
x86 CPU的大多数寄存器在开机后都有明确的值。指令指针(EIP)寄存器持有处理器正在执行的指令的内存地址。EIP被硬编码为0xFFFFFFF0的值。因此,x86 CPU被硬编码为在物理地址0xFFFFFFF0开始执行。事实上,它是32位地址空间的最后16个字节。这个内存地址被称为reset vector 复位向量。
指令指针是什么?0xFFFFFFF0又是什么?为什么不是别的地址?指令指针(EIP)寄存器保存着处理器正在执行的指令的内存地址。0xFFFFFFF0是x86 CPU被硬连线以在物理地址处开始执行的地址。这个地址被称为复位向量,它是32位地址空间的最后16个字节。至于为什么选择这个特定的地址,这是由x86架构决定的。
芯片组的内存映射确保 0xFFFFFFF0 被映射到 BIOS 的某个部分,而不是 RAM。这是为了在计算机启动时能够执行BIOS代码
同时,BIOS将自己从ROM复制到RAM中,以加快访问速度。这就是所谓的shadowing。地址 0xFFFFFFF0 将只包含一条跳转指令,跳转到 BIOS 复制自身的内存中的地址。
这样,BIOS 代码开始执行。BIOS 首先在配置的启动设备顺序中搜索一个可启动的设备。它检查某个神奇的数字以确定该设备是否可启动。(第一个扇区的511和512字节是否为0xAA55)
一旦 BIOS 找到一个可启动的设备,它就把设备的第一个扇区的内容从物理地址0x7c00 开始复制到 RAM 中;然后跳到这个地址,执行刚刚加载的代码。这段代码被称为引导程序。
然后引导程序在物理地址0x100000处加载内核。0x100000地址被用作x86机器上所有大内核的起始地址。
所有的x86处理器都是以一种简单的16位模式开始的,称为实模式。GRUB引导程序通过将CR0寄存器的最低位设置为1来切换到32位保护模式,因此内核以32位保护模式加载。
请注意,在Linux内核的情况下,GRUB检测到Linux启动协议,并以真实模式加载Linux内核。Linux内核自己会切换到保护模式。




