init.c

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

C
730
字号
/*++

Copyright (c)  1999 - 2003 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 32-bit environment.

Revision History

--*/

#include "bios32.h"
#include "plshell.h"
#include "PlIntCtrl.h"
#include "CpuInterrupt.h"
#include "CpuTimer.h"
#include "intload.h"
#include "Drivers.h"
#include "PlDefio.h"
#include "PlatformLib.h"
#include "PlEfiLdr.h"
 
#include EFI_PROTOCOL_DEFINITION (Decompress)

//
//
//
#define EFILDR_HEADER_ADDRESS      0x00022000

typedef struct {
    UINT32       CheckSum;
    UINT32       Offset;
    UINT32       Length;
    UINT8        FileName[52];
} EFILDR_IMAGE;

typedef struct {          
    UINT32       Signature;     
    UINT32       HeaderCheckSum;
    UINT32       FileLength;
    UINT32       NumberOfImages;
} EFILDR_HEADER;

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

STATIC
VOID
PlInitializeTables (
    );

STATIC
VOID
PlInstallMemoryMap (
    IN UINTN                    NoDesc,
    IN EFI_MEMORY_DESCRIPTOR    *Desc
    );

STATIC
VOID 
PlInstallBaseDevices (                      
    );

STATIC
VOID
InitTickHandler(
    VOID
    );

STATIC
VOID
PlExitBootServices (
    IN EFI_EVENT        Event,
    IN VOID             *Context
    );

VOID
MainEntry (
    IN EFILDRHANDOFF  *Handoff
    )

