bootxfr.c 5.9 KB

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