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

2019-08-30 13:20

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();

if (!ConstructMemoryDescriptors()) {

if (MachineType == MACHINE_TYPE_EISA) { IsaNumPages = IsaConstructMemoryDescriptors(); EisaNumPages = EisaConstructMemoryDescriptors(); if (EisaNumPages + 0x80

if (MachineType == MACHINE_TYPE_MCA) { McaConstructMemoryDescriptors(); } else {

IsaConstructMemoryDescriptors(); } }

}

// 搜索内存描述符来表示低内存 CurrentEntry = MemoryDescriptorList; while ((CurrentEntry->BlockBase != 0) && (CurrentEntry->BlockSize != 0)) { CurrentEntry++; }

if ((CurrentEntry->BlockBase == 0) &&

(CurrentEntry->BlockSize< (ULONG)512 * (ULONG)1024)) {

BlPrint(SU_NO_LOW_MEMORY,CurrentEntry->BlockSize/1024); while (1) { }

}

// 确保osloader映像文件包含一个内存描述符

OptionalHeader = (PIMAGE_OPTIONAL_HEADER)((PUCHAR)&edata + sizeof(IMAGE_FILE_HEADER)); ImageBase = OptionalHeader->ImageBase; ImageSize = OptionalHeader->SizeOfImage; OsLoaderBase = ImageBase;

OsLoaderExports = ImageBase + OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; CurrentEntry = MemoryDescriptorList; while (ImageSize> 0) {

while (CurrentEntry->BlockSize != 0) {

BlockEnd = CurrentEntry->BlockBase + CurrentEntry->BlockSize;

if ((CurrentEntry->BlockBase<= ImageBase) && (BlockEnd>ImageBase)) {

// 该描述符至少得包含osloader的一部分代码 if (BlockEnd-ImageBase>ImageSize) { ImageSize = 0;

} else {

ImageSize -= (BlockEnd-ImageBase); ImageBase = BlockEnd; } // 寻找剩余一部分的代码

CurrentEntry = MemoryDescriptorList; break; } CurrentEntry++; }

if (CurrentEntry->BlockSize == 0) { break; } }

if (ImageSize> 0) {

// 不能将osloader重定位到高内存位置,否则输出错误信息 BlPrint(SU_NO_EXTENDED_MEMORY);

CurrentEntry = MemoryDescriptorList; while (CurrentEntry->BlockSize != 0) { BlPrint(\ %lx - %lx\\n\, CurrentEntry->BlockBase,

CurrentEntry->BlockBase + CurrentEntry->BlockSize);

CurrentEntry++; } while (1) { } }

// 启用A20线 EnableA20();

// 重定位保护模式中使用的IDT和GDT结构 Relocatex86Structures();

// 首次开启保护模式和分页模式 EnableProtectPaging(ENABLING);

// 重定位代码段并建立页面表项

LoaderEntryPoint = RelocateLoaderSections(&OsLoaderStart, &OsLoaderEnd);

// 将控制权交给OS loader TransferToLoader(LoaderEntryPoint);

}

VOID

NtProcessStartup(

INPBOOT_CONTEXTBootContextRecord ) /*++

Routine Description:

Main entry point for setup loader. Control is transferred here by the start-up (SU) module. Arguments:

BootContextRecord - Supplies the boot context, particularly the ExternalServicesTable. Returns:

Does not return. Control eventually passed to the kernel. --*/ {

ARC_STATUSStatus;

// 初始化引导加载器的显示功能

DoGlobalInitialization(BootContextRecord);

BlFillInSystemParameters(BootContextRecord);

if (BootContextRecord->FSContextPointer->BootDrive == 0) {

// 从磁盘A:开始尝试引导

strcpy(BootPartitionName,\);

GET_SECTOR(0,0,0,0,0,0,NULL);

#ifdefined(ELTORITO)

} elseif (BlIsElToritoCDBoot(BootContextRecord->FSContextPointer->BootDrive)) {

// 从CD开始尝试引导

sprintf(BootPartitionName, \, BootContextRecord->FSContextPointer->BootDrive); ElToritoCDBoot = TRUE; #endif

} else {

//检查引导成功的分区是哪一个

BlGetActivePartition(BootPartitionName);

}

// 初始化内存描述符列表,OS loader的堆和参数块 Status = BlMemoryInitialize(); if (Status != ESUCCESS) {

BlPrint(\); while (1) { } }

// 初始化OS loader和I/O系统 Status = BlIoInitialize(); if (Status != ESUCCESS) {

BlPrint(\); }

BlStartup(BootPartitionName);

// 永远不应该运行到这里! do { GET_KEY(); } while ( 1 ); }

BOOLEAN

BlDetectHardware( INULONGDriveId, INPCHARLoadOptions ) /*++

Routine Description:

Loads and runs NTDETECT.COM to populate the ARC configuration tree. NTDETECT is assumed to reside in the root directory.

Arguments:

DriveId - Supplies drive id where NTDETECT is located. LoadOptions - Supplies Load Options string to ntdetect.

Return Value:

TRUE - NTDETECT successfully run. FALSE - Error --*/ {

ARC_STATUSStatus;

PCONFIGURATION_COMPONENT_DATATempFwTree; ULONGTempFwHeapUsed;

externBOOLEANFwDescriptorsValid; ULONGFileSize; ULONGDetectFileId;

FILE_INFORMATIONFileInformation; PUCHARDetectionBuffer; PUCHAROptions; UCHARBuffer[100];

LARGE_INTEGERSeekPosition; ULONGRead;

// 检查在根目录下是否存在文件ntdetect.com,如果有的话就将其加载到预定义的位置并将控制权转交给他

#ifdefined(ELTORITO) if (ElToritoCDBoot) {

// 假设ntdetect.com在i386目录下 Status = BlOpen( DriveId, \, ArcOpenReadOnly, &DetectFileId ); } else { #endif

Status = BlOpen( DriveId, \, ArcOpenReadOnly, &DetectFileId ); #ifdefined(ELTORITO) } #endif

DetectionBuffer = (PUCHAR)DETECTION_LOADED_ADDRESS;

if (Status != ESUCCESS) { #ifDBG

BlPrint(\, Status); BlPrint(\); while (!GET_KEY()) { } #endif return(FALSE); }


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

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

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

马上注册会员

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