当前位置:首页 > Windows NT引导过程源代码分析
… …
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
Os loader 刚接获控制时,处理器虽然已经工作在保护模式下,但是它的虚拟地址转译机制尚未开启,所以,处理器仍然直接使用物理地址。Os loader 首先做的工作是把物理内存管起来,用一个内存描述符(memory descriptor)数组把每一段内存的大小和用途记录下来,然后构造页目录和页表,使得16 MB 以下的内存能够通过页面映射(paging)机制进行访问,再设置好页目录寄存器,并打开页面映射机制。之后,os loader 继续执行其他的初始化工作,包括I/O 设备的初始化等。如果它还需要调用BIOS 中的服务(比如中断13h、中断15h 等),则必须保护好保护模式下的设置,并暂时切换回到实模式,待服务完成以后再切换到保护模式,并恢复设置。
Windows 的引导选项可以用来指示当前这次引导的各种参数,包括内核模块的文件名称、HAL 的文件名称、CPU 参数、各种内存参数、调试参数,等等。关于这些引导选项的全面列表和介绍,可参考[MSDN-BOOT]。接下来os loader 加载并执行NTDETECT.COM 程序,这是一个16 位实模式程序,它利用系统的BIOS 来查询系统的基本设备和配置信息,包括系统的日期和时间、总线的类型、磁盘的信息、输入/输出的接口信息等。这些信息被收集起来,在引导过程的后期被存放到注册表HKLM\\HARDWARE\\DESCRIPTION 键的下面。
代码摘自\\ntos\\boot\\startup\\i386\\main.c VOID SuMain(
INFPVOIDBtRootDir, INFPDISKBPBBtBiosBlock, INSHORTBtBootDrive ) /*++
Routine Description:
Main entrypoint of the SU module. Control is passed from the boot sector to startup.asm which does some run-time fixups on the stack and data segments and then passes control here. Arguments:
BtRootDir - Address of root directory left in memory by boot sector BtBiosBlock - Address of bios parameter block. BtBootDrive - Drive that we booted from. Returns:
Does not return. Passes control to the OS loader --*/ {
ULONGLoaderEntryPoint; ULONGEisaNumPages; USHORTIsaNumPages;
MEMORY_LIST_ENTRY_far *CurrentEntry; PIMAGE_OPTIONAL_HEADEROptionalHeader; ULONGBlockEnd; ULONGImageSize; ULONGImageBase;
// 保存文件系统上下文信息
FsContext.BootDrive = (ULONG)BtBootDrive;
FsContext.PointerToBPB = MAKE_FLAT_ADDRESS(BtBiosBlock);
PatchDiskBaseTable();
// 基于总线类型设置机器类型. if (BtIsEisaSystem()) {
MachineType = MACHINE_TYPE_EISA; } else {
if (BtIsMcaSystem()) {
MachineType = MACHINE_TYPE_MCA; } else {
MachineType = MACHINE_TYPE_ISA; }
}
// 如果系统由软盘引导,那么关掉软盘驱动器 TurnMotorOff();
// 初始化视频子系统以使得错误和异常信息可以被显示 InitializeVideoSubSystem();
共分享92篇相关文档