首页 >> 编程开发 >> 其他 >> 正文

reactos操作系统实现(75)

  在引导系统后,会有一些驱动程序是由引导参数指定的,下面这个函数,就是处理引导时加载到内存里的驱动程序,实现的代码如下:

#001  VOID
#002  FASTCALL
#003  IopInitializeBootDrivers(VOID)
#004  {
#005      PLIST_ENTRY ListHead, NextEntry;
#006      PLDR_DATA_TABLE_ENTRY LdrEntry;
#007      PDEVICE_NODE DeviceNode;
#008      PDRIVER_OBJECT DriverObject;
#009      LDR_DATA_TABLE_ENTRY ModuleObject;
#010      NTSTATUS Status;
#011      UNICODE_STRING DriverName;
#012 
#013      DPRINT("IopInitializeBootDrivers()\n");
#014 

  为根设备节点IopRootDeviceNode创建一个设备节点。

#015      /* Use IopRootDeviceNode for now */
#016      Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, NULL, &DeviceNode);
#017      if (!NT_SUCCESS(Status)) return;
#018 

  设置最基本的文件系统驱动程序。

#019      /* Setup the module object for the RAW FS Driver */
#020      ModuleObject.DllBase = NULL;
#021      ModuleObject.SizeOfImage = 0;
#022      ModuleObject.EntryPoint = RawFsDriverEntry;
#023      RtlInitUnicodeString(&DriverName, L"RAW");
#024 

  初始化这个驱动程序模块。

#025      /* Initialize it */
#026      Status = IopInitializeDriverModule(DeviceNode,
#027                                         &ModuleObject,
#028                                         &DriverName,
#029                                         TRUE,
#030                                         &DriverObject);
#031      if (!NT_SUCCESS(Status))
#032      {
#033          /* Fail */
#034          IopFreeDeviceNode(DeviceNode);
#035          return;
#036      }
#037 

  关联设备驱动程序到设备节点。

#038      /* Now initialize the associated device */
#039      Status = IopInitializeDevice(DeviceNode, DriverObject);
#040      if (!NT_SUCCESS(Status))
#041      {
#042          /* Fail */
#043          IopFreeDeviceNode(DeviceNode);
#044          return;
#045      }
#046 

  开始启动这个设备,通过IRP包来通知系统,然后分配设备所需要的资源。

#047      /* Start it up */
#048      Status = IopStartDevice(DeviceNode);
#049      if (!NT_SUCCESS(Status))
#050      {
#051          /* Fail */
#052          IopFreeDeviceNode(DeviceNode);
#053          return;
#054      }
#055 

  循环地加载引导时指定的驱动程序。

#056      /* Loop the boot modules */
#057      ListHead = &KeLoaderBlock->LoadOrderListHead;
#058      NextEntry = ListHead->Flink;
#059      while (ListHead != NextEntry)
#060      {
#061          /* Get the entry */
#062          LdrEntry = CONTAINING_RECORD(NextEntry,
#063                                       LDR_DATA_TABLE_ENTRY,
#064                                       InLoadOrderLinks);
#065 
#066          /*
#067           * HACK: Make sure we're loading a driver
#068           * (we should be using BootDriverListHead!)
#069           */
#070          if (wcsstr(_wcsupr(LdrEntry->BaseDllName.Buffer), L".SYS"))
#071          {
#072              /* Make sure we didn't load this driver already */
#073              if (!(LdrEntry->Flags & LDRP_ENTRY_INSERTED))
#074              {

  循环地加载已经在内存里驱动程序,并且启动这些设备。

#075                  DPRINT("Initializing bootdriver %wZ\n", &LdrEntry->BaseDllName);
#076                  /* Initialize it */
#077                  IopInitializeBuiltinDriver(LdrEntry);
#078              }
#079          }
#080 
#081          /* Go to the next driver */
#082          NextEntry = NextEntry->Flink;
#083      }
#084 
#085      /* In old ROS, the loader list became empty after this point. Simulate. */
#086      InitializeListHead(&KeLoaderBlock->LoadOrderListHead);
#087  }