reactos操作系统实现(49)
前面已经介绍怎么样从ISOBOOT里加载SETUPLDR.SYS,下面来分析一下这个程序与一般硬盘引导程序freeldr.sys有什么区别。 在文件freeldr.c里是这样这样调用安装函数的: #001 VOID BootMain(LPSTR CmdLine) #002 { #003 CmdLineParse(CmdLine); #004 #005 MachInit(CmdLine); #006 #007 DebugInit(); #008 #009 DbgPrint((DPRINT_WARNING,"BootMain() called./n")); #010 #011 if (!UiInitialize(FALSE)) #012 { #013 UiMessageBoxCritical("Unable to initialize UI./n"); #014 return; #015 } #016 #017 if (!MmInitializeMemoryManager()) #018 { #019 UiMessageBoxCritical("Unable to initialize memory manager"); #020 return; #021 } #022 #023 RunLoader(); #024 }
通过上面的函数,然后就调用文件bootmgr.c里的函数RunLoader(),如下: #001 VOID RunLoader(VOID) #002 { ...... #098 #ifdef FREELDR_REACTOS_SETUP #099 else if (_stricmp(SettingValue,"ReactOSSetup") == 0) #100 { #101 // In future we could pass the selected OS details through this #102 // to have different install methods,etc. #103 LoadReactOSSetup(); #104 } #105 #endif ...... #143 #144 reboot: #145 UiUnInitialize("Rebooting..."); #146 return; #147 }
上面函数调用LoadReactOSSetup函数来加载与一般硬盘引导不一样的代码。而这个函数的代码是在文件setupldr.c里,如下: #001 VOID LoadReactOSSetup(VOID) #002 { #003 ULONG i; #004 LPCSTR SourcePath; #005 LPCSTR LoadOptions,DbgLoadOptions = ""; #006 LPCSTR sourcePaths[] = { #007 "",/* Only for floppy boot */ #008 #if defined(_M_IX86) #009 "//I386", #010 #elif defined(_M_MPPC) #011 "//PPC", #012 #elif defined(_M_MRX000) #013 "//MIPS", #014 #endif
缺省安装的目录。 #015 "//reactos", #016 NULL }; #017 CHAR FileName[256]; #018 #019 HINF InfHandle; #020 ULONG ErrorLine; #021 INFCONTEXT InfContext; #022 PIMAGE_NT_HEADERS NtHeader; #023 PVOID LoadBase; #024
设置多重引导的系统信息。 #025 /* Setup multiboot information structure */ #026 LoaderBlock.CommandLine = reactos_kernel_cmdline; #027 LoaderBlock.PageDirectoryStart = (ULONG_PTR)&PageDirectoryStart; #028 LoaderBlock.PageDirectoryEnd = (ULONG_PTR)&PageDirectoryEnd; #029 LoaderBlock.ModsCount = 0; #030 LoaderBlock.ModsAddr = reactos_modules; #031 LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map,32) * sizeof(memory_map_t); #032 if (LoaderBlock.MmapLength) #033 { #034 #if defined (_M_IX86) || defined (_M_AMD64) #035 ULONG i; #036 #endif #037 LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO; #038 LoaderBlock.MmapAddr = (ULONG_PTR)&reactos_memory_map; #039 reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24 #040 #if defined (_M_IX86) || defined (_M_AMD64) #041 for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++) #042 { #043 if (BiosMemoryUsable == reactos_memory_map[i].type && #044 0 == reactos_memory_map[i].base_addr_low) #045 { #046 LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024; #047 if (640 < LoaderBlock.MemLower) #048 { #049 LoaderBlock.MemLower = 640; #050 } #051 } #052 if (BiosMemoryUsable == reactos_memory_map[i].type && #053 reactos_memory_map[i].base_addr_low <= 1024 * 1024 && #054 1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) #055 { #056 LoaderBlock.MemHigher = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024 - 1024; #057 } #058 } #059 #endif #060 } #061 #062 #ifdef USE_UI #063 SetupUiInitialize(); #064 #endif #065 UiDrawStatusText(""); #066 #067 extern BOOLEAN FrLdrBootType; #068 FrLdrBootType = TRUE; #069
检测安装电脑的硬件。 #070 /* Detect hardware */ #071 UiDrawStatusText("Detecting hardware..."); #072 LoaderBlock.ArchExtra = (ULONG_PTR)MachHwDetect(); #073 UiDrawStatusText(""); #074
设置引导的设备。 #075 /* set boot device */ #076 MachDiskGetBootDevice(&LoaderBlock.BootDevice); #077 #078 /* Open boot drive */ #079 if (!FsOpenBootVolume()) #080 { #081 UiMessageBox("Failed to open boot drive."); #082 return; #083 } #084
加载显示的SIF文件。 #085 UiDrawStatusText("Loading txtsetup.sif..."); #086 /* Open 'txtsetup.sif' */ #087 for (i = MachDiskBootingFromFloppy() ? 0 : 1; ; i++) #088 { #089 SourcePath = sourcePaths[i]; #090 if (!SourcePath) #091 { #092 printf("Failed to open 'txtsetup.sif'/n"); #093 return; #094 } #095 sprintf(FileName,"%s//txtsetup.sif",SourcePath); #096 if (InfOpenFile (&InfHandle,FileName,&ErrorLine)) #097 break; #098 } #099 if (!*SourcePath) #100 SourcePath = "//"; #101 #102 #ifdef DBG #103 /* Get load options */ #104 if (InfFindFirstLine (InfHandle, #105 "SetupData", #106 "DbgOsLoadOptions", #107 &InfContext)) #108 { #109 if (!InfGetDataField (&InfContext,1,&DbgLoadOptions)) #110 DbgLoadOptions = ""; #111 } #112 #endif #113 if (!strlen(DbgLoadOptions) && !InfFindFirstLine (InfHandle, #114 "SetupData", #115 "OsLoadOptions", #116 &InfContext)) #117 { #118 printf("Failed to find 'SetupData/OsLoadOptions'/n"); #119 return; #120 } #121 #122 if (!InfGetDataField (&InfContext, #123 1, #124 &LoadOptions)) #125 { #126 printf("Failed to get load options/n"); #127 return; #128 } #129
设置内核的命令行参数。 #130 /* Set kernel command line */ #131 MachDiskGetBootPath(reactos_kernel_cmdline,sizeof(reactos_kernel_cmdline)); #132 strcat(strcat(strcat(strcat(reactos_kernel_cmdline,SourcePath)," "), #133 LoadOptions),DbgLoadOptions); #134
设置引导的路径和内核。 #135 /* Setup the boot path and kernel path */ #136 strcpy(szBootPath,SourcePath); #137 #138 sprintf(SystemRoot,"%s//",SourcePath); #139 sprintf(FileName,"%s//ntoskrnl.exe",SourcePath); #140 sprintf(szHalName,"%s//hal.dll",SourcePath); #141
加载内核和硬件抽象层。 #142 /* Load the kernel */ #143 LoadBase = FrLdrLoadImage(FileName,5,1); #144 if (!LoadBase) return; #145 #146 /* Get the NT header,kernel base and kernel entry */ #147 NtHeader = RtlImageNtHeader(LoadBase); #148 KernelBase = SWAPD(NtHeader->OptionalHeader.ImageBase); #149 KernelEntryPoint = (ROS_KERNEL_ENTRY_POINT)(KernelBase + SWAPD(NtHeader->OptionalHeader.AddressOfEntryPoint)); #150 LoaderBlock.KernelBase = KernelBase; #151 #152 /* Insert boot disk 2 */ #153 if (MachDiskBootingFromFloppy()) #154 { #155 UiMessageBox("Please insert /"ReactOS Boot Disk 2/" and press ENTER"); #156 #157 /* Open boot drive */ #158 if (!FsOpenBootVolume()) #159 { #160 UiMessageBox("Failed to open boot drive."); #161 return; #162 } #163 #164 /* FIXME: check volume label or disk marker file */ #165 } #166 #167
获取ANSI的代码表文件。 #168 /* Get ANSI codepage file */ #169 if (!InfFindFirstLine (InfHandle, #170 "NLS", #171 "AnsiCodepage", #172 &InfContext)) #173 { #174 printf("Failed to find 'NLS/AnsiCodepage'/n"); #175 return; #176 } #177 #178 if (!InfGetDataField (&InfContext, #179 1, #180 &LoadOptions)) #181 { #182 printf("Failed to get load options/n"); #183 return; #184 } #185 #186 sprintf(FileName,"%s//%s",SourcePath,LoadOptions); #187 /* Load ANSI codepage file */ #188 if (!FrLdrLoadNlsFile(FileName,"ansi.nls")) #189 { #190 UiMessageBox("Failed to load the ANSI codepage file."); #191 return; #192 } #193 #194 /* Get OEM codepage file */ #195 if (!InfFindFirstLine (InfHandle, #196 "NLS", #197 "OemCodepage", #198 &InfContext)) #199 { #200 printf("Failed to find 'NLS/AnsiCodepage'/n"); #201 return; #202 } #203 #204 if (!InfGetDataField (&InfContext, #205 1, #206 &LoadOptions)) #207 { #208 printf("Failed to get load options/n"); #209 return; #210 } #211 #212 sprintf(FileName,LoadOptions); #213 /* Load OEM codepage file */ #214 if (!FrLdrLoadNlsFile(FileName,"oem.nls")) #215 { #216 UiMessageBox("Failed to load the OEM codepage file."); #217 return; #218 } #219 #220 /* Get Unicode Casemap file */ #221 if (!InfFindFirstLine (InfHandle, #222 "NLS", #223 "UnicodeCasetable", #224 &InfContext)) #225 { #226 printf("Failed to find 'NLS/AnsiCodepage'/n"); #227 return; #228 } #229 #230 if (!InfGetDataField (&InfContext, #231 1, #232 &LoadOptions)) #233 { #234 printf("Failed to get load options/n"); #235 return; #236 } #237 #238 sprintf(FileName,LoadOptions); #239 /* Load Unicode casemap file */ #240 if (!FrLdrLoadNlsFile(FileName,"casemap.nls")) #241 { #242 UiMessageBox("Failed to load the Unicode casemap file."); #243 return; #244 } #245 #246 /* Load additional files specified in txtsetup.inf */ #247 if (InfFindFirstLine(InfHandle, #248 "SourceDisksFiles", #249 NULL, #250 &InfContext)) #251 { #252 do #253 { #254 LPCSTR Media,DriverName; #255 if (InfGetDataField(&InfContext,7,&Media) && #256 InfGetDataField(&InfContext,&DriverName)) #257 { #258 if (strcmp(Media,"x") == 0) #259 { #260 if (!FrLdrLoadDriver((PCHAR)DriverName,0)) #261 return; #262 } #263 } #264 } while (InfFindNextLine(&InfContext,&InfContext)); #265 } #266
显示开始引导ReactOS。 #267 UiUnInitialize("Booting ReactOS..."); #268 #269 #270 // #271 // Perform architecture-specific pre-boot configuration #272 // #273 MachPrepareForReactOS(TRUE); #274
这里跳到内核代码执行。 #275 // #276 // Setup paging and jump to kernel #277 // #278 FrLdrStartup(0x2badb002); #279 }
后面加载函数FrLdrStartup,与最前面讨论的引导是一样功能了,最后就跳到ntoskrnl.exe文件里执行内核代码了。在内核里,也有一些跟安装有关系的配置,主要就是在内存里创建虚拟磁盘。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |