本项目是一个基于 NASM + Bochs + FreeDOS 的 x86 保护模式课程设计工程,目标是在裸机环境下完成保护模式初始化、分页、TSS/LDT 任务定义,以及基于时钟中断的多任务切换。
当前仓库保留了 LEVEL1 到 LEVEL4 四个阶段的源码,其中最终展示版本为 LEVEL4。LEVEL4 实现了 4 个任务、4 套地址空间、优先数调度和同一线性地址的不同物理映射,能够在屏幕同一位置按不同频率显示不同字符串。
LEVEL1
实现保护模式初始化,包含 GDT、段描述符、权限切换等基础内容。
LEVEL2
实现两个任务和两套页表,完成从任务 A 到任务 B 的一次切换。
LEVEL3
保留了双任务和时钟中断切换的中间版本源码,适合作为从两任务过渡到多任务的参考实现。
LEVEL4
这是当前完整实现。程序在保护模式下建立 4 个任务,每个任务都有自己的 LDT、TSS、堆栈和页目录/页表。4 个任务通过同一个线性地址 0x00401000 进入各自逻辑,但由于每个任务使用不同的 CR3,最终执行到不同物理页中的任务代码。
4 个任务当前显示的字符串为:
HUSTMRSUDIONYSUSHELLO
调度采用加权轮转表:
_sched_table: db 0,0,0,0, 1,1,1, 2,2, 3这表示 4 个任务获得 CPU 的机会比例为 4:3:2:1。在运行效果上,HUST 出现最频繁,HELLO 最少,能直观看到优先级差异。
程序启动后先在实模式下完成内存检测、GDT/IDT 准备、A20 打开和保护模式切换,然后进入 32 位代码段继续初始化。
在 32 位阶段,程序会把 4 段任务代码复制到不同物理页,建立 4 套页目录和页表,并把同一个线性地址映射到不同物理页。之后加载 LDTR 和 TR,初始化 8259A,只开放时钟中断 IRQ0。
时钟中断处理程序会根据 _sched_table 更新当前任务号,并通过 jmp SelectorTSSx:0 跳转到目标任务对应的 TSS,从而完成硬件任务切换。任务本身都是死循环,并持续调用同一个线性地址上的例程,因此在不同地址空间下会显示不同字符串。
为了便于调试,IDT 中还区分了异常处理和伪中断处理。如果屏幕上出现 ! 并停机,通常表示程序触发了异常。
.
├── README.md
├── docs/
│ ├── guide.pdf
│ ├── level4_report.md
│ └── task1_level4.asm
├── work/
│ ├── build/ # 构建出的 .COM 文件
│ ├── img/ # FreeDOS 镜像与实验软盘镜像
│ ├── scripts/ # 运行脚本与 Bochs 配置
│ └── src/
│ ├── level1/
│ ├── level2/
│ ├── level3/
│ └── level4/
└── vendor/ # 参考资料与原始样例
本项目当前在以下环境中整理和验证过:
Ubuntu 24.04.4 LTSNASMmtoolsBochs
建议安装命令:
sudo apt update
sudo apt install nasm mtools bochs bochs-x最常用的运行入口是:
./work/scripts/run.sh LEVEL4 gui该脚本会完成以下工作:
- 汇编
work/src/level4/level4.asm - 生成
work/build/LEVEL4.COM - 把
LEVEL4.COM写入work/img/pmtest.img - 使用
work/scripts/.bochsrc.runtime启动 Bochs
Bochs 启动进入 FreeDOS 后,在 DOS 命令行中输入:
LEVEL4
如果要运行其他阶段,把 LEVEL4 替换为 LEVEL1、LEVEL2 或 LEVEL3 即可:
./work/scripts/run.sh LEVEL1 gui
./work/scripts/run.sh LEVEL2 gui
./work/scripts/run.sh LEVEL3 gui
./work/scripts/run.sh LEVEL4 gui执行 LEVEL4 后,首先应看到保护模式提示信息 It is Protect Mode now. 和内存检测结果。如果程序在这一步就死机、重启或返回 DOS,通常说明保护模式初始化、IDT、分页或中断配置存在问题。
初始化完成后,应重点观察屏幕同一位置会反复显示不同字符串,而不是在不同位置同时输出。正常情况下会周期性显示 HUST、MRSU、DIONYSUS 和 HELLO。
更关键的现象是 4 个字符串出现频率不同。由于当前优先级权重为 4:3:2:1,所以正常效果应当是 HUST 最常出现,MRSU 次之,DIONYSUS 再次,HELLO 最少。这一现象说明时钟中断调度和多任务切换已经按优先数策略生效。
如果屏幕出现 ! 并停住,说明程序进入了异常处理流程,应优先检查中断返回路径、TSS 配置和页表映射。
如果不使用脚本,也可以手工构建并写入镜像:
cd work/src/level4
nasm level4.asm -o ../../build/LEVEL4.COM
cd ../../..
mcopy -o -i work/img/pmtest.img work/build/LEVEL4.COM "::LEVEL4.COM"
bochs -q -f work/scripts/.bochsrc.runtime当前项目默认使用 legacy BIOS,否则某些环境下会出现启动不稳定的问题:
romimage: file=/usr/share/bochs/BIOS-bochs-legacy
图形模式配置文件为:
work/scripts/.bochsrc.runtime
无界面模式配置文件为:
work/scripts/.bochsrc.headless
需要注意,当前仓库中的 headless 配置使用的是 display_library: rfb。如果本机端口或显示后端不可用,Bochs 可能无法启动,此时优先使用 gui 模式,或者自行修改 Bochs 显示后端配置。
docs/guide.pdf:课程设计任务书docs/task1_level4.asm:四任务参考框架docs/level4_report.md:实验报告草稿和设计说明vendor/yuyuan/:于渊配套样例与镜像资源
仓库中的 docs/ 和 vendor/ 目录既包含当前实现依赖的资料,也保留了一些开发过程中的参考代码和历史版本。最终展示和提交时,建议以 work/src/level4/level4.asm 为准。