前言:通过阅读并理解操作系统源码中的代码作用和应用场景,可以快速学会64位操作系统开发的相关知识点。在这里感谢田宇先生的开源贡献精神,他的想法,与我不谋而合,作为白帽黑客,对于底层原理的技术探索与研究,是必要的一个发展过程!
注:本文的源码内容,参考自 田宇先生 的 《一个64位操作系统的设计与实现》这本书!
操作系统开发的技术探索:基于Linux内核的64位操作系统(MINE)
本文章仅提供学习,切勿将其用于不法手段!
在计算机系统的启动与运行过程中,内存是最核心的资源之一。操作系统(OS)的内存布局设计,如同城市规划般精妙——既要为底层硬件保留必要的“基础设施”,又要为上层软件提供灵活的“扩展空间”。本文将以经典的x86架构内存布局为蓝本(如图1所示),结合操作系统引导与运行的全流程,解析各内存区域的功能定位、设计逻辑及其背后的技术权衡。
一、内存布局的宏观视角:分层与隔离的艺术
如图1所示,x86架构的内存空间从低地址到高地址被划分为多个功能区,形成“自底向上”的层级结构。这种设计的核心目标是隔离不同层次的硬件与软件功能,避免地址冲突,同时为系统启动和运行提供明确的资源边界。
1. 底层基石:BIOS与MBR的“初始舞台”
最底部的0x0000~0x7C00是BIOS(基本输入输出系统)的代码与数据区。BIOS是计算机加电后第一个运行的固件,负责初始化硬件(如CPU、内存、显卡)、检测设备,并从引导介质(如硬盘、U盘)加载引导程序。其代码直接固化在主板的ROM芯片中,运行时会占用0x0000~0x7C00的部分空间(具体取决于BIOS实现)。
紧随其后的是MBR(主引导记录),位于0x7C00~0x7E00(512字节)。MBR是硬盘的第一个扇区(0号扇区),由BIOS加载到内存后执行。它的核心任务是识别活动分区,并加载该分区的引导扇区(如本文讨论的LOADER.BIN)到内存0x1000:0x00(即0x10000~0x10000+512B)。MBR的512字节包含引导代码(446字节)、分区表(64字节)和校验签名(2字节0xAA55),是系统启动的“第一跳板”。
二、过渡地带:硬件信息与临时缓冲区的“中转站”
从0x7E00到0x90000的内存区域,是引导过程中关键的“过渡地带”,承担着硬件信息传递和临时数据存储的功能。
1. VBE信息与内存映射:图形与内存的桥梁
0x7E00~0x8000通常用于存储VBE(VESA BIOS扩展)信息。VBE是BIOS对显卡的高级支持接口,允许操作系统获取显存地址、分辨率、颜色深度等信息。引导程序(如LOADER)会调用VBE功能(通过BIOS中断INT 10h),将显卡支持的显示模式信息(如1024x768@32bit)写入此区域,供后续内核初始化图形子系统时使用。
0x8000~0x9000则是内存信息区。引导程序(如BIOS或LOADER)会在此存储物理内存布局的描述(如可用内存块、保留区域),通常通过INT 15h功能调用获取。例如,BIOS会返回一个E820h内存映射表,记录0x000000~0xFFFFFFFF范围内每个内存块的起始地址、长度和类型(可用/保留/ACPI等)。内核在初始化内存管理单元(MMU)时,会依赖此信息划分可用空间。
2. 内核临时缓冲区:加载与校验的“工作台”
0x90000~0xA0000被称为内核临时缓冲区。在引导过程中,LOADER需要从硬盘加载内核(如KERNEL.BIN)到内存,但内核可能较大(超过一个扇区),无法一次性放入小缓冲区。此时,LOADER会将内核分块读取到此区域,进行校验(如CRC校验)或解压缩(如gzip),确认无误后再转移到最终的运行地址(通常更高,如0x100000以上)。这一区域的存在,避免了内核加载过程中对其他关键区域(如BIOS、MBR)的覆盖风险。
三、核心运行区:LOADER与内核的“主战场”
从0x10000到0x100000(即1MB~16MB)是操作系统的核心运行区,承载着引导加载程序(LOADER)和内核本体的运行。
1. LOADER:连接BIOS与内核的“桥梁”
0x10000~0x90000是LOADER的典型存放与运行区域。LOADER是比MBR更复杂的引导程序,通常由高级语言(如C)编写,负责完成MBR未完成的任务:
- 设备初始化:检测并初始化硬盘、键盘、网络等设备;
- 文件系统解析:从硬盘(如FAT12/FAT32)读取内核文件(
KERNEL.BIN); - 内存管理初始化:设置页表,为内核分配连续内存空间;
- 环境准备:跳转到内核的入口点(如
0x100000),传递硬件信息(如内存映射表、VBE参数)。
以本文开头的引导代码为例,LOADER被加载到0x1000:0x00(即0x10000),运行后通过FAT12文件系统读取KERNEL.BIN到0x100000以上的内存,最终跳转执行内核代码。
2. 内核:系统的“大脑”与“管家”
内核通常被加载到0x100000(1MB)以上的地址,原因有二:
- 避开低地址保留区:低地址已被BIOS、MBR、LOADER等占用,高地址空间更“干净”;
- 支持保护模式:x86 CPU在保护模式下,地址线扩展至32位(最大4GB),内核需要更大的连续空间来管理页表、进程、设备驱动等。
内核的职责包括:
- 内存管理:通过页表实现虚拟内存,隔离进程空间;
- 进程调度:管理CPU时间片,实现多任务并发;
- 设备驱动:控制硬盘、显卡、网卡等硬件,提供统一接口;
- 文件系统:管理存储设备上的文件,支持读写操作。
四、高地址保留区:扩展与兼容的“预留空间”
0xA0000以上的内存区域主要用于扩展功能和兼容旧设备:
0xA0000~0xBFFFF是传统显存区(EGA/VGA显卡的显存映射),现代操作系统虽使用独立显存,但仍需兼容此区域以避免老程序崩溃;0xC0000~0xDFFFF是扩展系统BIOS区,用于存放第三方硬件(如RAID卡、网卡)的BIOS扩展程序;0xE0000~100000及以上是内核与用户程序区,现代操作系统(如Linux、Windows)会将内核放在0x80000000(32位)或更高地址,用户程序则运行在用户态空间(如0x00400000起)。
五、总结:内存布局的底层逻辑与设计哲学
x86内存布局的本质是分层隔离与资源预留:
- 底层隔离:BIOS、MBR等底层固件占据固定低地址,避免被上层软件意外覆盖;
- 过渡缓冲:VBE信息、内存映射、临时缓冲区为引导过程提供必要数据交换空间;
- 核心运行:LOADER与内核占据中间区域,完成系统初始化与资源接管;
- 扩展兼容:高地址保留区兼顾新旧硬件与软件的兼容性。
对于操作系统开发者而言,理解内存布局不仅是掌握启动流程的关键,更是优化内存管理、避免地址冲突的基础。从MBR的512字节到内核的数MB/GB空间,每一寸内存都被精心规划,支撑着计算机从“开机”到“运行”的完整生命周期。这或许就是计算机科学的魅力——在有限的资源中,构建无限的可能。
图1:x86内存布局示意图(原文提供)
;|----------------------|
;| 100000 ~ END | 内核与用户程序区
;| KERNEL |
;|----------------------|
;| E0000 ~ 100000 | 扩展系统BIOS区
;| Extended System BIOS |
;|----------------------|
;| C0000 ~ Dffff | 扩展区(旧设备兼容)
;| Expansion Area |
;|----------------------|
;| A0000 ~ bffff | 传统显存区(EGA/VGA)
;| Legacy Video Area |
;|----------------------|
;| 9f000 ~ A0000 | BIOS保留区
;|----------------------|
;| 90000 ~ 9f000 | 内核临时缓冲区(加载/校验)
;|----------------------|
;| 10000 ~ 90000 | LOADER运行区(引导加载内核)
;|----------------------|
;| 8000 ~ 10000 | VBE信息与内存映射区(硬件参数)
;|----------------------|
;| 7e00 ~ 8000 | MBR(主引导记录)
;|----------------------|
;| 0000 ~ 7c00 | BIOS代码区(固件初始化)
;|----------------------|
注:本文仅用于教育目的,实际渗透测试必须获得合法授权。未经授权的黑客行为是违法的。

1954

被折叠的 条评论
为什么被折叠?



