当前位置: 首页 > news >正文

手把手图解:Linux 0.11 启动时那场关键的‘内存大搬家’(从 0x10000 到 0x0)

手把手图解:Linux 0.11 启动时那场关键的‘内存大搬家’(从 0x10000 到 0x0)

当计算机从通电到操作系统完全启动的短短几秒内,内存中发生着一场精密的数据迁移。这场迁移不仅关乎系统能否正常启动,更体现了早期操作系统设计者对硬件资源的极致掌控。本文将带您深入Linux 0.11启动过程中那段关键的汇编代码,揭示为何需要将0x10000至0x90000的数据搬迁到物理内存起始处,以及这一操作如何为后续的保护模式切换铺平道路。

1. 启动初期的内存布局

在理解"大搬家"之前,我们需要先了解计算机刚完成自检时的内存状态。此时BIOS已经完成了硬件检测,并将控制权交给了位于0x7C00处的bootsect.s引导扇区代码。这段512字节的代码随后将自己复制到0x90000处,并加载setup.s和system模块到0x90200和0x10000位置。

此时的内存布局如下:

内存地址范围内容描述
0x00000-0x003FFBIOS中断向量表
0x00400-0x004FFBIOS数据区
0x00500-0x07BFF可用内存
0x07C00-0x07DFF原始bootsect.s
0x10000-0x8FFFFsystem模块
0x90000-0x901FF移动后的bootsect.s
0x90200-0x90FFFsetup.s

这种布局看似合理,但存在一个关键问题:当系统准备进入保护模式时,需要重新配置全局描述符表(GDT)和中断描述符表(IDT),而这些数据结构最好放置在内存起始位置。

2. 为何需要内存搬迁

2.1 保护模式的内存需求

实模式下,程序通过段寄存器:偏移地址的方式访问内存,每个段最大64KB。而保护模式下,内存管理完全由操作系统控制,需要通过GDT和IDT来定义内存段的属性和权限。

Linux 0.11需要:

  1. 在0x00000处放置新的GDT和IDT
  2. 确保system模块位于连续的低地址空间
  3. 保留BIOS获取的硬件信息(存储在0x90000附近)

如果保持原有布局,0x00000处仍被BIOS中断向量表占据,无法满足这些需求。

2.2 搬迁的具体目标

setup.s中的do_move循环执行以下操作:

  1. 将0x10000-0x8FFFF的内容下移到0x00000-0x7FFFF
  2. 保留0x90000-0x90FFF的硬件信息
  3. 腾出0x00000-0x0FFFF空间用于GDT/IDT

这样调整后,内存布局变为:

内存地址范围内容描述
0x00000-0x0FFFF新GDT/IDT空间
0x10000-0x8FFFFsystem模块(原位置)
0x90000-0x90FFF硬件信息区

3. 深入do_move汇编实现

让我们逐行分析这段经典的汇编代码:

mov ax,#0x0000 ; 目标段初始化为0x0000 cld ; 清除方向标志,确保movs向前移动 do_move: mov es,ax ; 设置目标段地址 add ax,#0x1000; 每次移动4KB(0x1000字节) cmp ax,#0x9000; 是否到达0x90000(段地址表示) jz end_move ; 完成则跳转 mov ds,ax ; 设置源段地址 sub di,di ; 目标偏移清零 sub si,si ; 源偏移清零 mov cx,#0x8000; 设置计数器(0x8000字=64KB) rep movsw ; 重复移动字数据 jmp do_move ; 继续下一块 end_move:

这段代码的精妙之处在于:

  1. 批量传输:使用rep movsw指令每次传输64KB数据
  2. 段地址递增:每次循环源段和目标段都增加0x1000(4KB)
  3. 高效循环:通过简单的比较和跳转控制流程

实际传输过程如下表所示:

循环次数源地址范围目标地址范围传输量
10x10000-0x1FFFF0x00000-0x0FFFF64KB
20x20000-0x2FFFF0x10000-0x1FFFF64KB
............
80x80000-0x8FFFF0x70000-0x7FFFF64KB

4. 搬迁后的关键操作

内存搬迁完成后,系统紧接着执行以下关键步骤:

4.1 加载段描述符

end_move: mov ax,#SETUPSEG mov ds,ax lidt idt_48 ; 加载IDT lgdt gdt_48 ; 加载GDT

这里idt_48gdt_48是预先定义好的描述符表指针,其结构如下:

IDT描述符:

idt_48: .word 0 ; 界限 .long 0 ; 基址

GDT描述符:

gdt_48: .word 0x800 ; 界限(2KB) .long 0x00000 ; 基址

