02.加载GDT表,进入保护模式

news/2024/7/5 5:51:12

加载GDT表,进入保护模式

加载GDT表,实现操作系统从实模式进入保护模式

参考
操作系统学习 — 启动操作系统:进入保护模式
保护模式与实模式
GDT、GDTR、LDT、LDTR
调用门与特权级
趣谈 Linux 操作系统

在01.硬盘启动盘,加载操作系统中BIOS在0x7c00处加载MBR,并让程序跳转到该处。MBR只是一个中转站,其他功能如加载GDT表、切换保护模式,需要loader完成。

1.实模式

概念:
在程序中用到的地址都是真实的物理地址,“段基址:段内偏移地址”产生的逻辑地址就是物理地址,即程序员可见的地址完全是真实的内存地址。
物理地址(physicaladdress)=段值(segment) * 16 + 偏移(offset)

缺点:

  • 没有权限划分,实模式下操作系统和用户程序属于同一特权级
  • 程序中用到的地址都是真实的物理地址,逻辑地址等于物理地址
  • 访问超过 64KB 的内存区域时要切换段基址,16位寄存器,2^16 = 64KB
  • 共 20 条地址线,最大可用内存为 1MB
  • 平坦模型,无法支持多任务,安全性无法保证

2.保护模式

概念:
保护模式下,全部32条地址线有效,可寻址高达4G字节的物理地址空间。保护模式下,地址表示方式:段(segment):偏移(offset),虽然段值仍然由原来的cs、ds等寄存器表示,但此时它仅仅变成了一个索引,这个索引指向了一个数据结构的一个表项(段描述符),表项中详细定义了段的起始地址、界限、属性等内容。这个数据结构就是全局描述符表GDT(LDT是局部的)。
段描述符
在实模式下,段地址并非真实的物理地址,在计算物理地址时,还要左移 4 位(乘以 16)。和实模式不同,在 32 位保护模式下,段地址是 32 位的线性地址,如果未开启分页功能,该线性地址就是物理地址

  • 段基址:指定了这个段的起始地址,它是一个32位的值,用于计算线性地址。
  • 段界限:段界限符 = 该段的大小。
  • G位G表示段界限粒度大小,假如 G = 1,粒度 = 4kb(最大段界限 = 2 20 ∗ 4 K B = 2 32 2^{20} * 4KB=2^{32} 2204KB=232),G = 0,粒度 = 1字节( 2 20 ∗ 1 = 2 20 2^{20} * 1=2^{20} 2201=220)。超过段界限,就会触发内存段保护。
  • 段类型:需要看两个字段:type和S位。
  • S位:S位的作用在于,指示这个段是不是系统段。只有知道了S位,type段才有意义。系统段就是说,这个段由硬件CPU运行,非系统段是由软件(OS/用户)运行。
    • S = 1 代码段或数据段的描述符
      在这里插入图片描述
    • S= 0 系统段的描述符
      在这里插入图片描述

3.分段机制

段描述符表

每个段都需要一个段描述符。这些描述符存储在内存的一段空间中,即全局描述符表GDT(或LDT)。
GDT与LDT的区别:

  • 范围不同:GDT 是全局段描述符表,包含系统中所有进程所需的所有段描述符,而 LDT 是局部段描述符表,只有在需要更多段描述符时才使用。
  • 使用限制不同:每个进程只能使用一个 GDT,但可以同时使用多个 LDT。
  • 加载方式不同:GDT 的基地址和限长保存在 GDTR 寄存器中,由 CPU 加载,而 LDT 的基地址和限长保存在相应进程的 LDTR寄存器中,由操作系统加载,与进程的虚拟地址空间独立。
  • 访问速度不同:由于 GDT 存储所有段描述符,因此访问 GDT 通常比访问 LDT 更快

描述符表的长度可变,最多可以包含8K个这样的描述符(因为段选择子是16位的,其中的13bit用来作index,2^13=8K)。

段选择器

实模式下的 6 个段寄存器 CS、 DS、 ES、 FS、 GS 和 SS,在保护模式下叫做段选择器。
其结构如下图所示
在这里插入图片描述

  • 第0-1位:请求特权级(Requestor Privilege Level, RPL),用于表示当前代码的特权级别。RPL可以取值0、1、2、3,其中0表示最高特权级,3表示最低特权级。
  • 第2位:表指示器(TableIndicator, TI),用于指示该段描述符存储在全局描述符表(GDT)还是局部描述符表(LDT)中。TI的值为0表示描述符存储在GDT 中,为1表示描述符存储在 LDT 中。
  • 第3-15位:索引(Index),用于标识段描述符在 GDT 或 LDT中的位置,索引的值必须是 8 的倍数。

段选择子的结构可以通过一个 16 位的寄存器来存储和传递,如 CS(代码段选择子)、DS(数据段选择子)和 SS(堆栈段选择子)等。当 CPU 访问某个段时,它会根据段选择子来确定所需的段描述符的位置,并加载该段描述符以获取相应的段基址、权限和限长等信息,从而实现对这个段的正确访问。

