北京建设监理协会官方网站,西安模板网站建设套餐,视频多平台发布,8网站建设做网站加载GDT表#xff0c;进入保护模式 加载GDT表#xff0c;实现操作系统从实模式进入保护模式 参考 操作系统学习 — 启动操作系统#xff1a;进入保护模式 保护模式与实模式 GDT、GDTR、LDT、LDTR 调用门与特权级 趣谈 Linux 操作系统
在01.硬盘启动盘#xff0c;加载操作系…加载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等寄存器表示但此时它仅仅变成了一个索引这个索引指向了一个数据结构的一个表项段描述符表项中详细定义了段的起始地址、界限、属性等内容。这个数据结构就是全局描述符表GDTLDT是局部的。 在实模式下段地址并非真实的物理地址在计算物理地址时还要左移 4 位乘以 16。和实模式不同在 32 位保护模式下段地址是 32 位的线性地址如果未开启分页功能该线性地址就是物理地址。
段基址指定了这个段的起始地址它是一个32位的值用于计算线性地址。段界限段界限符 该段的大小。G位G表示段界限粒度大小假如 G 1粒度 4kb(最大段界限 2 20 ∗ 4 K B 2 32 2^{20} * 4KB2^{32} 220∗4KB232)G 0粒度 1字节( 2 20 ∗ 1 2 20 2^{20} * 12^{20} 220∗1220)。超过段界限就会触发内存段保护。段类型需要看两个字段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用来作index2^138K。
段选择器
实模式下的 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 0xfffffCODE_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表示特权级01表示的代码段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 0xffffdw DATA_SEG_BASE 0xffffdb DATA_SEG_BASE 16 0xff; P_DPL_S_TYPE; 其中1表示段描述符有效00表示特权级01表示数据段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 0xfgdt_ptr:dw $ - gdt_base - 1dd gdt_base寻址流程
寻址流程图下图所示
分段机制下的虚拟地址由两部分组成段选择子和段内偏移量。段选择子保存段寄存器里面。段选择子里面最重要的是段号用作段表的索引。段表里面保存的是这个段的基地址、段的界限和特权等级等。虚拟地址中的段内偏移量应该位于 0 和段界限之间。如果段内偏移量是合法的就将段基地址加上段内偏移量得到物理内存地址。
1.根据段选择子在段描述表中找到对应的段描述符号。2.根据段描述符获取段基址、段界限、特权等级等。3.根据段基地址和段内偏移量得到物理地址。
根据GDT寻址
当 TI0时表示段描述符在GDT中 ① 先从GDTR寄存器中获得GDT基址。 ② 然后再GDT中以段选择符高13位位置索引值得到段描述符。 ③ 段描述符符包含段的基址、限长、优先级等各种属性这就得到了段的起始地址基址再以基址加上偏移地址(程序给出)才得到最后的线性地址。
根据LDT寻址
当TI1时表示段描述符在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, 92hor al, 00000010bout 92h, al加载 gdt
GDT 有两个相关的指令
lgdt xxxxxxxx有6字节前2字节是一个gdt界限后4字节是gdt起始地址。将 xxxx 存储到 gdtrsgdt 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, cr0or eax, 0x00000001mov cr0, eax5.验证
进入保护模式流程图 验证方法
protected_mode:; 设置段寄存器mov ax, DATA_SELECTOR ; 设置数据段选择子为DATA_SELECTORmov ds, ax ; 将数据段寄存器设置为DATA_SELECTOR; 转换为逻辑地址ds:0xB7000; ds 绑定数据段基地址为0x1000, 对应的线性地址(物理地址)0xB70000x1000 0xB8000; 0xB8000对应显存的物理地址若能超过写入字符; 说明CPU 能够正确地处理地址映射并且成功进入了保护模式mov byte [0xB7000], A; 测试是否成功进入保护模式.如果没有,写入内存是失败的; 同理逻辑地址为: ds:0x100000; 对应的线性地址(物理地址) 0x101000xchg bx, bxmov byte [0x100000], 0xABjmp $ 当前未开启分页线性地址物理地址。