news 2026/5/4 22:25:06

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手把手图解: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. 掌握底层内存操作技巧

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/4 22:23:00

嵌入式知识篇---嵌入式板子上电启动方式

嵌入式板子(如开发板、ARM板、单片机系统)的上电启动方式,通常由 Boot ROM、启动引脚电平 和 存储器类型 共同决定。以下是常见的几种上电启动方式: 1. 从片内 Flash 启动(Nor Flash / 嵌入式 Flash) 原理…

作者头像 李华
网站建设 2026/5/4 22:20:46

Python 爬虫高级实战:爬虫黑白名单机制与智能过滤

前言 在大规模集群爬虫、多目标站点批量采集、全网数据抓取以及跨境多源数据汇聚场景下,无差别请求与无规则数据采集会引发一系列严重工程问题:高危违规站点接入、无效垃圾链接泛滥、重复数据冗余采集、反爬风控批量触发、恶意请求导致 IP 封禁、违规内容合规风险激增。传统…

作者头像 李华
网站建设 2026/5/4 22:19:53

如何用Happy Island Designer轻松设计动物森友会完美岛屿:完整指南

如何用Happy Island Designer轻松设计动物森友会完美岛屿:完整指南 【免费下载链接】HappyIslandDesigner "Happy Island Designer (Alpha)",是一个在线工具,它允许用户设计和定制自己的岛屿。这个工具是受游戏《动物森友会》(Anim…

作者头像 李华
网站建设 2026/5/4 22:17:02

保姆级教程:用PyTorch复现LSS的Lift模块,搞懂BEV感知的2D转3D核心

从零实现LSS的Lift模块:PyTorch实战BEV感知的2D-3D转换核心 在自动驾驶的感知系统中,BEV(鸟瞰图)视角正逐渐成为主流范式。它像为车辆装上了"上帝之眼",让算法能够穿透遮挡,统览全局路况。而实现…

作者头像 李华
网站建设 2026/5/4 22:14:26

Vibe Coding:动态风格编码与迁移的AI视频生成技术实践

1. 项目概述与核心价值最近在折腾一个挺有意思的玩意儿,叫“skonto/vibe-coded”。乍一看这个项目名,可能有点摸不着头脑,但如果你对AI生成内容、特别是视频和动态图像生成感兴趣,那这个项目绝对值得你花时间研究一下。简单来说&a…

作者头像 李华
网站建设 2026/5/4 22:14:26

CoPaw智能体技能钩子开发指南:从事件系统到安全监控实战

1. 项目概述与核心价值如果你正在使用或开发基于 CoPaw 框架的智能体,并且希望为你的技能(Skill)增加一些“自动化”或“拦截”能力,比如在智能体开始推理前做个安全检查,或者在执行特定命令时记录日志,那么…

作者头像 李华