在这里插入图片描述
GDT表可以很大,存放在内存中,由 GDTR寄存器 存储它的地址。同理,LDT存储在LDTR中。其中:

  • GDTR全局描述符寄存器:48位,高32位存放GDT基址,低16为存放GDT限长。
    在这里插入图片描述
    • 通过 lgdt xxxx 将xxxx存储到 GDTR 寄存器,xxxx包含GDT内存起始地址和GDT界限。
    • 通过 sgdt xxxx获得当前 GDTR 寄存器的内容存储到 xxxx 当中。
  • LDTR局部描述符寄存器:16位,高13为存放LDT在GET中的索引值。

以此构建GDT表:

[SECTION .gdt]
DATA_SEG_BASE equ (0x1000)
DATA_SEG_LIMIT equ 0xfffff

CODE_SEG_BASE equ (0x0)
CODE_SEG_LIMIT equ 0xfffff
; 索引<<3位 = 地址相减  。2^3 = 8字节
CODE_SELECTOR equ (gdt_code - gdt_base) ; 代码段选择子
DATA_SELECTOR equ (gdt_data - gdt_base) ; 数据段选择子

gdt_base:
    dd 0, 0
gdt_code:
    dw CODE_SEG_LIMIT & 0xffff ; 段界限
    dw CODE_SEG_BASE & 0xffff ;
    db CODE_SEG_BASE >> 16 & 0xff
    ;    P_DPL_S_TYPE
    ; 其中1表示有效,00表示特权级0,1表示的代码段,1000表示代码段不可读写,可执行
    db 0b1_00_1_1000
    ;    G_DB_AVL_LIMIT
    ; 其中0表示段界限以字节为单,1表示此段是32位的,后四位表示段界限高4位。
    db 0b0_1_00_0000 | (CODE_SEG_LIMIT >> 16 & 0xf)
    db CODE_SEG_BASE >> 24 & 0xf
gdt_data:
    dw DATA_SEG_LIMIT & 0xffff
    dw DATA_SEG_BASE & 0xffff
    db DATA_SEG_BASE >> 16 & 0xff
    ;    P_DPL_S_TYPE
    ; ,其中1表示段描述符有效,00表示特权级0,1表示数据段,0010表示数据段可读写。
    db 0b1_00_1_0010
    ;    G_DB_AVL_LIMIT
    ;   其中1表示段界限以4KB作为单位,1表示此段是32位的,后四位表示段界限高4位。
    db 0b1_1_00_0000 | (DATA_SEG_LIMIT >> 16 & 0xf)
    db DATA_SEG_BASE >> 24 & 0xf

gdt_ptr:
    dw $ - gdt_base - 1
    dd gdt_base

寻址流程

寻址流程图下图所示:
在这里插入图片描述

分段机制下的虚拟地址由两部分组成,段选择子段内偏移量。段选择子保存段寄存器里面。段选择子里面最重要的是段号,用作段表的索引。段表里面保存的是这个段的基地址、段的界限和特权等级等。虚拟地址中的段内偏移量应该位于 0 和段界限之间。如果段内偏移量是合法的,就将段基地址加上段内偏移量得到物理内存地址。

  • 1.根据段选择子在段描述表中找到对应的段描述符号。
  • 2.根据段描述符获取段基址、段界限、特权等级等。
  • 3.根据段基地址和段内偏移量得到物理地址。

根据GDT寻址

当 TI=0时表示段描述符在GDT中
在这里插入图片描述
① 先从GDTR寄存器中获得GDT基址。
② 然后再GDT中以段选择符高13位位置索引值得到段描述符。
③ 段描述符符包含段的基址、限长、优先级等各种属性,这就得到了段的起始地址(基址),再以基址加上偏移地址(程序给出)才得到最后的线性地址。

根据LDT寻址

当TI=1时表示段描述符在LDT中
在这里插入图片描述
① 还是先从GDTR寄存器中获得GDT基址。
② 从LDTR寄存器中获取LDT所在段的位置索引(LDTR高13位)。
③ 以这个位置索引在GDT中得到LDT段描述符从而得到LDT段基址。
④ 用段选择符高13位位置索引值从LDT段中得到段描述符。根据位置索引在GDT中得到LDT段描述符从而得到LDT段基址。
⑤ 段描述符符包含段的基址、限长、优先级等各种属性,这就得到了段的起始地址(基址),再以基址加上偏移地址(程序给出)才得到最后的线性地址。

4.进入保护模式流程

进入保护模式的代码却是千奇百怪的,形式可不统一。比如进入保护模式需要三个步骤。

  • 打开 A20
  • 加载 gdt
  • 将 cr0 的 pe 位置 1

打开 A20

打开A20,避免地址回绕
在这里插入图片描述
打开方式:

  • 通过键盘控制器
  • 调用BIOS功能
  • 使用系统端口
    in    al,  92h
    or    al,  00000010b
    out   92h, al

加载 gdt

