init.c

来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 818 行 · 第 1/2 页

C
818
字号
/*++

Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.


Module Name:

    init.c

Abstract:

    Main entry point on EFI emulation application



Revision History

--*/


#include "ntemul.h"
#include "plshell.h"
#include "intload.h"
#include "PlWatchDog.h"
#include "Drivers.h"
#include "PlDefio.h"
#include "PlatformLib.h"

//
// prototypes
//
EFI_STATUS
BuildEfiCoreImageHandle (
  IN  VOID                 *EntryPoint,
  IN  VOID                 *BaseAddress,
  IN  UINT64               Size,
  OUT EFI_HANDLE           *CoreImageHandle
  );

EFI_STATUS
PlKillNtConsoles (
    UINTN   ResetCode
    );


STATIC
EFI_STATUS
NtPlResetSystem (
    IN EFI_RESET_TYPE   ResetType,
    IN EFI_STATUS       ResetStatus,
    IN UINTN            DataSize,
    IN CHAR16           *ResetData OPTIONAL
    );

STATIC
VOID
PlInitializeTables (
    VOID
    );

STATIC
VOID
PlInstallMemoryMap (
    VOID
    );

STATIC
VOID
PlInstallBaseDevices (
    VOID
    );

STATIC
VOID
PlIdleLoop (
    IN BOOLEAN  Polling
    );

STATIC
BOOLEAN
PlSetInterruptState (
    IN BOOLEAN  Enable
    );

STATIC
VOID
PlSetVirtualAddressMap (
    IN EFI_CONVERT_POINTER      ConvertPointer,
    IN UINTN                    MemoryMapSize,
    IN UINTN                    DescriptorSize,
    IN UINT32                   DescriptorVersion,
    IN EFI_MEMORY_DESCRIPTOR    *VirtualMap
    );

VOID
PlInstallSignalHandlers (
    VOID
    );

STATIC
EFI_STATUS
PlStall(
    IN UINTN Microseconds
    );

STATIC
VOID
PlEnableTimerInterrupt(
    VOID
    );

//
//
//

INTN
main (
    INTN        argc,
    CHAR8       **argv,
    CHAR8       **envp
    )
{
    EFI_STATUS      Status;
	EFI_HANDLE      EfiCoreImageHandle;

    //
    // Set the process to the highest priority in the idle class
    //
    SetPriorityClass (GetCurrentProcess(), IDLE_PRIORITY_CLASS);
    SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_NORMAL);

    //
    // Add the platform support to the EFI FW tables.
    //
    PlInitializeTables();                               // First

    //
    // Initialize the EFI FW memory map
    //
    PlInstallMemoryMap();     
    FW->MemoryMapInstalled();                           // Second

    //
    // Once the memory map has been installed, basic EFI services
    // are now functional.   Although no devices or variable
    // store support is on line.
    //
    InitializeLib (NULL, ST);

    //
    // Build an image handle for the current executing image
    // 
    BuildEfiCoreImageHandle (
      main,
      0,
      0,
      &EfiCoreImageHandle
      );

    PlInitializeWinNtThunkTable ();

    PlInitWatchdogTimer();

    //
    // Install base devices.  This would at least include a 
    // global device_IO device, all NV ram store device(s), and 
    // the timer tick.  It may optionally include other device_io
    // devices.
    //
    PlInstallBaseDevices ();
    FW->NvStoreInstalled ();
    PlInstallSignalHandlers ();
    PlEnableTimerInterrupt ();
    
    //
    // Say we only support English
    //
    Status = RT->SetVariable (  
                    VarLanguageCodes, &EfiGlobalVariable,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    strlena (LanguageCodeEnglish), LanguageCodeEnglish 
                    );
    ASSERT (!EFI_ERROR(Status));

    //
    // Set supported language to English.
    //
    Status = RT->SetVariable (  
                    VarLanguage, &EfiGlobalVariable,
                    EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    strlena (LanguageCodeEnglish), LanguageCodeEnglish 
                    );
    //ASSERT (!EFI_ERROR(Status));
    
    //
    // Set EFIDebug based on NVRAM variable;
    //
    EFIDebugVariable ();

    //
    // Install and connect all built in EFI 1.1 Drivers.
    //
    LOAD_INTERNAL_BS_DRIVER (L"Ebc",                    InitializeEbcDriver);
    LOAD_INTERNAL_BS_DRIVER (L"Decompress",             DecompressDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"WinNtBusDriver",         InitializeWinNtBusDriver);
    LOAD_INTERNAL_BS_DRIVER (L"WinNtSerialIo",          InitializeWinNtSerialIo);

    LOAD_INTERNAL_BS_DRIVER (L"WinNtPciRootBridge",     InitializeWinNtPciRootBridge);
    LOAD_INTERNAL_BS_DRIVER (L"PciBus",                 PciBusEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"WinNtConsole",           InitializeWinNtConsole);
    LOAD_INTERNAL_BS_DRIVER (L"WinNtUga",               InitializeWinNtUga);
    LOAD_INTERNAL_BS_DRIVER (L"GraphicsConsole",        InitializeGraphicsConsole);
    LOAD_INTERNAL_BS_DRIVER (L"Terminal",               InitializeTerminal);
    LOAD_INTERNAL_BS_DRIVER (L"ConPlatform",            ConPlatformDriverEntry);
    LOAD_INTERNAL_BS_DRIVER (L"ConSplitter",            ConSplitterDriverEntry);

    ConnectAllConsoles ();

    //
    // Once consoles are installed, messages may be printed to the consoles
    //
    EFIFirmwareBanner();
    PlPrintLogonBanner();
    Print (L"This image %HMainEntry%N is at address %08x\n",  (UINTN)main);

    //
    // Install remaining EFI 1.1 Drivers
    //
    LOAD_INTERNAL_BS_DRIVER (L"WinNtSimpleFileSystem",  InitializeWinNtSimpleFileSystem);
    LOAD_INTERNAL_BS_DRIVER (L"WinNtBlockIo",           InitializeWinNtBlockIo);
    LOAD_INTERNAL_BS_DRIVER (L"DiskIo",                 DiskIoDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"Partition",              PartitionEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"Fat",                    FatEntryPoint);

    //
    // Install all built in EFI 1.1 Drivers that require EFI Variable Services
    //
    LOAD_INTERNAL_BS_DRIVER (L"BIS",                    EFIBIS_BaseCodeModuleInit);
    LOAD_INTERNAL_BS_DRIVER (L"SerialMouse",            SerialMouseDriverEntryPoint);