4.2 切换到保护模式

mov ax,#0x0001 lmsw ax ; 加载机器状态字(CR0) jmpi 0,8 ; 跳转到保护模式代码

这个jmpi 0,8指令中的8是段选择子,指向GDT中的代码段描述符。

5. 实际调试技巧

如果想在模拟器(Bochs/QEMU)中观察这一过程,可以:

  1. do_move循环开始前设置断点
  2. 使用内存查看命令观察0x10000和0x00000处内容
  3. 单步执行每条汇编指令
  4. 特别注意ES、DS、SI、DI寄存器的变化

调试示例命令(Bochs):

b 0x90200:0x00 # 在setup.s开始处设断点 c # 继续执行 s # 单步执行 x /16x 0x10000 # 查看源内存 x /16x 0x00000 # 查看目标内存 info registers # 查看寄存器状态

6. 历史背景与现代对比

这一设计反映了早期PC硬件的限制:

  1. 实模式下1MB内存限制
  2. BIOS服务的依赖
  3. 保护模式切换的特殊要求

现代Linux启动过程已经大为简化:

  1. 使用GRUB等引导加载程序直接进入保护模式
  2. 内存管理更灵活
  3. 不再需要手动搬迁系统代码

然而理解这一经典机制仍有价值:

  1. 学习x86架构的演变
  2. 理解操作系统与硬件的交互
  3. 掌握底层内存操作技巧

在开发嵌入式系统或微内核时,类似的低层次内存操作仍然常见。

http://www.jsqmd.com/news/753440/

相关文章:

  • Altium Designer 22 新手避坑指南:从原理图到PCB的10个关键设置(附快捷键清单)
  • 3步构建Windows任务栏透明化工具TranslucentTB的容器化开发环境
  • 从UE5的坐标转换函数出发,手把手带你复现一个简易的3D拾取Demo(C++/蓝图)
  • 为什么你的IAsyncEnumerable在Azure Functions中内存暴涨300%?C# 13新配置项AsyncStreamOptions.BufferCapacity正在悄悄改写GC命运
  • 65周作业
  • TTP223触摸模块的5个常见坑与避坑指南:从模式切换、电平匹配到驱动能力详解
  • C#/.NET 6下用NModbus4快速搭建Modbus TCP从站(附完整源码与ModbusPoll测试)
  • 避开MATLAB优化这些坑:fminsearch和fmincon初值设置与全局最优解搜寻指南
  • 2026 全国防水公司 TOP5 权威排名 - 企业资讯
  • 快手网页版扫码登录的Python逆向手记:我是如何‘抓’出那三个关键接口的
  • 为什么92%的C#医疗系统在FHIR 2026适配中卡在Resource Validation?——基于HL7官方Test Server压测的.NET源码级调试日志解密
  • 如何用Python快速接入Taotoken并调用多个大模型API
  • STM32MP257D异构计算模块MYC-LD25X解析与应用
  • 基于MCP协议的邮件设计自动化:AI驱动的高兼容性邮件模板生成
  • 多模态旋转位置编码原理与医疗影像应用实践
  • 企业如何利用多模型聚合能力优化内部知识问答系统
  • AI厨房管家:用Git工作流与LLM打造可复现的智能食谱系统
  • Python 爬虫高级实战:多环境爬虫配置统一管理方案
  • TCGA数据实战:用sva和limma搞定批次效应,附COAD/READ结肠癌数据完整R代码
  • Music Tag Web音乐标签编辑器:从新手到高手的完整使用指南
  • 你的LCD1602 I2C地址不对?手把手教你用Arduino IDE扫描并修复0x27/0x3F地址冲突问题
  • 普遍认为学历越高,薪资一定越高,编程整合学历,岗位,能力,业绩数据,分析学历与收入无绝对关联,打破求职固有偏见。
  • GEEKOM A5迷你主机评测:Ryzen 7 5800H性能解析
  • 如何实现单细胞数据分析:SCP端到端流程的实践指南
  • REIN方法:基于推理初始化的对话系统错误恢复技术
  • 利用 Taotoken 为 AIGC 内容生成平台提供稳定的模型供应链
  • SQL 第一篇:CRUD 实战,从 user 表开始写接口
  • 视频信号耦合技术:AC与DC耦合原理及应用对比
  • RoboMaster 2023赛季大能量机关识别:从OpenCV二值化到findContours轮廓分析,一个完整实战流程
  • 大众觉得投入资金越多生意越红火,编程统计创业投入金额与营收数据,验证小额轻资产创业回报率远超重资产模式。