GDT全局描述表
GDT全局描述表
实模式下内存的地址访问限制是1M, 这是由于8086cpu的使用的寄存器是16位的 而地址总线是20位。1M = 1<<20。
现在cpu的寄存器早就不是什么16位的了,但是计算机现代计算机启动后还是采用实模式。
实模式中就有内存访问限制,要突破这个限制,计算机必须进入保护模式。
Intel 64 and IA-32 Architectures. Software Developer’s Manual. Volume 3A的第二章对GDT进行了详细的描述。
实模式中内存寻址才用方式:
Segment:Offset
Segment 是段寄存器: CS, ES, DS, FS, GS
实模式下内存段
转换成物理地址公式
PhysicalAddress = Segment * 16 + Offset
比如:
mov $0x7c0, %ax
mov %ax, %ds
mov %ds:(0x20), %ax
这里访问的物理地址就是0x7c0*0x10 + 0x20
保护模式下内存段
保护模式的内存寻址(32bits)
保护模式突破实模式的内存限制, 能够使用4G的内存。 保护模式中,内存的管理模式分为两种,段模式和页模式。
段模式就采用GDT来进行内存管理。GDT在内存中任意位置, 所以lgdt指令用于让cpu设置gdtr的值, gdtr是一个48bits的寄存器。
gdtr结构如下图:
图片来源于OSWIKI
Offset | Name | Description |
0..15 | Size | 整个GDT表的大小 2Bytes |
16..47 | Offset | GDT的入口位置 |
gdtptr:
.word (GdtLen - 1) /* limit */
.long 0
lgdt gdtptr
使用lgdt来设置.
图片来源于OSWIKI
Offset | Name | Description |
0..15 | Limit | limit的底4Bytes |
16..31 | Base | base的底4Bytes |
32..39 | Base | base的中间2Bytes |
40..47 | Access Byte | 内存访问控制标志字节 |
48..51 | Limit | limit的高4Bytes |
52..55 | Flags | 4个段大小标记 |
56..63 | Base | Base的高2Bytes |
这里比较让人迷惑的是BASE与LIMIT不是完整的内存表示,而是分散分布在里面。
Base Address: 32bits基址 分布在在描述符中分成三块存在。 可以指向4G内存的任意地方。
Limit: 20bits的限制, 由于是20bits所以一般情况限制最大值是1M, 但是可以通过设置页粒度值让限制由1M变成1M*4096(4G)
Bit | Name | Description |
Pr | Present | 1 selector 现在不可用, 0 可用. |
Privl | Privilege Level | 3Bits特权级别标识. |
Ex | Executable | 1 表示内存是代码区, 0表示是数据区. |
DC(code) | Direction | 1 表示代码从低优先级开始执行 代码段有效. |
DC(data) | Conforming | 1 端从下向上增加。 0 端从上向下增加. |
RW(code) | Readable | 1 允许读,永远不允许写入 |
RW(data) | Readable | 1 允许写入,永远都能读 |
Ac | Accessed | CPU使用此端的时候设置为1, 初始化是0 |
Gr | Granularity | 0 表示Limit的单位Byte, 1 limit单位是4096Bytes |
Sz | Size | 0 表示 16-bit 保护模式, 1 表示32位保护模式 |
.macro SEG_DESC Base, Limit, Attr
.2byte (\Limit & 0xFFFF)
.2byte (\Base & 0xFFFF)
.byte ((\Base >> 16) & 0xFF)
.2byte ((\Attr & 0xF0FF) | ((\Limit >> 8) & 0x0F00))
.byte ((\Base >> 24) & 0xFF)
.endm
......
gdt:
GDT_DESC_NULL: SEG_DESC 0, 0, 0
GDT_DESC_C32: SEG_DESC 0, (c32len - 1), (0x9A | 0x4000)
GDT_DESC_VIDEO: SEG_DESC 0xB8000, 0xFFFF, (0x92)
定义一段宏帮助设定描述。gdt是自定义的全局描述表。
TI: 1表示此descriptor是ldt
blog comments powered by Disqus