【OS课设日志】《Orange‘S:一个操作系统的实现》Ch3

本文详细介绍了如何从实模式转换到保护模式,涉及GDT(全局描述符表)的设置,实现大于1MB内存的寻址,以及LDT(局部描述符表)的概念。通过Bochs虚拟机进行实验,演示了在保护模式下进行内存管理的步骤和方法,强调了这些技术在提高系统安全性和稳定性方面的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

《Orange’S:一个操作系统的实现》第三章——保护模式

实验内容:认识保护模式,实现从实模式到保护模式的转换,GDT描述符;实现实模式大于1MB内存的寻址能力,并接着上一次实验,从保护模式返回到实模式,重新设置各个段寄存器的值;LDT描述符;学会使用挂载指令和运行程序。

3.1 认识保护模式

认识保护模式,实现从实模式到保护模式的转换,GDT描述符

实验步骤:
①根据书中汇编代码创建pmtest1.asm文件并编译为pmtest1.bin

touch pmtest1.asm
# 这里省略编辑pmtest1.asm内容的操作
nasm pmtest1.asm -o pmtest1.bin

②复制第二章的软盘映像文件a.img和配置文件bochsrc
!注意,若此处报错“No bootable device",参考附录解决办法

③使用dd指令将pmtest1.bin文件写入a.img的引导扇区

dd if=pmtest1.bin of=a.img bs=512 count=1 conv=notrunc

④运行Bochs
跳入保护模式
出现红色字母P
至此,我们已经实现了从实模式到保护模式的转换

直观改变:

  • 定义了一个叫GDT的数据结构
  • 16位代码进行了一些与GDT有关的操作
  • 最后程序跳转到32位代码进行了一些现存操作

上述问题将在下面详解


3.1.1 保护模式的运行环境

执行步骤:
①下载freedos.img,将解压后的a.img复制到目录,并重命名为freedos.img
②使用bximage生成pm.img
③修改bochsrc配置文件,确保其中有以下三行:

floppya: 1_44=freedos.img, status=inserted
floppyb: 1_44=pm.img, status=inserted

boot: a

④执行bochs -f bochsrc启动Bochs,格式化B盘
⑤编译pmtest1.asmpmtest1.com

nasm pmtest1.asm -o pmtest1.com

⑥将pmtest1.com复制到虚拟软盘pm.img

sudo mount -o loop pm.img /mnt/floppy
sudo cp pmtest1.com /mnt/floppy/
sudo umount /mnt/floppy

⑦到FreeDos中执行下述指令

b:
pmtest1.com

解释:更改配置文件bochsrc之后,Bochs将从freedos.img的引导扇区启动,并能够执行一系列DOS指令。上述操作为切换到B盘,执行pmtest1.com文件

3.1.2 GDT

实模式和保护模式的内存管理机制不同,实模式下可以直接使用物理地址进行访问,而保护模式需要使用GDT和段描述符来进行管理和保护。

GDT是全局描述符表(Global Descriptor Table)的缩写,是在保护模式下使用的一种数据结构,用于描述内存段的属性访问权限。每个内存段都由一个或多个GDT表项描述。

GDT表项是一个8字节的数据结构,包含了内存段的基地址、大小、访问权限、特权级别等信息。在GDT中,每个表项都有一个唯一的段选择器(segment selector)与之对应。使用GDT可以提供更为安全和可靠的内存管理,可以确保不同程序之间的内存空间相互隔离,防止程序访问非法内存,从而提高系统的稳定性和安全性。

段式寻址示意图

3.1.3 实模式到保护模式

跳转步骤如下:

①准备GDT:初始化GDT表,将GDT表中的每个表项设置为合适的值,包括内存段的基地址、大小、访问权限、特权级别等信息。
②用lgdt加载gdtrlgdt指令的作用是将GDT表的起始地址和大小保存到gdtr寄存器中的相应字段中,gdtr包含了GDT表的起始地址和大小,以及一些其他的控制信息。
③打开A20:实模式寻址能力为1MB,用不到第20个(从零开始)地址位,超出回滚,故实模式下A20始终为0;进入保护模式后获得更大的寻址能力,因此需要打开A20地址线。
④置cr0的PE位为1:打开开关
⑤跳转


3.2 保护模式进阶

3.2.1 实现大于1MB的内存寻址能力

上文提到,在保护模式之下寻址空间可以达到4GB,下面试验读写大地址内存(以5MB为例)。

一句话:实际上在GDT中增加一个表项即可,该描述符的段基址为0500000h,段界限和属性等略

实验步骤:
①复制文章pmtest2.asm代码,编译为pmtest2.com

②执行下述指令,将pmtest2.com写入虚拟软盘pm.img

sudo mount -o loop pm.img /mnt/floppy
sudo cp pmtest2.com /mnt/floppy/
sudo umount /mnt/floppy

③执行bochs -f bochsrc开启Bochs虚拟机,并在虚拟机中切换到B盘,执行pmtest2.com,得到如下图所示结果:
大于1MB的寻址能力

3.2.2 LDT

在选择子(Selector)的高13位中,T1(Table Indicator)位表示GDT(全局描述符表)或LDT(局部描述符表)的标识符。当T1位为0时,选择子表示GDT表中的一个描述符;当T1位为1时,选择子表示LDT表中的一个描述符。


附录:Bug

1. No bootable device

问题描述
在3.1中,若新建一个a.img软盘映像文件,然后将pmtest1.bin写入软盘的第一个扇区,再运行Bochs时会产生如下错误
no bootable device
原因分析
根据上一篇博客内容【OS课设日志】《Orange‘S:一个操作系统的实现》Ch1/2

(如果是从软盘启动)计算机会自动检查0面0磁道1扇区(即第一个扇区),如果该扇区以0xAA55结束,则BIOS认为它是一个引导扇区。

我们观察第二章中.asm文件最后两行代码

times 510 - ($ - $$)
dw 0xaa55

上述代码使a.img已经被填充为512字节并且以0xaa55结束,所以BISO就认为它是一个引导区,就去加载它。若第三章中新建文件,则该文件第一个扇区没有以0xaa55结束,BIOS无法识别,因此出现No bootable device错误

解决办法

按书中要求,复制第二章中的a.img,重新写入pmtest1.bin


2. mount: /mnt/floppy: mount point does not exist.

问题描述

pmtest1.com复制到细腻软盘pm.img上时需要执行下面指令:

sudo mount -o loop pm.img /mnt/floppy
sudo cp pmtest1.com /mnt/floppy/
sudo umount /mnt/floppy

执行第一条时报错

mount: /mnt/floppy: mount point does not exist.

错误原因

挂载点目录不存在:在执行mount命令时,指定的挂载点目录可能尚未创建已经被删除。需要确保挂载点目录存在,可以使用mkdir命令创建挂载点目录。

解决办法

执行指令sudo mkdir /mnt/floppy创建挂载点,而后运行不报错

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值