Linux内核启动过程分析:从实模式到保护模式的关键步骤
linux-insides-zh Linux 内核揭秘 项目地址: https://gitcode.com/gh_mirrors/li/linux-insides-zh
引言
在上一篇文章中,我们分析了Linux内核启动的初始阶段,了解了实模式下的基本设置过程。本文将深入探讨内核启动过程中从实模式切换到保护模式的关键步骤,这是操作系统能够充分利用现代CPU功能的重要转折点。
保护模式概述
保护模式是现代操作系统运行的基础模式,它提供了比实模式更强大的内存管理和硬件保护机制。理解保护模式对于深入掌握操作系统原理至关重要。
保护模式与实模式的主要区别
- 内存访问能力:实模式只能访问1MB内存空间,而保护模式可以访问4GB(32位)甚至更大的地址空间
- 内存保护机制:保护模式提供了内存段保护机制,防止应用程序随意访问内核空间
- 特权级别:保护模式引入了特权级概念(Ring 0-3),内核运行在最高特权级
全局描述符表(GDT)
保护模式的核心数据结构之一是全局描述符表(GDT),它定义了系统中所有内存段的属性。
段描述符结构详解
每个段描述符64位,包含以下关键信息:
63 48 47 46 44 43 40 39 32
------------------------------------------------
| Base 31:24 |G |D/B|L | 段限长19:16 |P |DPL|S| TYPE | Base 23:16 |
------------------------------------------------
31 16 15 0
------------------------------------------------
| Base 15:0 | 段限长15:0 |
------------------------------------------------
关键字段说明:
- Base:32位段基址
- Limit:20位段限长,决定段大小
- G:粒度标志,0表示字节粒度,1表示4KB粒度
- D/B:默认操作数大小/栈指针大小标志
- L:64位代码段标志
- P:段存在标志
- DPL:描述符特权级(0-3)
- S:描述符类型(0=系统段,1=代码/数据段)
- TYPE:段类型属性
GDT的加载
内核使用lgdt
指令加载GDT:
lgdt gdt_descriptor
其中gdt_descriptor
包含:
- 16位GDT大小
- 32位GDT基地址
实模式到保护模式的切换流程
切换到保护模式需要严格按照以下步骤进行:
- 禁用中断:使用
cli
指令 - 加载GDT:使用
lgdt
指令 - 设置CR0寄存器:将PE位(第0位)置1
- 远跳转:清除指令流水线中的实模式代码
- 重新加载段寄存器:更新CS以外的段寄存器
- 建立保护模式栈:设置ESP和SS
- 启用中断:使用
sti
指令(可选)
内核启动过程中的关键初始化
控制台初始化
内核早期通过console_init()
函数初始化控制台:
- 检查
earlyprintk
启动参数 - 根据参数配置串口
- 如果启用调试输出,显示初始化信息
putchar()
函数实现细节:
- 处理换行符转换(\n -> \r\n)
- 通过BIOS中断显示字符
- 如果串口初始化,同时输出到串口
堆初始化
init_heap()
函数负责初始化早期堆:
- 检查
CAN_USE_HEAP
标志 - 计算堆栈结束地址
- 确定堆结束地址
- 调整堆栈位置避免冲突
CPU检测
validate_cpu()
函数执行以下操作:
- 检查CPU级别是否满足最低要求
- 检测CPU特性标志
- 根据制造商设置特定选项
- 对于AMD CPU,检查SSE/SSE2支持
内存检测
detect_memory()
函数使用多种方法检测内存:
- e820h接口:获取详细内存映射
- e801h接口:检测标准内存大小
- 88h接口:检测低端内存
e820h内存检测流程:
- 初始化调用参数
- 循环调用中断15h
- 收集内存区域信息
- 直到返回CF标志为止
键盘初始化
keyboard_init()
函数:
- 获取键盘状态
- 设置按键重复率
- 存储键盘状态供后续使用
系统参数查询
内核查询多种系统参数:
- 机器型号和BIOS版本
- 高级电源管理(APM)信息
- PCI总线配置
- 显示适配器信息
总结
从实模式到保护模式的切换是Linux内核启动过程中的关键步骤。通过本文的分析,我们了解了保护模式的基本原理、GDT的结构与作用,以及内核在早期启动阶段进行的各种初始化工作。这些基础工作为后续内核的完整初始化奠定了基础,使操作系统能够充分利用现代CPU的特性,提供稳定可靠的运行环境。
在下一篇文章中,我们将继续分析内核启动过程,探讨如何进入长模式(64位模式)以及更高级的初始化步骤。
linux-insides-zh Linux 内核揭秘 项目地址: https://gitcode.com/gh_mirrors/li/linux-insides-zh
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考