GDT 有两个相关的指令:

  • lgdt xxxx:xxxx有6字节,前2字节是一个gdt界限,后4字节是gdt起始地址。将 xxxx 存储到 gdtr
  • sgdt xxxx:获得gdtr的值,存储到 xxxx
    进入保护模式一定需要加载gdt,首先在loader建立一个GDT,然后将 GDT 的地址、界限存储到 GDTR 寄存器当中。
lgdt [gdt_ptr]

将 cr0 的 pe 位置 1

CR0 寄存器的第0位是 pe位,Protection Enable,用来启动保护模式,是保护模式的开关。所以这一步一般都是最后一步。
在这里插入图片描述
PE 为 0 表示在实模式下运行,PE 为 1 表示在保护模式下运行。

   mov eax, cr0
   or eax, 0x00000001
   mov cr0, eax

5.验证

进入保护模式流程图:
在这里插入图片描述
验证方法:

protected_mode:
   ; 设置段寄存器
   mov ax, DATA_SELECTOR      ; 设置数据段选择子为DATA_SELECTOR
   mov ds, ax        ; 将数据段寄存器设置为DATA_SELECTOR

    ; 转换为逻辑地址:ds:0xB7000
    ; ds 绑定数据段,基地址为0x1000, 对应的线性地址(物理地址)0xB7000+0x1000 = 0xB8000
    ; 0xB8000对应显存的物理地址,若能超过写入字符
    ; 说明CPU 能够正确地处理地址映射,并且成功进入了保护模式
    mov byte [0xB7000], 'A'

    ; 测试是否成功进入保护模式.如果没有,写入内存是失败的
  	; 同理逻辑地址为: ds:0x100000
  	; 对应的线性地址(物理地址) 0x101000
    xchg bx, bx
    mov byte [0x100000], 0xAB

    jmp $

在这里插入图片描述
在这里插入图片描述
当前未开启分页,线性地址=物理地址。


http://lihuaxi.xjx100.cn/news/1235120.html

相关文章

随机数组归并问题

1 问题 生成两个任意的随机数组&#xff0c;并将这两个数组按照数字大小按顺序归并到一个新数组中。 2 方法 思路&#xff1a;定义三个数组&#xff0c;两个数组自己输入值&#xff0c;第三个数组用来作归并后的数组&#xff0c;先将两个数组的值全部赋给第三个数组&#xff0c…

DAY 72 redis高可用的主从复制、哨兵、cluster集群

Redis 高可用 什么是高可用 在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。 但是在Redis语境中&#xff0c;高可用的含义似乎要宽泛一些&#xff0c;除了保证提供正常服…

对数组的“reg [7:0] a_tmp[32:0]”理解

数组 在verilog中&#xff0c;对数组reg [7:0] a_tmp[32:0]进行操作时&#xff0c;分不清楚先对[32:0]进行操作还是先对 [7:0]进行操作&#xff0c;为此进行下面的实验。进一步加深对数组的理解。 实验1&#xff1a; reg [7:0] a_tmp[32:0];遍历的方式&#xff1a; integer …

对话利星行汽车:合作圆满,对斯歌充分信任!

上海斯歌在利星行汽车的OA替换项目中&#xff0c;喜提客户高度评价。近日&#xff0c;就企业数字化及斯歌产品、服务、体验等问题&#xff0c;斯歌与利星行汽车的管理信息系统总经理庄淑菱女士展开了一次对话访谈。 利星行汽车简介 利星行汽车于1993年进入中国大陆市场&#xf…

【几分醉意赠书活动 - 03期】 | 《Python系列丛书》

个人主页&#xff1a; 几分醉意的CSDN博客主页_传送门 个人主页&#xff1a; 陈老板的CSDN博客主页_传送门 赠书活动 | 第三期 本期好书推荐&#xff1a;《Python系列丛书》 粉丝福利&#xff1a;书籍赠送&#xff1a;共计送出30本 参与方式&#xff1a;关注公众号&#xff1a;…

Kali Linux 简介

概要 Kali Linux 是安全专家和以及网络安全爱好者所使用的工具&#xff0c;你不应该也不允许使用它来对他人的计算机系统进行未经允许的任何活动。任何使用它带来的法律后果和损失&#xff0c;将由使用者自行承担。我们之所以推荐 Kali Linux&#xff0c;是希望有更多的人来保护…

作为leader,如何去做,如何去把控,如何对外交流

充分的理解理论知识&#xff0c;找到正确的人去验证你的理论知识时可行的。 作为leader&#xff0c;如何去用人&#xff0c;如何能让人把他们的才华展现出来&#xff0c;用尽其才华很重要。 作为项目开发的案例我后续会继续复盘&#xff0c;有人可用&#xff0c;有正确的用人方…

macbook pro存储空间不足怎么办? MacBook Pro怎么优化或清理Mac磁盘空间?

MacBook Pro用久了之后都会堆积很多残留文件或缓存垃圾&#xff0c;久经之下MacBook Pro磁盘空间将会面临不够用的情况。 macbook pro存储空间不足怎么办&#xff1f;macbook pro笔记本中的存储空间不足&#xff0c;想要优化一下&#xff0c;该怎么优化呢&#xff1f; 这时候…