分类: LINUX
2010-10-08 18:14:38
来自《自己动手写操作系统》第三章的感悟
在操作系统进入保护模式前(即实模式)先建立描述符表(全局的吧)
在其中创建多个描述符(每个描述符占8个字节,如图3-2),并把重要的内存段基地址赋给某个描述符的段地址部分(例如显存:首地址B8000h, 界限ffffh, 属性DA_DRW,首地址在描述符里实质储存为000B8000h(物理地址))。或者为某程序创建程序段的段描述符。
然后创建和gtr寄存器格式一样的变量:
GdtPtr dw xxxxh ; GDT界限,16位, word ptr [GdtPtr]=xxxxh
dd xxxxxxxxh ; GDT基地址,32位(物理地址),dword ptr [GdtPtr+2]=xxxxxxxxh
使用汇编语言:lgdt [GdtPtr] 把gtr寄存器改为我们要的GdtPtr的值。
然后使用以下语句切换到保护模式:
; 打开地址线A20
in al, 92h
or al, 00000010b
out 92h, al
; 准备切换到保护模式
mov eax, cr0
or eax, 1
mov cr0, eax
现在已经进入保护模式了。当要访问第n个段时(n从0开始),可以把某个段寄存器设为n*8,例如:把cs设置为8,因为我们已经指定GDT基地址为[GdtPtr+2],那么计算机就会自动查找[GdtPtr+2]+8(第1号描述符,每个描述符占8个字节)处的描述符,并重新定位到第1号描述符的段地址部分指向的位置。即如果第1号描述符的段地址部分的值为addr,那么使用jmp 8h:0h语句,程序就会跳到addr处的0h偏移的内存处。
但是逻辑地址应该还是8h而不是addr,因为程序员编写是不会知道addr的值。
保护模式下只能用32位汇编,不能用16位汇编。
-------------------------------------------------------------------------------
其中描述符结构如下: