华纳云:当我们按下开机键后,发生了什么?
字数 1215 2025-08-15 21:34:08

计算机启动过程详解

前置知识

理解计算机启动过程需要掌握以下基本概念:

  1. 内存功能:内存是存储数据的地方,给出地址信号可返回对应数据
  2. CPU工作原理:CPU不断从内存中取出指令并执行
  3. 程序计数器(PC):决定CPU从内存哪个地址取指令,会不断+1或由跳转指令修改

启动过程核心机制

1. BIOS主导启动的原因

计算机启动时,CPU的PC寄存器被强制初始化为0xFFFF0,这是BIOS程序的入口地址。具体实现方式:

  • 段基址寄存器cs初始化为0xF000
  • 偏移地址寄存器IP初始化为0xFFF0
  • 实模式下最终地址计算:cs左移4位 + IP = 0xFFFF0

2. 内存映射机制

CPU地址总线宽度决定可访问内存空间大小,但并非全部分配给内存:

  • 部分地址空间分配给外设(显存、硬盘控制器等)
  • 外设存储区域被"映射"到内存特定区域
  • 实模式下(开机时)只有1MB内存可用

3. 实模式内存分布

BIOS空间被映射到内存0xC0000-0xFFFFF,其中:

  • 系统BIOS位于0xF0000-0xFFFFF
  • BIOS程序占用内存开头区域(如中断向量表)

BIOS执行流程

  1. 初始跳转

    • 0xFFFF0处指令:jmp far f000:e05b
    • 跳转到0xFE05B执行BIOS核心代码
  2. BIOS主要工作

    • 硬件检测和初始化
    • 建立中断向量表并填写中断例程
    • 最后加载启动区

启动区加载机制

1. 启动区识别

BIOS按启动顺序检查设备:

  • 读取每个设备的0盘0道1扇区(512字节)
  • 检查最后两个字节是否为0x550xAA
  • 找到符合条件的第一个设备作为启动设备

2. 启动区加载

  • 将512字节启动区内容复制到内存0x7C00
  • 执行跳转指令使PC指向0x7C00
  • 控制权转交给启动区代码

3. 0x7C00的由来

历史原因:

  • 第一个BIOS(IBM PC 5150)假设操作系统最小需要32KB内存
  • 为安全预留空间:32KB末尾(0x8000)减去1KB(0x400) = 0x7C00
  • 后续保持兼容性无法更改

启动区代码功能

启动区主要任务:

  1. 加载真正的操作系统内核到内存
  2. 跳转到内核入口地址

典型启动区代码结构示例:

; hello-os
ORG 0x7c00  ; 声明加载地址

entry:
    ; 初始化寄存器
    MOV AX,0
    MOV SS,AX
    MOV SP,0x7c00
    MOV DS,AX
    MOV ES,AX
    
    ; 显示消息
    MOV SI,msg
putloop:
    MOV AL,[SI]
    ADD SI,1
    CMP AL,0
    JE fin
    MOV AH,0x0e
    MOV BX,15
    INT 0x10
    JMP putloop
    
fin:
    HLT
    JMP fin
    
msg:
    DB 0x0a,0x0a      ; 换行
    DB "hello-os"
    DB 0x0a           ; 换行
    DB 0              ; 结束符
    
    RESB 0x7dfe-$     ; 填充到510字节
    DB 0x55, 0xaa     ; 启动标识

操作系统内核加载

启动区完成后:

  1. 从磁盘特定位置加载操作系统内核到内存
  2. 跳转到内核入口地址
  3. 内核开始执行:初始化内存管理、进程管理、文件系统等

完整启动流程总结

  1. 按下电源,CPU PC初始化为0xFFFF0(一跳)
  2. 跳转到BIOS核心代码0xFE05B(二跳)
  3. BIOS加载启动区到0x7C00并跳转(三跳)
  4. 启动区加载操作系统内核并跳转(四跳)
  5. 操作系统内核开始执行,完成系统初始化

深入学习的建议

要完全理解计算机启动过程,建议:

  1. 研究实模式和保护模式的内存管理
  2. 学习x86汇编语言
  3. 阅读Linux内核源码中启动相关部分
  4. 实践编写简单的启动区代码
计算机启动过程详解 前置知识 理解计算机启动过程需要掌握以下基本概念: 内存功能 :内存是存储数据的地方,给出地址信号可返回对应数据 CPU工作原理 :CPU不断从内存中取出指令并执行 程序计数器(PC) :决定CPU从内存哪个地址取指令,会不断+1或由跳转指令修改 启动过程核心机制 1. BIOS主导启动的原因 计算机启动时,CPU的PC寄存器被强制初始化为 0xFFFF0 ,这是BIOS程序的入口地址。具体实现方式: 段基址寄存器cs初始化为 0xF000 偏移地址寄存器IP初始化为 0xFFF0 实模式下最终地址计算: cs左移4位 + IP = 0xFFFF0 2. 内存映射机制 CPU地址总线宽度决定可访问内存空间大小,但并非全部分配给内存: 部分地址空间分配给外设(显存、硬盘控制器等) 外设存储区域被"映射"到内存特定区域 实模式下(开机时)只有1MB内存可用 3. 实模式内存分布 BIOS空间被映射到内存 0xC0000-0xFFFFF ,其中: 系统BIOS位于 0xF0000-0xFFFFF BIOS程序占用内存开头区域(如中断向量表) BIOS执行流程 初始跳转 : 0xFFFF0 处指令: jmp far f000:e05b 跳转到 0xFE05B 执行BIOS核心代码 BIOS主要工作 : 硬件检测和初始化 建立中断向量表并填写中断例程 最后加载启动区 启动区加载机制 1. 启动区识别 BIOS按启动顺序检查设备: 读取每个设备的 0盘0道1扇区 (512字节) 检查最后两个字节是否为 0x55 和 0xAA 找到符合条件的第一个设备作为启动设备 2. 启动区加载 将512字节启动区内容复制到内存 0x7C00 执行跳转指令使PC指向 0x7C00 控制权转交给启动区代码 3. 0x7C00的由来 历史原因: 第一个BIOS(IBM PC 5150)假设操作系统最小需要32KB内存 为安全预留空间:32KB末尾( 0x8000 )减去1KB( 0x400 ) = 0x7C00 后续保持兼容性无法更改 启动区代码功能 启动区主要任务: 加载真正的操作系统内核到内存 跳转到内核入口地址 典型启动区代码结构示例: 操作系统内核加载 启动区完成后: 从磁盘特定位置加载操作系统内核到内存 跳转到内核入口地址 内核开始执行:初始化内存管理、进程管理、文件系统等 完整启动流程总结 按下电源,CPU PC初始化为 0xFFFF0 (一跳) 跳转到BIOS核心代码 0xFE05B (二跳) BIOS加载启动区到 0x7C00 并跳转(三跳) 启动区加载操作系统内核并跳转(四跳) 操作系统内核开始执行,完成系统初始化 深入学习的建议 要完全理解计算机启动过程,建议: 研究实模式和保护模式的内存管理 学习x86汇编语言 阅读Linux内核源码中启动相关部分 实践编写简单的启动区代码