init.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073
  1. /*++
  2. Copyright (c) 2012 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. init.c
  5. Abstract:
  6. This module contains code to initialize the I/O subsystem.
  7. Author:
  8. Evan Green 16-Sep-2012
  9. Environment:
  10. Kernel
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <minoca/kernel/kernel.h>
  16. #include <minoca/kernel/bootload.h>
  17. #include <minoca/lib/bconf.h>
  18. #include "iop.h"
  19. #include "pagecach.h"
  20. //
  21. // ---------------------------------------------------------------- Definitions
  22. //
  23. //
  24. // ------------------------------------------------------ Data Type Definitions
  25. //
  26. /*++
  27. Structure Description:
  28. This structure defines the iteration context that initializes the physical
  29. address space arbiter.
  30. Members:
  31. PreviousEnd - Stores the end of the previous descriptor.
  32. Status - Stores the final status code.
  33. --*/
  34. typedef struct _IO_INIT_PHYSICAL_MAP_ITERATOR {
  35. ULONGLONG PreviousEnd;
  36. KSTATUS Status;
  37. } IO_INIT_PHYSICAL_MAP_ITERATOR, *PIO_INIT_PHYSICAL_MAP_ITERATOR;
  38. //
  39. // ----------------------------------------------- Internal Function Prototypes
  40. //
  41. KSTATUS
  42. IopInitializeDeviceSupport (
  43. VOID
  44. );
  45. KSTATUS
  46. IopInitializeResourceAllocation (
  47. PKERNEL_INITIALIZATION_BLOCK Parameters
  48. );
  49. KSTATUS
  50. IopInitializeBootDrivers (
  51. PKERNEL_INITIALIZATION_BLOCK Parameters
  52. );
  53. KSTATUS
  54. IopInitializeDeviceDatabase (
  55. PKERNEL_INITIALIZATION_BLOCK Parameters
  56. );
  57. KSTATUS
  58. IopCreateBootDevices (
  59. PKERNEL_INITIALIZATION_BLOCK Parameters
  60. );
  61. VOID
  62. IopInitializePhysicalAddressArbiterIterator (
  63. PMEMORY_DESCRIPTOR_LIST DescriptorList,
  64. PMEMORY_DESCRIPTOR Descriptor,
  65. PVOID Context
  66. );
  67. //
  68. // -------------------------------------------------------------------- Globals
  69. //
  70. //
  71. // ------------------------------------------------------------------ Functions
  72. //
  73. KSTATUS
  74. IoInitialize (
  75. ULONG Phase,
  76. PKERNEL_INITIALIZATION_BLOCK Parameters
  77. )
  78. /*++
  79. Routine Description:
  80. This routine initializes the I/O subsystem.
  81. Arguments:
  82. Phase - Supplies the initialization phase.
  83. Parameters - Supplies a pointer to the kernel's initialization information.
  84. Return Value:
  85. Status code.
  86. --*/
  87. {
  88. PBOOT_ENTRY BootEntry;
  89. ULONG Flags;
  90. KSTATUS Status;
  91. UINTN SystemDirectorySize;
  92. INITIALIZE_LIST_HEAD(&IoDeviceList);
  93. IoDeviceListLock = KeCreateQueuedLock();
  94. if (IoDeviceListLock == NULL) {
  95. Status = STATUS_INSUFFICIENT_RESOURCES;
  96. goto InitializeEnd;
  97. }
  98. //
  99. // Copy the boot information over.
  100. //
  101. if (Parameters->BootEntry != NULL) {
  102. BootEntry = Parameters->BootEntry;
  103. ASSERT((sizeof(IoBootInformation.SystemDiskIdentifier) ==
  104. sizeof(BootEntry->DiskId)) &&
  105. (sizeof(IoBootInformation.SystemPartitionIdentifier) ==
  106. sizeof(BootEntry->PartitionId)));
  107. RtlCopyMemory(&(IoBootInformation.SystemDiskIdentifier),
  108. &(BootEntry->DiskId),
  109. sizeof(IoBootInformation.SystemDiskIdentifier));
  110. RtlCopyMemory(&(IoBootInformation.SystemPartitionIdentifier),
  111. &(BootEntry->PartitionId),
  112. sizeof(IoBootInformation.SystemPartitionIdentifier));
  113. //
  114. // Copy the system directory path.
  115. //
  116. if (BootEntry->SystemPath != NULL) {
  117. SystemDirectorySize = RtlStringLength(BootEntry->SystemPath) + 1;
  118. IoSystemDirectoryPath = MmAllocateNonPagedPool(SystemDirectorySize,
  119. IO_ALLOCATION_TAG);
  120. if (IoSystemDirectoryPath == NULL) {
  121. Status = STATUS_INSUFFICIENT_RESOURCES;
  122. goto InitializeEnd;
  123. }
  124. RtlStringCopy(IoSystemDirectoryPath,
  125. BootEntry->SystemPath,
  126. SystemDirectorySize);
  127. }
  128. }
  129. RtlCopyMemory(&(IoBootInformation.BootTime),
  130. &(Parameters->BootTime),
  131. sizeof(SYSTEM_TIME));
  132. //
  133. // Create the Interfaces object directory.
  134. //
  135. IoInterfaceDirectory = ObCreateObject(ObjectDirectory,
  136. NULL,
  137. "Interface",
  138. sizeof("Interface"),
  139. sizeof(OBJECT_HEADER),
  140. NULL,
  141. OBJECT_FLAG_USE_NAME_DIRECTLY,
  142. IO_ALLOCATION_TAG);
  143. if (IoInterfaceDirectory == NULL) {
  144. Status = STATUS_INSUFFICIENT_RESOURCES;
  145. goto InitializeEnd;
  146. }
  147. IoInterfaceLock = KeCreateQueuedLock();
  148. if (IoInterfaceLock == NULL) {
  149. Status = STATUS_INSUFFICIENT_RESOURCES;
  150. goto InitializeEnd;
  151. }
  152. //
  153. // Create the IRP directory.
  154. //
  155. IoIrpDirectory = ObCreateObject(ObjectDirectory,
  156. NULL,
  157. "Irp",
  158. sizeof("Irp"),
  159. sizeof(OBJECT_HEADER),
  160. NULL,
  161. OBJECT_FLAG_USE_NAME_DIRECTLY,
  162. IO_ALLOCATION_TAG);
  163. if (IoIrpDirectory == NULL) {
  164. Status = STATUS_INSUFFICIENT_RESOURCES;
  165. goto InitializeEnd;
  166. }
  167. //
  168. // Create the pipe directory.
  169. //
  170. IoPipeDirectory = ObCreateObject(ObjectDirectory,
  171. NULL,
  172. "Pipe",
  173. sizeof("Pipe"),
  174. sizeof(OBJECT_HEADER),
  175. NULL,
  176. OBJECT_FLAG_USE_NAME_DIRECTLY,
  177. FI_ALLOCATION_TAG);
  178. if (IoPipeDirectory == NULL) {
  179. Status = STATUS_INSUFFICIENT_RESOURCES;
  180. goto InitializeEnd;
  181. }
  182. //
  183. // Create the shared memory object directory.
  184. //
  185. IoSharedMemoryObjectDirectory = ObCreateObject(
  186. ObjectDirectory,
  187. NULL,
  188. "SharedMemoryObjects",
  189. sizeof("SharedMemoryObjects"),
  190. sizeof(OBJECT_HEADER),
  191. NULL,
  192. OBJECT_FLAG_USE_NAME_DIRECTLY,
  193. FI_ALLOCATION_TAG);
  194. if (IoSharedMemoryObjectDirectory == NULL) {
  195. Status = STATUS_INSUFFICIENT_RESOURCES;
  196. goto InitializeEnd;
  197. }
  198. //
  199. // Initialize the file system list head and create the lock protecting
  200. // access to it.
  201. //
  202. INITIALIZE_LIST_HEAD(&IoFileSystemList);
  203. IoFileSystemListLock = KeCreateQueuedLock();
  204. if (IoFileSystemListLock == NULL) {
  205. Status = STATUS_INSUFFICIENT_RESOURCES;
  206. goto InitializeEnd;
  207. }
  208. //
  209. // Create the volume directory.
  210. //
  211. Flags = OBJECT_FLAG_USE_NAME_DIRECTLY;
  212. IoVolumeDirectory = ObCreateObject(ObjectDirectory,
  213. NULL,
  214. "Volume",
  215. sizeof("Volume"),
  216. sizeof(OBJECT_HEADER),
  217. NULL,
  218. Flags,
  219. FI_ALLOCATION_TAG);
  220. if (IoVolumeDirectory == NULL) {
  221. Status = STATUS_INSUFFICIENT_RESOURCES;
  222. goto InitializeEnd;
  223. }
  224. //
  225. // Initialize support for device information requests.
  226. //
  227. Status = IopInitializeDeviceInformationSupport();
  228. if (!KSUCCESS(Status)) {
  229. goto InitializeEnd;
  230. }
  231. //
  232. // Initialize support for file objects.
  233. //
  234. Status = IopInitializeFileObjectSupport();
  235. if (!KSUCCESS(Status)) {
  236. goto InitializeEnd;
  237. }
  238. //
  239. // Initialize support for path traversal.
  240. //
  241. Status = IopInitializePathSupport();
  242. if (!KSUCCESS(Status)) {
  243. goto InitializeEnd;
  244. }
  245. //
  246. // Initialize support for mount points.
  247. //
  248. Status = IopInitializeMountPointSupport();
  249. if (!KSUCCESS(Status)) {
  250. goto InitializeEnd;
  251. }
  252. //
  253. // Initialize support for the page cache.
  254. //
  255. Status = IopInitializePageCache();
  256. if (!KSUCCESS(Status)) {
  257. goto InitializeEnd;
  258. }
  259. //
  260. // Initialize support for terminals.
  261. //
  262. Status = IopInitializeTerminalSupport();
  263. if (!KSUCCESS(Status)) {
  264. goto InitializeEnd;
  265. }
  266. //
  267. // Initialize the device database.
  268. //
  269. Status = IopInitializeDeviceDatabase(Parameters);
  270. if (!KSUCCESS(Status)) {
  271. goto InitializeEnd;
  272. }
  273. Status = IopInitializeDeviceSupport();
  274. if (!KSUCCESS(Status)) {
  275. goto InitializeEnd;
  276. }
  277. //
  278. // Initialize support for resource allocation.
  279. //
  280. Status = IopInitializeResourceAllocation(Parameters);
  281. if (!KSUCCESS(Status)) {
  282. goto InitializeEnd;
  283. }
  284. //
  285. // Load all boot drivers and call their entry routines.
  286. //
  287. Status = IopInitializeBootDrivers(Parameters);
  288. if (!KSUCCESS(Status)) {
  289. goto InitializeEnd;
  290. }
  291. //
  292. // Create the base devices described in the device map.
  293. //
  294. Status = IopCreateBootDevices(Parameters);
  295. if (!KSUCCESS(Status)) {
  296. goto InitializeEnd;
  297. }
  298. //
  299. // Fire up power management.
  300. //
  301. Status = PmInitializeLibrary();
  302. if (!KSUCCESS(Status)) {
  303. goto InitializeEnd;
  304. }
  305. InitializeEnd:
  306. return Status;
  307. }
  308. //
  309. // --------------------------------------------------------- Internal Functions
  310. //
  311. KSTATUS
  312. IopInitializeDeviceSupport (
  313. VOID
  314. )
  315. /*++
  316. Routine Description:
  317. This routine initializes support for devices.
  318. Arguments:
  319. None.
  320. Return Value:
  321. Status code.
  322. --*/
  323. {
  324. KSTATUS Status;
  325. ULONG WorkQueueFlags;
  326. WorkQueueFlags = WORK_QUEUE_FLAG_SUPPORT_DISPATCH_LEVEL;
  327. IoDeviceWorkQueue = KeCreateWorkQueue(WorkQueueFlags, "IoDeviceWorker");
  328. if (IoDeviceWorkQueue == NULL) {
  329. Status = STATUS_INSUFFICIENT_RESOURCES;
  330. goto InitializeDeviceSupportEnd;
  331. }
  332. //
  333. // Create and initialize the root device.
  334. //
  335. Status = IoCreateDevice(NULL,
  336. NULL,
  337. NULL,
  338. "Device",
  339. NULL,
  340. NULL,
  341. &IoRootDevice);
  342. if (!KSUCCESS(Status)) {
  343. goto InitializeDeviceSupportEnd;
  344. }
  345. ASSERT(IoRootDevice != NULL);
  346. InitializeDeviceSupportEnd:
  347. return Status;
  348. }
  349. KSTATUS
  350. IopInitializeResourceAllocation (
  351. PKERNEL_INITIALIZATION_BLOCK Parameters
  352. )
  353. /*++
  354. Routine Description:
  355. This routine initializes support for device resource allocation.
  356. Arguments:
  357. Parameters - Supplies a pointer to the kernel initialization block.
  358. Return Value:
  359. Status code.
  360. --*/
  361. {
  362. IO_INIT_PHYSICAL_MAP_ITERATOR Context;
  363. KSTATUS Status;
  364. //
  365. // Create the physical address arbiter.
  366. //
  367. Status = IoCreateResourceArbiter(IoRootDevice,
  368. ResourceTypePhysicalAddressSpace);
  369. if (!KSUCCESS(Status)) {
  370. goto InitializeResourceAllocationEnd;
  371. }
  372. //
  373. // Loop through the physical memory descriptor list looking for holes, and
  374. // add those holes as allocatable regions.
  375. //
  376. RtlZeroMemory(&Context, sizeof(IO_INIT_PHYSICAL_MAP_ITERATOR));
  377. Context.Status = STATUS_SUCCESS;
  378. MmMdIterate(Parameters->MemoryMap,
  379. IopInitializePhysicalAddressArbiterIterator,
  380. &Context);
  381. if (!KSUCCESS(Context.Status)) {
  382. goto InitializeResourceAllocationEnd;
  383. }
  384. //
  385. // Create an I/O space arbiter.
  386. //
  387. if (ArGetIoPortCount() != 0) {
  388. Status = IoCreateResourceArbiter(IoRootDevice, ResourceTypeIoPort);
  389. if (!KSUCCESS(Status)) {
  390. goto InitializeResourceAllocationEnd;
  391. }
  392. Status = IoAddFreeSpaceToArbiter(IoRootDevice,
  393. ResourceTypeIoPort,
  394. 0,
  395. ArGetIoPortCount(),
  396. 0,
  397. NULL,
  398. 0);
  399. if (!KSUCCESS(Status)) {
  400. goto InitializeResourceAllocationEnd;
  401. }
  402. }
  403. //
  404. // Create an interrupt line arbiter.
  405. //
  406. Status = IoCreateResourceArbiter(IoRootDevice, ResourceTypeInterruptLine);
  407. if (!KSUCCESS(Status)) {
  408. goto InitializeResourceAllocationEnd;
  409. }
  410. Status = IoAddFreeSpaceToArbiter(IoRootDevice,
  411. ResourceTypeInterruptLine,
  412. 0,
  413. -1,
  414. 0,
  415. NULL,
  416. 0);
  417. if (!KSUCCESS(Status)) {
  418. goto InitializeResourceAllocationEnd;
  419. }
  420. //
  421. // Create an interrupt vector arbiter.
  422. //
  423. Status = IoCreateResourceArbiter(IoRootDevice, ResourceTypeInterruptVector);
  424. if (!KSUCCESS(Status)) {
  425. goto InitializeResourceAllocationEnd;
  426. }
  427. Status = IoAddFreeSpaceToArbiter(IoRootDevice,
  428. ResourceTypeInterruptVector,
  429. ArGetMinimumDeviceVector(),
  430. ArGetMaximumDeviceVector() + 1,
  431. 0,
  432. NULL,
  433. 0);
  434. if (!KSUCCESS(Status)) {
  435. goto InitializeResourceAllocationEnd;
  436. }
  437. //
  438. // Create a bus number arbiter.
  439. //
  440. Status = IoCreateResourceArbiter(IoRootDevice, ResourceTypeBusNumber);
  441. if (!KSUCCESS(Status)) {
  442. goto InitializeResourceAllocationEnd;
  443. }
  444. Status = IoAddFreeSpaceToArbiter(IoRootDevice,
  445. ResourceTypeBusNumber,
  446. 0,
  447. -1,
  448. 0,
  449. NULL,
  450. 0);
  451. if (!KSUCCESS(Status)) {
  452. goto InitializeResourceAllocationEnd;
  453. }
  454. //
  455. // Create a DMA line arbiter.
  456. //
  457. Status = IoCreateResourceArbiter(IoRootDevice, ResourceTypeDmaChannel);
  458. if (!KSUCCESS(Status)) {
  459. goto InitializeResourceAllocationEnd;
  460. }
  461. Status = IoAddFreeSpaceToArbiter(IoRootDevice,
  462. ResourceTypeDmaChannel,
  463. 0,
  464. -1,
  465. 0,
  466. NULL,
  467. 0);
  468. if (!KSUCCESS(Status)) {
  469. goto InitializeResourceAllocationEnd;
  470. }
  471. //
  472. // Create an empty vendor defined arbiter. Allocation requests that hit
  473. // this arbiter will always fail.
  474. //
  475. Status = IoCreateResourceArbiter(IoRootDevice,
  476. ResourceTypeVendorSpecific);
  477. if (!KSUCCESS(Status)) {
  478. goto InitializeResourceAllocationEnd;
  479. }
  480. //
  481. // Also create an empty GPIO arbiter and an empty simple bus arbiter.
  482. //
  483. Status = IoCreateResourceArbiter(IoRootDevice, ResourceTypeGpio);
  484. if (!KSUCCESS(Status)) {
  485. goto InitializeResourceAllocationEnd;
  486. }
  487. Status = IoCreateResourceArbiter(IoRootDevice, ResourceTypeSimpleBus);
  488. if (!KSUCCESS(Status)) {
  489. goto InitializeResourceAllocationEnd;
  490. }
  491. //
  492. // Perform any architecture specific initialization.
  493. //
  494. Status = IopArchInitializeKnownArbiterRegions();
  495. if (!KSUCCESS(Status)) {
  496. goto InitializeResourceAllocationEnd;
  497. }
  498. InitializeResourceAllocationEnd:
  499. return Status;
  500. }
  501. KSTATUS
  502. IopInitializeBootDrivers (
  503. PKERNEL_INITIALIZATION_BLOCK Parameters
  504. )
  505. /*++
  506. Routine Description:
  507. This routine initializes all boot start drivers.
  508. Arguments:
  509. Parameters - Supplies a pointer to the kernel's initialization information.
  510. Return Value:
  511. Status code.
  512. --*/
  513. {
  514. PLIST_ENTRY CurrentEntry;
  515. PDRIVER Driver;
  516. PLOADED_IMAGE Image;
  517. PKPROCESS Process;
  518. KSTATUS Status;
  519. Status = STATUS_SUCCESS;
  520. //
  521. // Loop over every loaded image in the kernel process and create a driver
  522. // object for it. The driver image list is guarded by the device database
  523. // lock rather than the kernel process lock so that threads can be created.
  524. //
  525. Process = PsGetKernelProcess();
  526. KeAcquireQueuedLock(IoDeviceDatabaseLock);
  527. CurrentEntry = Process->ImageListHead.Next;
  528. while (CurrentEntry != &(Process->ImageListHead)) {
  529. Image = LIST_VALUE(CurrentEntry, LOADED_IMAGE, ListEntry);
  530. CurrentEntry = CurrentEntry->Next;
  531. //
  532. // Skip the kernel module.
  533. //
  534. if (Image->LoadedLowestAddress ==
  535. Parameters->KernelModule->LowestAddress) {
  536. continue;
  537. }
  538. Image->SystemContext = Process;
  539. Status = IoCreateDriverStructure(Image);
  540. if (!KSUCCESS(Status)) {
  541. goto InitializeBootDriversEnd;
  542. }
  543. Status = IopInitializeDriver(Image);
  544. if (!KSUCCESS(Status)) {
  545. goto InitializeBootDriversEnd;
  546. }
  547. Driver = Image->SystemExtension;
  548. Driver->Flags |= DRIVER_FLAG_LOADED_AT_BOOT;
  549. }
  550. InitializeBootDriversEnd:
  551. KeReleaseQueuedLock(IoDeviceDatabaseLock);
  552. return Status;
  553. }
  554. KSTATUS
  555. IopInitializeDeviceDatabase (
  556. PKERNEL_INITIALIZATION_BLOCK Parameters
  557. )
  558. /*++
  559. Routine Description:
  560. This routine initializes the device to driver database.
  561. Arguments:
  562. Parameters - Supplies a pointer to the kernel's initialization information.
  563. Return Value:
  564. Status code.
  565. --*/
  566. {
  567. PSTR Device;
  568. PSTR Driver;
  569. PSTR FileEnd;
  570. ULONG FileSize;
  571. PSTR LineEnd;
  572. PSTR Separator;
  573. KSTATUS Status;
  574. //
  575. // Initialize the device database lock and list heads.
  576. //
  577. IoDeviceDatabaseLock = KeCreateQueuedLock();
  578. if (IoDeviceDatabaseLock == NULL) {
  579. Status = STATUS_INSUFFICIENT_RESOURCES;
  580. goto InitializeDeviceDatabaseEnd;
  581. }
  582. INITIALIZE_LIST_HEAD(&IoDeviceDatabaseHead);
  583. INITIALIZE_LIST_HEAD(&IoDeviceClassDatabaseHead);
  584. //
  585. // Loop through every entry in the file.
  586. //
  587. Device = Parameters->DeviceToDriverFile.Buffer;
  588. FileSize = Parameters->DeviceToDriverFile.Size;
  589. FileEnd = Device + FileSize;
  590. while (TRUE) {
  591. Driver = NULL;
  592. //
  593. // Find the end of the line.
  594. //
  595. LineEnd = RtlStringFindCharacter(Device, '\n', FileSize);
  596. if (LineEnd != NULL) {
  597. //
  598. // If the line is less than 2 characters wide, ignore it.
  599. //
  600. if (LineEnd - Device < 2) {
  601. ASSERT(LineEnd != Device);
  602. if (LineEnd + 3 >= FileEnd) {
  603. break;
  604. }
  605. FileSize -= (UINTN)(LineEnd + 1) - (UINTN)Device;
  606. Device = LineEnd + 1;
  607. continue;
  608. }
  609. //
  610. // Terminate the end. Watch for a CR.
  611. //
  612. if (*(LineEnd - 1) == '\r') {
  613. *(LineEnd - 1) = '\0';
  614. } else {
  615. *LineEnd = '\0';
  616. }
  617. }
  618. //
  619. // Find the last equals.
  620. //
  621. if (*Device != '#') {
  622. Separator = RtlStringFindCharacterRight(Device, '=', FileSize);
  623. if ((Separator == NULL) || (Separator == LineEnd - 1) ||
  624. (Separator == Device)) {
  625. Status = STATUS_FILE_CORRUPT;
  626. goto InitializeDeviceDatabaseEnd;
  627. }
  628. *Separator = '\0';
  629. Driver = Separator + 1;
  630. }
  631. //
  632. // Add a device or device class entry, depending on the first character
  633. // in the line.
  634. //
  635. if (*Device == 'D') {
  636. Status = IoAddDeviceDatabaseEntry(Device + 1, Driver);
  637. } else if (*Device == 'C') {
  638. Status = IoAddDeviceClassDatabaseEntry(Device + 1, Driver);
  639. } else if (*Device == '#') {
  640. Status = STATUS_SUCCESS;
  641. } else {
  642. Status = STATUS_FILE_CORRUPT;
  643. }
  644. if (!KSUCCESS(Status)) {
  645. goto InitializeDeviceDatabaseEnd;
  646. }
  647. //
  648. // Stop if this is end of the file.
  649. //
  650. if ((LineEnd == NULL) || (LineEnd == FileEnd) ||
  651. (LineEnd + 1 == FileEnd)) {
  652. break;
  653. }
  654. FileSize -= (UINTN)(LineEnd + 1) - (UINTN)Device;
  655. Device = LineEnd + 1;
  656. }
  657. Status = STATUS_SUCCESS;
  658. InitializeDeviceDatabaseEnd:
  659. return Status;
  660. }
  661. KSTATUS
  662. IopCreateBootDevices (
  663. PKERNEL_INITIALIZATION_BLOCK Parameters
  664. )
  665. /*++
  666. Routine Description:
  667. This routine creates all unenumerable devices described at boot time by the
  668. device map.
  669. Arguments:
  670. Parameters - Supplies a pointer to the kernel's initialization information.
  671. Return Value:
  672. Status code.
  673. --*/
  674. {
  675. PSTR Device;
  676. PSTR DeviceSeparator;
  677. PSTR FileEnd;
  678. ULONG FileSize;
  679. PSTR LineEnd;
  680. KSTATUS Status;
  681. Status = STATUS_SUCCESS;
  682. //
  683. // Loop through every entry in the file.
  684. //
  685. Device = Parameters->DeviceMapFile.Buffer;
  686. FileSize = Parameters->DeviceMapFile.Size;
  687. FileEnd = Device + FileSize;
  688. while (TRUE) {
  689. //
  690. // Find the end of the line.
  691. //
  692. LineEnd = RtlStringFindCharacter(Device, '\n', FileSize);
  693. if (LineEnd != NULL) {
  694. //
  695. // If the line is less than 2 characters wide, ignore it.
  696. //
  697. if (LineEnd - Device < 2) {
  698. ASSERT(LineEnd != Device);
  699. if (LineEnd + 3 >= FileEnd) {
  700. break;
  701. }
  702. FileSize -= (UINTN)(LineEnd + 1) - (UINTN)Device;
  703. Device = LineEnd + 1;
  704. continue;
  705. }
  706. //
  707. // Terminate the end. Watch for a CR.
  708. //
  709. if (*(LineEnd - 1) == '\r') {
  710. *(LineEnd - 1) = '\0';
  711. } else {
  712. *LineEnd = '\0';
  713. }
  714. }
  715. //
  716. // Find the last colon.
  717. //
  718. if (*Device != '#') {
  719. DeviceSeparator = RtlStringFindCharacterRight(Device,
  720. ':',
  721. FileSize);
  722. if (DeviceSeparator == Device) {
  723. Status = STATUS_FILE_CORRUPT;
  724. goto CreateBootDevicesEnd;
  725. }
  726. if (DeviceSeparator != NULL) {
  727. *DeviceSeparator = '\0';
  728. }
  729. //
  730. // Create the device.
  731. //
  732. Status = IoCreateDevice(NULL, NULL, NULL, Device, NULL, NULL, NULL);
  733. if (!KSUCCESS(Status)) {
  734. goto CreateBootDevicesEnd;
  735. }
  736. }
  737. //
  738. // Stop if this is end of the file.
  739. //
  740. if ((LineEnd == NULL) || (LineEnd == FileEnd) ||
  741. (LineEnd + 1 == FileEnd)) {
  742. break;
  743. }
  744. FileSize -= (UINTN)(LineEnd + 1) - (UINTN)Device;
  745. Device = LineEnd + 1;
  746. }
  747. Status = STATUS_SUCCESS;
  748. CreateBootDevicesEnd:
  749. return Status;
  750. }
  751. VOID
  752. IopInitializePhysicalAddressArbiterIterator (
  753. PMEMORY_DESCRIPTOR_LIST DescriptorList,
  754. PMEMORY_DESCRIPTOR Descriptor,
  755. PVOID Context
  756. )
  757. /*++
  758. Routine Description:
  759. This routine is called once for each descriptor in the memory descriptor
  760. list.
  761. Arguments:
  762. DescriptorList - Supplies a pointer to the descriptor list being iterated
  763. over.
  764. Descriptor - Supplies a pointer to the current descriptor.
  765. Context - Supplies an optional opaque pointer of context that was provided
  766. when the iteration was requested.
  767. Return Value:
  768. None.
  769. --*/
  770. {
  771. PIO_INIT_PHYSICAL_MAP_ITERATOR PhysicalContext;
  772. KSTATUS Status;
  773. PhysicalContext = Context;
  774. ASSERT(PhysicalContext->PreviousEnd <= Descriptor->BaseAddress);
  775. //
  776. // If there was a gap between the last descriptor and this one, add it
  777. // as a hole.
  778. //
  779. if (PhysicalContext->PreviousEnd < Descriptor->BaseAddress) {
  780. Status = IoAddFreeSpaceToArbiter(
  781. IoRootDevice,
  782. ResourceTypePhysicalAddressSpace,
  783. PhysicalContext->PreviousEnd,
  784. Descriptor->BaseAddress - PhysicalContext->PreviousEnd,
  785. 0,
  786. NULL,
  787. 0);
  788. if (!KSUCCESS(Status)) {
  789. PhysicalContext->Status = Status;
  790. }
  791. }
  792. PhysicalContext->PreviousEnd = Descriptor->BaseAddress + Descriptor->Size;
  793. return;
  794. }