123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- /*++
- Copyright (c) 2014 Minoca Corp.
- This file is licensed under the terms of the GNU General Public License
- version 3. Alternative licensing terms are available. Contact
- info@minocacorp.com for details. See the LICENSE file at the root of this
- project for complete licensing information.
- Module Name:
- bootxfr.c
- Abstract:
- This module implements support for transition between the boot manager and
- another boot application.
- Author:
- Evan Green 24-Feb-2014
- Environment:
- Boot
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include <minoca/kernel/kernel.h>
- #include "firmware.h"
- #include "bootlib.h"
- #include "bootman.h"
- #include "bios.h"
- //
- // ---------------------------------------------------------------- Definitions
- //
- #define EXTRA_BOOT_REGION_COUNT 4
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- /*++
- Structure Description:
- This structure defines the iteration context for copying the memory
- descriptor list for the boot block.
- Members:
- RegionCount - Stores the current region count.
- AllocatedRegionCount - Stores the number of allocated regions in the array.
- RegionArray - Stores the allocated array of regions.
- --*/
- typedef struct _BOOT_BLOCK_DESCRIPTOR_CONTEXT {
- UINTN RegionCount;
- UINTN AllocatedRegionCount;
- PBOOT_RESERVED_REGION RegionArray;
- } BOOT_BLOCK_DESCRIPTOR_CONTEXT, *PBOOT_BLOCK_DESCRIPTOR_CONTEXT;
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- KSTATUS
- BmpFwCreatePageTables (
- PBOOT_INITIALIZATION_BLOCK Parameters
- );
- VOID
- BmpFwBootBlockDescriptorIterationRoutine (
- PMEMORY_DESCRIPTOR_LIST DescriptorList,
- PMEMORY_DESCRIPTOR Descriptor,
- PVOID Context
- );
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // ------------------------------------------------------------------ Functions
- //
- KSTATUS
- BmpFwInitializeBootBlock (
- PBOOT_INITIALIZATION_BLOCK Parameters,
- PBOOT_VOLUME OsVolume
- )
- /*++
- Routine Description:
- This routine initializes the boot initialization block that is passed when
- control is handed off to the next boot application.
- Arguments:
- Parameters - Supplies a pointer to the boot initialization block.
- OsVolume - Supplies a pointer to the open volume containing the application
- to be launched.
- Return Value:
- Status code.
- --*/
- {
- ULONG AllocatedRegionCount;
- UINTN AllocationSize;
- BOOT_BLOCK_DESCRIPTOR_CONTEXT Context;
- KSTATUS Status;
- RtlZeroMemory(&Context, sizeof(BOOT_BLOCK_DESCRIPTOR_CONTEXT));
- //
- // Loop through the memory map once to determine the number of reserved
- // regions.
- //
- MmMdIterate(&BoMemoryMap,
- BmpFwBootBlockDescriptorIterationRoutine,
- &Context);
- AllocatedRegionCount = Context.RegionCount + EXTRA_BOOT_REGION_COUNT;
- //
- // Allocate space for the descriptor array.
- //
- AllocationSize = AllocatedRegionCount * sizeof(BOOT_RESERVED_REGION);
- Context.RegionArray = BoAllocateMemory(AllocationSize);
- if (Context.RegionArray == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto FwInitializeBootBlockEnd;
- }
- RtlZeroMemory(Context.RegionArray, AllocationSize);
- Context.AllocatedRegionCount = AllocatedRegionCount;
- Context.RegionCount = 0;
- //
- // Allocate page tables if transferring to a 64-bit application.
- //
- if ((Parameters->Flags & BOOT_INITIALIZATION_FLAG_64BIT) != 0) {
- Status = BmpFwCreatePageTables(Parameters);
- if (!KSUCCESS(Status)) {
- goto FwInitializeBootBlockEnd;
- }
- }
- //
- // Loop through the descriptors again and mark all the regions used by this
- // and previous boot applications.
- //
- MmMdIterate(&BoMemoryMap,
- BmpFwBootBlockDescriptorIterationRoutine,
- &Context);
- Parameters->ReservedRegions = (UINTN)(Context.RegionArray);
- Parameters->ReservedRegionCount = Context.RegionCount;
- FwpPcatGetDiskInformation(OsVolume->DiskHandle,
- &(Parameters->DriveNumber),
- &(Parameters->PartitionOffset));
- Status = STATUS_SUCCESS;
- FwInitializeBootBlockEnd:
- if (!KSUCCESS(Status)) {
- if (Context.RegionArray != NULL) {
- BoFreeMemory(Context.RegionArray);
- }
- }
- return Status;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
- VOID
- BmpFwBootBlockDescriptorIterationRoutine (
- PMEMORY_DESCRIPTOR_LIST DescriptorList,
- PMEMORY_DESCRIPTOR Descriptor,
- PVOID Context
- )
- /*++
- Routine Description:
- This routine is called once for each descriptor in the memory descriptor
- list.
- Arguments:
- DescriptorList - Supplies a pointer to the descriptor list being iterated
- over.
- Descriptor - Supplies a pointer to the current descriptor.
- Context - Supplies an optional opaque pointer of context that was provided
- when the iteration was requested.
- Return Value:
- None.
- --*/
- {
- PBOOT_BLOCK_DESCRIPTOR_CONTEXT BootContext;
- PBOOT_RESERVED_REGION Region;
- BootContext = Context;
- //
- // Skip all except interesting descriptors.
- //
- if ((Descriptor->Type == MemoryTypeFirmwareTemporary) ||
- (Descriptor->Type == MemoryTypeLoaderTemporary) ||
- (Descriptor->Type == MemoryTypeLoaderPermanent)) {
- //
- // If there's a region array, fill this in. Otherwise, just count.
- //
- if (BootContext->RegionArray != NULL) {
- ASSERT(BootContext->RegionCount <
- BootContext->AllocatedRegionCount);
- Region = &(BootContext->RegionArray[BootContext->RegionCount]);
- Region->Address = Descriptor->BaseAddress;
- Region->Size = Descriptor->Size;
- }
- BootContext->RegionCount += 1;
- }
- return;
- }
|