/*++

  Routine Description:

    This is the entry point after this code has been loaded into memory. 

Arguments:


Returns:

    Calls into EFI Firmware

--*/
{
    EFI_STATUS                Status;
    EFI_EVENT                 Event;
    EFI_DECOMPRESS_PROTOCOL   *Decompress;
    EFILDR_HEADER             *EFILDRHeader;
    EFILDR_IMAGE              *EFILDRImage;
    UINTN                     Index;
    CHAR16                    DriverFileName[280];
    EFI_DEVICE_PATH           *FilePath;
    EFI_HANDLE                ImageHandle;
    VOID                      *Destination;
    VOID                      *Scratch;
    UINTN                     DestinationSize;
    UINTN                     ScratchSize;
    EFI_HANDLE                EfiCoreImageHandle;

    PlInitEfiLdrCallBack (Handoff->EfiLdrCallBack);

    //
    // Add the platform support to the EFI FW tables.
    //
POST_CODE(0xaf);
    PlInitializeTables();

    //
    // Initialize the EFI FW memory map
    //
POST_CODE(0x01);
    PlInstallMemoryMap (Handoff->MemDescCount,Handoff->MemDesc);

    //
    // Set up interrupt vector mappings in interrupt controller for EFI
    //
POST_CODE(0x02);
    PlSetupInterruptController(INT_CTRLR_EFIMODE);
POST_CODE(0x03);
    InitTickHandler();

POST_CODE(0x04);
    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.
    //
POST_CODE(0x05);
    InitializeLib (NULL, ST);

    //
    // Build an image handle for the current executing image
    // 
POST_CODE(0x06);
    BuildEfiCoreImageHandle (
      MainEntry,
      Handoff->ImageBase,
      Handoff->ImageSize,
      &EfiCoreImageHandle
      );

POST_CODE(0x07);
    PlInitWatchdogTimer();

    //
    // Initialize support for calling BIOS functions
    //
POST_CODE(0x08);
    InitializeBiosIntCaller ();

    //
    // 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.
    //
POST_CODE(0x09);
    PlInstallBaseDevices();                   
POST_CODE(0x0a);
    FW->NvStoreInstalled();                             // Third

    //
    // Install and connect all built in EFI 1.1 Drivers.
    //
POST_CODE(0x0d);
    LOAD_INTERNAL_BS_DRIVER (L"BiosDisk",               InstallBiosBlkIoDrivers);

    LOAD_INTERNAL_BS_DRIVER (L"Ebc",                    InitializeEbcDriver);
    LOAD_INTERNAL_BS_DRIVER (L"Decompress",             DecompressDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"PcatPciRootBridge",      InitializePcatPciRootBridge);
    LOAD_INTERNAL_BS_DRIVER (L"PciBus",                 PciBusEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"PcatIsaAcpi",            PcatIsaAcpiDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"IsaBus",                 IsaBusControllerDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"IsaSerial",              SerialControllerDriverEntryPoint);

POST_CODE(0x0e);
    LOAD_INTERNAL_BS_DRIVER (L"BiosVgaMiniPort",        BiosVgaMiniPortDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"VgaClass",               VgaClassDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"CirrusLogic5430",        CirrusLogic5430UgaDrawDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"GraphicsConsole",        InitializeGraphicsConsole);
    LOAD_INTERNAL_BS_DRIVER (L"ConPlatform",            ConPlatformDriverEntry);
    LOAD_INTERNAL_BS_DRIVER (L"ConSplitter",            ConSplitterDriverEntry);

POST_CODE(0x0f);
    ConnectAllConsoles ();

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

    //
    // Install remaining EFI 1.1 Drivers
    //
POST_CODE(0x11);
    LOAD_INTERNAL_BS_DRIVER (L"DiskIo",                 DiskIoDriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"Partition",              PartitionEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"Fat",                    FatEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"BiosKeyboard",           BiosKeyboardDriverEntryPoint);

    //
    // Load all images that follow the EFI Core image in EFILDR
    // 
POST_CODE(0x12);
    Status = BS->LocateProtocol(&gEfiDecompressProtocolGuid, NULL, &Decompress);

    if (!EFI_ERROR (Status)) {
      EFILDRHeader = (EFILDR_HEADER *)(EFILDR_HEADER_ADDRESS);
      EFILDRImage  = (EFILDR_IMAGE *)(EFILDR_HEADER_ADDRESS + sizeof(EFILDR_HEADER));
      EFILDRImage += 2;
      for (Index = 2; Index < EFILDRHeader->NumberOfImages; Index++, EFILDRImage++) {
        SPrint(DriverFileName, sizeof(DriverFileName), L"%a", EFILDRImage->FileName);
        FilePath = FileDevicePath (NULL, DriverFileName);

        //
        // Decompress the image
        //

        Status = Decompress->GetInfo(
                   Decompress, 
                   (VOID *)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
                   EFILDRImage->Length,
                   &DestinationSize, 
                   &ScratchSize
                   );
        if (!EFI_ERROR (Status)) {
          Destination = AllocatePool(DestinationSize);
          Scratch = AllocatePool(ScratchSize);
          if (Destination != NULL && Scratch != NULL) {

            Status = Decompress->Decompress(
                       Decompress, 
                       (VOID *)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
                       EFILDRImage->Length,
                       Destination,
                       DestinationSize, 
                       Scratch,
                       ScratchSize
                       );
            if (!EFI_ERROR (Status)) {
  
              Status = BS->LoadImage(
                             TRUE,
                             EfiCoreImageHandle,
                             FilePath,
                             Destination,
                             DestinationSize,
                             &ImageHandle
                             );
              if (!EFI_ERROR (Status)) {
                Status = BS->StartImage (ImageHandle, 0, NULL);
              }
            }
          }
          if (Destination != NULL) {
            FreePool (Destination);
          }
          if (Scratch != NULL) {
            FreePool (Scratch);
          }
        }
      }
    }

    BS->FreePages((EFI_PHYSICAL_ADDRESS)EFILDR_HEADER_ADDRESS, (EFILDRHeader->FileLength + EFI_PAGE_SIZE - 1) >> EFI_PAGE_SHIFT);

    //
    // Connect all EFI 1.1 drivers to get disks connected so access to the
    // BootStr file is possible.  Also redisplay the banner just in case
    // additional consoles showed up.
    //
POST_CODE(0x13);
    ConnectAll();
    EFIFirmwareBanner();
    PlPrintLogonBanner();
    Print (L"This image %HMainEntry%N is at address %08x\n",  (UINTN)MainEntry);

    //
    //
    //
POST_CODE(0x14);
    PlInitNvVarStoreFile ( 
        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
        0x4000, 2
        );
    FW->NvStoreInstalled();                             // Third

    //
    // Say we only support English
    //
POST_CODE(0x15);
    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 ();

POST_CODE(0x16);
    InitializeLib (NULL, ST);

    //
    // Install all built in EFI 1.1 Drivers that require EFI Variable Services
    //
POST_CODE(0x17);
    LOAD_INTERNAL_BS_DRIVER (L"Terminal",               InitializeTerminal);
    LOAD_INTERNAL_BS_DRIVER (L"BiosSnp16",              BiosSnp16DriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"Snp3264",                InitializeSnpNiiDriver);
    LOAD_INTERNAL_BS_DRIVER (L"PxeBc",                  InitializeBCDriver);
    LOAD_INTERNAL_BS_DRIVER (L"BIS",                    EFIBIS_BaseCodeModuleInit);
    LOAD_INTERNAL_BS_DRIVER (L"PxeDhcp4",               PxeDhcp4DriverEntryPoint);
    LOAD_INTERNAL_BS_DRIVER (L"SerialMouse",            SerialMouseDriverEntryPoint);

⌨️ 快捷键说明

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