【从头开始写操作系统系列】实现一个-GDT(2)

举报
远航 | FIBOS 发表于 2020/12/02 00:34:01 2020/12/02
【摘要】 在这篇文章我们将要做: 介绍选择子实现一个选择子结构 选择子是什么? 在上篇文章中我们介绍了段描述符以及段描述符表,这篇文章我们复习一下段、段描述符、段描述符表的功能,并且介绍一下段选择子以及段描述符表。 段(Segment):在80X86中,我们知道分段机制将内存空间分为了多个线性区域,我们把这些线性区域称为段。由于我们要将这些段区分开来,于是我们对段赋予3个...

在这篇文章我们将要做:

  • 介绍选择子
  • 实现一个选择子结构

选择子是什么?

在上篇文章中我们介绍了段描述符以及段描述符表,这篇文章我们复习一下段、段描述符、段描述符表的功能,并且介绍一下段选择子以及段描述符表。

  • 段(Segment):在80X86中,我们知道分段机制将内存空间分为了多个线性区域,我们把这些线性区域称为。由于我们要将这些段区分开来,于是我们对段赋予3个属性。他们分别是段基址(Base)段界限(Limit)段属性(Attribute)段基址表示了一个段在线性空间中的开始地址,段界限表示段内最大偏移量,也就是说,它定义了段的大小,段属性描述了段的一些特性,包括可读可写可执行、特权级等。

  • 段描述符(Descriptor):在程序中我们需要定义一个数据结构来表示段,包括段基址(Base)段界限(Limit)段属性(Attribute)这3个属性,这个数据结构叫做 段描述符(Descriptor)。段是一个逻辑概念,段描述符是对应的数据结构。

  • 段描述符表(Descriptor Table):在一个程序中,不仅仅是只有一个段(段描述符),我们需要一种方法将它们组织起来,也就是说需要一个数组来保存它们,这个结构就是段描述符表。段描述符表分为两种,一种是全局描述符表(GDT),一种是局部描述符表(LDT),系统中供所有任务使用的是全局描述符表,每个任务使用的是它自己的局部描述符表。

  • 段选择子(Selector):我们已经知道段描述符是存储于段描述符表中的,当我们需要访问段描述符时是如何访问的呢?其实,我们是通过段描述符在段描述符表中的位置来进行访问的。段选择子就是这样的一个16位的标识符,它标识了段描述符在段描述符表中的位置。

  • 段描述表寄存器:如何让系统知道段描述符表在什么地方呢?处理器提供了内存管理寄存器,分别是全局描述符表寄存器(GDTR)局部描述符表寄存器(LDTR)。GDTR寄存器中用于存放全局描述符表GDT的32位线性基地址和16位的表的长度值。LDTR寄存器中用于存放局部描述符表LDT的32位线性基地址和16位的表的长度值。通过系统指令,lgdt将GDT的线性基址和长度值加载到GDTR寄存器中,lldt将LDT的线性基址和长度值加载到LDTR寄存器中。

image

动手实现选择子

选择子结构

image

选择子的汇编实现

  • testgdt.asm

[SECTION .gdt]
; 定义GDT数据段
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32; 非一致代码段
LABEL_DESC_VIDEO:  Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址
; GDT 结束

GdtLen equ $ - LABEL_GDT  ; GDT长度
GdtPtr dw  GdtLen - 1  ; GDT界限 dd  0 ; GDT基地址

; GDT 选择子
SelectorCode32 equ LABEL_DESC_CODE32   - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
; END of [SECTION .gdt]

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • pm.inc
; 描述符类型
DA_32 EQU 4000h   ; 32 位段

; 存储段描述符类型
DA_DRW EQU 92h ; 存在的可读写数据段属性值
DA_C EQU 98h ; 存在的只执行代码段属性值
DA_CR EQU 9Ah ; 存在的可执行可读代码段属性值
DA_CCO EQU 9Ch ; 存在的只执行一致代码段属性值
DA_CCOR EQU 9Eh ; 存在的可执行可读一致代码段属性值

;描述符
;3个参数:
;   1.段基址:32位(4字节)
;   2.段界限:低20位
;   3.属性:12位(高字节中的低4位总是0%macro Descriptor 3 ;定义宏Descriptor,有3个参数 dw  %2 & 0FFFFh ;用参数2的低16位填充一个WORD dw  %1 & 0FFFFh ;用参数1的低16位填充一个WORD db  (%1 >> 16) & 0FFh   ;用参数117-25位填充一个BYTE dw  ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ;用参数217-21位以及参数31-8位和13-16位填充一个WORD dw  (%1 >> 24) & 0FFh   ;用参数125-32位填充一个WORD
%endmacro

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

现在选择子已经初步完成,下篇文章我们重点讲解 GDT 以及它的实现。


版权声明:本文为博主原创文章,未经博主允许不得转载。

文章来源:http://blog.luoyuanhang.com

文章来源: blog.csdn.net,作者:冰水比水冰,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/luoyhang003/article/details/47346249

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。