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,"%s//%s", SourcePath,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,"%s//%s", SourcePath,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, 0, &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文件里执行内核代码了。在内核里,也有一些跟安装有关系的配置,主要就是在内存里创建虚拟磁盘。

你可能感兴趣的:(react)