bootxfr.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. bootxfr.c
  5. Abstract:
  6. This module implements support for transition between the boot manager and
  7. another boot application.
  8. Author:
  9. Evan Green 24-Feb-2014
  10. Environment:
  11. Boot
  12. --*/
  13. //
  14. // ------------------------------------------------------------------- Includes
  15. //
  16. #include <minoca/kernel/kernel.h>
  17. #include "firmware.h"
  18. #include "bootlib.h"
  19. #include "bootman.h"
  20. #include "bios.h"
  21. //
  22. // ---------------------------------------------------------------- Definitions
  23. //
  24. #define EXTRA_BOOT_REGION_COUNT 4
  25. //
  26. // ------------------------------------------------------ Data Type Definitions
  27. //
  28. /*++
  29. Structure Description:
  30. This structure defines the iteration context for copying the memory
  31. descriptor list for the boot block.
  32. Members:
  33. RegionCount - Stores the current region count.
  34. AllocatedRegionCount - Stores the number of allocated regions in the array.
  35. RegionArray - Stores the allocated array of regions.
  36. --*/
  37. typedef struct _BOOT_BLOCK_DESCRIPTOR_CONTEXT {
  38. UINTN RegionCount;
  39. UINTN AllocatedRegionCount;
  40. PBOOT_RESERVED_REGION RegionArray;
  41. } BOOT_BLOCK_DESCRIPTOR_CONTEXT, *PBOOT_BLOCK_DESCRIPTOR_CONTEXT;
  42. //
  43. // ----------------------------------------------- Internal Function Prototypes
  44. //
  45. VOID
  46. BmpFwBootBlockDescriptorIterationRoutine (
  47. PMEMORY_DESCRIPTOR_LIST DescriptorList,
  48. PMEMORY_DESCRIPTOR Descriptor,
  49. PVOID Context
  50. );
  51. //
  52. // -------------------------------------------------------------------- Globals
  53. //
  54. //
  55. // ------------------------------------------------------------------ Functions
  56. //
  57. KSTATUS
  58. BmpFwInitializeBootBlock (
  59. PBOOT_INITIALIZATION_BLOCK Parameters,
  60. PBOOT_VOLUME OsVolume
  61. )
  62. /*++
  63. Routine Description:
  64. This routine initializes the boot initialization block that is passed when
  65. control is handed off to the next boot application.
  66. Arguments:
  67. Parameters - Supplies a pointer to the boot initialization block.
  68. OsVolume - Supplies a pointer to the open volume containing the application
  69. to be launched.
  70. Return Value:
  71. Status code.
  72. --*/
  73. {
  74. ULONG AllocatedRegionCount;
  75. UINTN AllocationSize;
  76. BOOT_BLOCK_DESCRIPTOR_CONTEXT Context;
  77. KSTATUS Status;
  78. RtlZeroMemory(&Context, sizeof(BOOT_BLOCK_DESCRIPTOR_CONTEXT));
  79. //
  80. // Loop through the memory map once to determine the number of reserved
  81. // regions.
  82. //
  83. MmMdIterate(&BoMemoryMap,
  84. BmpFwBootBlockDescriptorIterationRoutine,
  85. &Context);
  86. AllocatedRegionCount = Context.RegionCount + EXTRA_BOOT_REGION_COUNT;
  87. //
  88. // Allocate space for the descriptor array.
  89. //
  90. AllocationSize = AllocatedRegionCount * sizeof(BOOT_RESERVED_REGION);
  91. Context.RegionArray = BoAllocateMemory(AllocationSize);
  92. if (Context.RegionArray == NULL) {
  93. Status = STATUS_INSUFFICIENT_RESOURCES;
  94. goto FwInitializeBootBlockEnd;
  95. }
  96. RtlZeroMemory(Context.RegionArray, AllocationSize);
  97. Context.AllocatedRegionCount = AllocatedRegionCount;
  98. Context.RegionCount = 0;
  99. //
  100. // Loop through the descriptors again and mark all the regions used by this
  101. // and previous boot applications.
  102. //
  103. MmMdIterate(&BoMemoryMap,
  104. BmpFwBootBlockDescriptorIterationRoutine,
  105. &Context);
  106. Parameters->ReservedRegions = Context.RegionArray;
  107. Parameters->ReservedRegionCount = Context.RegionCount;
  108. FwpPcatGetDiskInformation(OsVolume->DiskHandle,
  109. &(Parameters->DriveNumber),
  110. &(Parameters->PartitionOffset));
  111. Status = STATUS_SUCCESS;
  112. FwInitializeBootBlockEnd:
  113. if (!KSUCCESS(Status)) {
  114. if (Context.RegionArray != NULL) {
  115. BoFreeMemory(Context.RegionArray);
  116. }
  117. }
  118. return Status;
  119. }
  120. INT
  121. BmpFwTransferToBootApplication (
  122. PBOOT_INITIALIZATION_BLOCK Parameters,
  123. PBOOT_APPLICATION_ENTRY EntryPoint
  124. )
  125. /*++
  126. Routine Description:
  127. This routine transfers control to another boot application.
  128. Arguments:
  129. Parameters - Supplies a pointer to the initialization block.
  130. EntryPoint - Supplies tne address of the entry point routine of the new
  131. application.
  132. Return Value:
  133. Returns the integer return value from the application. Often does not
  134. return on success.
  135. --*/
  136. {
  137. INT Result;
  138. Result = EntryPoint(Parameters);
  139. return Result;
  140. }
  141. //
  142. // --------------------------------------------------------- Internal Functions
  143. //
  144. VOID
  145. BmpFwBootBlockDescriptorIterationRoutine (
  146. PMEMORY_DESCRIPTOR_LIST DescriptorList,
  147. PMEMORY_DESCRIPTOR Descriptor,
  148. PVOID Context
  149. )
  150. /*++
  151. Routine Description:
  152. This routine is called once for each descriptor in the memory descriptor
  153. list.
  154. Arguments:
  155. DescriptorList - Supplies a pointer to the descriptor list being iterated
  156. over.
  157. Descriptor - Supplies a pointer to the current descriptor.
  158. Context - Supplies an optional opaque pointer of context that was provided
  159. when the iteration was requested.
  160. Return Value:
  161. None.
  162. --*/
  163. {
  164. PBOOT_BLOCK_DESCRIPTOR_CONTEXT BootContext;
  165. PBOOT_RESERVED_REGION Region;
  166. BootContext = Context;
  167. //
  168. // Skip all except interesting descriptors.
  169. //
  170. if ((Descriptor->Type == MemoryTypeFirmwareTemporary) ||
  171. (Descriptor->Type == MemoryTypeLoaderTemporary) ||
  172. (Descriptor->Type == MemoryTypeLoaderPermanent)) {
  173. //
  174. // If there's a region array, fill this in. Otherwise, just count.
  175. //
  176. if (BootContext->RegionArray != NULL) {
  177. ASSERT(BootContext->RegionCount <
  178. BootContext->AllocatedRegionCount);
  179. Region = &(BootContext->RegionArray[BootContext->RegionCount]);
  180. Region->Address = Descriptor->BaseAddress;
  181. Region->Size = Descriptor->Size;
  182. }
  183. BootContext->RegionCount += 1;
  184. }
  185. return;
  186. }