#if EFI_BOOTSHELL
    PlInitializeInternalLoad();
#endif

    // 
    // loop thru boot manager and boot maintenance until a boot
    // option is selected
    //
    while (TRUE) {
        //
        // The platform code is ready to boot the machine. Pass control
        // to the boot manager
        // 
        LOAD_INTERNAL_DRIVER(
            FW,
            IMAGE_SUBSYSTEM_EFI_APPLICATION,
            L"bootmgr",
            InitializeBootManager
            );

        //
        // If we return from above, means that no boot choices were found
        // or boot maintenance chosen. hence invoke boot maintenance menu
        // 
        LOAD_INTERNAL_DRIVER(
            FW,
            IMAGE_SUBSYSTEM_EFI_APPLICATION,
            L"bmaint",
            InitializeBootMaintenance
            );
    }

    return 0;
}

#if EFI_BOOTSHELL
//
// Global Data
//
STATIC BOOLEAN  ShellToolsLoaded = FALSE;


VOID
PlStartShell (
    VOID
    )
{
    if (ShellToolsLoaded == FALSE) {
        PlLoadShellTools();
        PlLoadShellDebugTools();
        PlLoadShellAdditionalTools();
        ShellToolsLoaded = TRUE;
    }
    PlLoadShell();
}
#endif

STATIC
VOID
PlInitializeTables (
    VOID
    )
/*++

Routine Description:

    Initialization function called to obtain and update any 
    global table information or entry points that are in:

        SystemTable
        SystemTable->BootServices
        SystemTAble->RuntimeServices

Arguments:

    None

Returns:

    Tables set and updated

--*/
{

    //
    // Initialize the platform table
    //

    PlTable.EmulateLoad          = PlEmulateLoad;
    PlTable.IdleLoop             = PlIdleLoop;
    PlTable.SetInterruptState    = PlSetInterruptState;
    PlTable.SetVirtualAddressMap = NULL;
    PlTable.SI_HandoffState      = NULL;
    PlTable.EI_ReturnState       = NULL;

    //
    // Call the EFI FW's entry point and get back the initial
    // Firwmare and SystemTable
    //

    EFIEntryPoint (&PlTable, &FW, &ST);  
    BS = ST->BootServices;
    RT = ST->RuntimeServices;

    //
    // Update / provide system table information.
    // The core EFI firmware does not provide the following 
    // system table information and should be filled in here:
    //          MpsTable
    //          AcpiTable
    //          SMBIOSTable
    //          OEMVendorGuid
    //          OEMSystemTable
    //

    ST->NumberOfTableEntries = 0;
    ST->ConfigurationTable   = NULL;

    //
    // Update / provide any entries in the boot services table
    // The core EFI firmware does not provide the following
    // entries in the boot services table:
    //          Stall
    //

    BS->Stall = PlStall;
    BS->SetWatchdogTimer = PlSetWatchdogTimer;

    //
    // Update / provide any entries in the runtime service table.
    // The core EFI firmware does not provide the following
    // entries in the runtime services table:
    //          GetTime
    //          SetTime
    //          GetWakeupTime
    //          SetWakeupTime
    //

    RT->GetTime       = PlGetTime;
    RT->SetTime       = PlSetTime;
    RT->GetWakeupTime = PlGetWakeupTime;
    RT->SetWakeupTime = PlSetWakeupTime;

    RT->ResetSystem   = NtPlResetSystem;

    //
    // Done with table initializations
    //
}

STATIC
VOID
PlInstallMemoryMap (
    VOID
    )
/*++

Routine Description:

    Called to initialize the memory map descriptors for
    the system's memory map.   

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?