Windows NT引导过程源代码分析(3)

2019-08-30 13:20

;加载gdtr和idtr

;在这里禁用中断,因为无法在转换到保护模式之前位于实模式且idt已被载入的情况下处理中断

cli

lgdt fword ptr [_GDTregister]

lidt fword ptr [_IDTregister]

; We have to stamp the segment portion of any real-mode far pointer withthe corresponding selector values before we go protected.

mov si,offset _ScreenStart

mov word ptr [si+2],VideoSelector

mov si,offset _vp

mov word ptr [si+2],VideoSelector

; 开启保护模式和分页机制

mov eax,cr0

; 如果是第一次开启保护模式,那么无需开启分页机制,因为osloader已经做好一切

; 如果代码是返回保护模式,分页表已经设置完毕,同样无需开启

or dx,dx

jz only_prot

or eax,PROT_MODE + ENABLE_PAGING

mov cr0,eax

; 接下来代码中的JMP必须是双字对齐,为了避免触发一个i386的硬件bug

; 否则有可能使得预取队列混乱

ALIGN 4

jmp flush

only_prot:

or eax,PROT_MODE

mov cr0,eax

; 刷新预取队列

ALIGN 4

jmp flush

flush:

; 将寄存器CS作为SU模块的代码选择子

push SuCodeSelector

push offset cs:restart

retf

; 将寄存器DS和SS作为SU模块的保护模式数据选择子.

restart:

mov ax,SuDataSelector

mov ds,ax

mov ss,ax

; 加载LDT为0,因为从未被使用.

xor bx,bx

lldt bx

; 加载任务寄存器

or dx,dx

jnz epp10

mov bx,TSS_Selector

ltr bx

epp10:

ret;返回之后介绍的su.asm中的模块

_EnableProtectPaging endp

… …

public _RealMode

_RealMode proc near

; 转换到实模式

sgdt fword ptr [_GDTregister]

sidt fword ptr [_IDTregister]

push [saveDS] ; 将saveDS入栈,方便之后的跳转

mov ax,SuDataSelector

mov es,ax

mov fs,ax

mov gs,ax

mov eax,cr0

and eax, not (ENABLE_PAGING + PROT_MODE)

mov cr0,eax

; 刷新流水线

jmp far ptr here

here:

; Flush TLB

; We don't know where the page directory is, since it wasallocated in the osloader.

; So we don't want to clear out cr3,but we DO want to flush the TLB....

mov eax,cr3

nop ; Fill - Ensure 13 non-page split

nop ; accesses before CR3 load

nop

nop

mov cr3,eax

; 转换为实模式地址

; 此处需要一个远跳转而不是指令retf,因为retf不能正确地重置访问权限为CS

db 0EAh ; JMP FAR PTR

dw offset _TEXT:rmode ; 2000:rmode

dw 02000h

rmode:

pop ax

mov ds,ax

mov ss,ax

; Stamp video pointers for real-mode use

mov si,offset _ScreenStart

mov word ptr [si+2],0b800h

mov si,offset _vp

mov word ptr [si+2],0b800h

lidt fword ptr [_IDTregisterZero]

sti

ret

_RealMode endp

Ntldr 的实模式代码首先获得控制,它的任务是,完成需在16 位模式下执行的初始化工作,例如清除键盘缓冲区,然后为切换到保护模式做好基本的环境准备,之后将处理器切换到保护模式(32 位模式)下,这样它就可以访问整个32 位地址空间了。最后它将控制权交给os loader。

; _TransferToLoader ;该子程序将控制权交给osloader

public _TransferToLoader

_TransferToLoader proc near

mov ebx,dword ptr [esp+2] ; 获取入口点参数

xor eax,eax

mov ax,[saveDS]

; 设置osloader的堆栈

mov cx,KeDataSelector

mov ss,cx

mov esp,LOADER_STACK

; 加载ds和es作为内核数据选择子

mov ds,cx

mov es,cx

; 设置指向文件系统和引导上下文记录的指针

shl eax,4

xor ecx,ecx

mov cx,offset _BootRecord

add eax,ecx

push eax

push 1010h ; 压入假的返回地址

; 将一个48位的地址传给loader的入口点

db OVERRIDE

push KeCodeSelector

push ebx

; 将控制权交还OS loader

db OVERRIDE

retf

_TransferToLoader endp


Windows NT引导过程源代码分析(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:重庆一中高2009级(下)09年文科数学2月月考试题 doc

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: