DXE Phase

  • Overview
    • DXE Core
    • DXE Dispatcher
    • EFI System Table
    • DXE Driver - Non-Driver Model
    • DXE Driver - Driver Model
    • Protocol & Handle
  • 执行流程图
  • 涉及元件及功能
    • DXE architecture protocol种类及其功能
  • DxeMain()

Overview

DXE ( Driver Execution Environment)阶段执行大部分系统初始化工作,进人此阶段时, 内存已经可以被完全使用,因而此阶段可以进行大量的复杂工作。从程序设计的角度讲, DXE阶段与PEI阶段相似,由于最终的OS 是64位的,所以要引导和启动OS就需要相应的64位环境同时从该阶段开始memory可用空间变多(不局限4G以内),可以使用更好的访问模式、启动性能。
DXE阶段及后面的程序在内存中执行
主要含有以下概念:

  • DXE Core
  • DXE Dispatcher
  • System Table
  • DXE Driver
  • Protocol and Handle

DXE Core

DxeMain (),是DXE阶段执行的主函数,同时以参数的形式接收PEI阶段生成的HOB表。

  • 创建EFI System Table,在随后被执行的DXE Driver中逐步完善此table。
  • 生成Boot Services / Run Time Services / DXE Services.
  • 负责调用Dispatcher,所有的DXE Driver在这个函数中被检测并执行。
  • 当所有的DXE Driver被执行完成之后,接着会执行一个特殊的DXE Driver进而进入BDS阶段。

DXE Dispatcher

  • 调用DXE Service里提供的服务函数去BIOS芯片里搜寻并执行DXE Driver。
  • 检测并按照相应的顺序执行所有的DXE Driver:在每个driver的inf文件的[Depex]段里有该driver的依赖条件,当所有的依赖条件都成立时,该driver才被允许执行。

EFI System Table

  • System Table是UEFI内核的全局结构体,是最重要的数据结构之一
  • UEFI Driver利用System Table才可以访问UEFI内核、硬件资源和I/O设备。
  • System Table指针作为Image入口函数的参数传递到用户空间,因此用户可以使用它。Image的入口函数有统一的格式,其函数原型如下:
typedef
EFI_STATUS
(EFIAPI *EFI_IMAGE_ENTRY_POINT)(IN  EFI_HANDLE                   ImageHandle,IN  EFI_SYSTEM_TABLE             *SystemTable);

System Table包含了以下子结构体:

  • Boot Services Table
  • Runtime Service Table
  • DXE Service Table
  • System Configuration Tables
  • 其他 (Console in/out, Handle Database, …)
    可以参考:https://blog.csdn.net/weixin_45279063/article/details/116023011

DXE Driver - Non-Driver Model

Non-Driver Model特征:

  • 在DXE早期阶段执行。
  • 分步骤初始化CPU & chipset。
  • 生成Architectural protocol供DXE Core或其它的DXE Driver使用。

DXE Driver - Driver Model

Driver Model特征:

  • 符合标准的UEFI驱动模式。
  • 执行此模组时不会对硬件进行初始化操作。
  • 注册Driver binding protocol到handle database。
  • 注册的protocol在BDS阶段被调用并对硬件进行操作。

Protocol & Handle

Protocols由一组数据结构和一个GUID组成,安装在handle上。可以参考:https://blog.csdn.net/weixin_45279063/article/details/116268076
Handle, 也叫对象(Object), 其本质是一个VOID型指针, 是protocol的载体

执行流程图

几乎所有的硬件的初始化都在DXE这做完,同时产生efi system table, 来提供各种service供所面阶段使用。最后把控制权交给bds来boot os.

涉及元件及功能

  1. DXE Core,可视为dxe的核心,用来dispatch dxe driver 和产生efi system
    table,以提供boot service, runtime service, dxe service,负责DXE基础服务和执行流程.
  2. dxe driver, 被dxe core 所读取,用来做各种硬件的初始化,产生protocol和其他service.
  3. dxe dispatcher: dxe core 的一部分,以正确的顺序来搜寻和执行dxe driver,负责调度执行DXE驱动,初始化系统设备。 DXE提供的基础服务包括系统表、启动服务、Run Time Services.
  4. dxe architecture protocol: 由dxe driver所产生,是dxe core和hardware沟通的唯一介面,所以没有install 完全不能开机。
  5. efi system table: 包含了许多pointer,如所有 efi system table, configuration table, handledatabase, and console device.

DXE architecture protocol种类及其功能

这些Protocol在UEFI BIOS运行的过程中会安装,且一定需要被安装,如果没有被安装的话,系统就会报错。

//
// DXE Core Global Variables for all of the Architectural Protocols.
// If a protocol is installed mArchProtocols[].Present will be TRUE.
//
// CoreNotifyOnArchProtocolInstallation () fills in mArchProtocols[].Event
// and mArchProtocols[].Registration as it creates events for every array
// entry.
//
EFI_CORE_PROTOCOL_NOTIFY_ENTRY  mArchProtocols[] = {{ &gEfiSecurityArchProtocolGuid,         (VOID **)&gSecurity,      NULL, NULL, FALSE },{ &gEfiCpuArchProtocolGuid,              (VOID **)&gCpu,           NULL, NULL, FALSE },{ &gEfiMetronomeArchProtocolGuid,        (VOID **)&gMetronome,     NULL, NULL, FALSE },{ &gEfiTimerArchProtocolGuid,            (VOID **)&gTimer,         NULL, NULL, FALSE },{ &gEfiBdsArchProtocolGuid,              (VOID **)&gBds,           NULL, NULL, FALSE },{ &gEfiWatchdogTimerArchProtocolGuid,    (VOID **)&gWatchdogTimer, NULL, NULL, FALSE },{ &gEfiRuntimeArchProtocolGuid,          (VOID **)&gRuntime,       NULL, NULL, FALSE },{ &gEfiVariableArchProtocolGuid,         (VOID **)NULL,            NULL, NULL, FALSE },{ &gEfiVariableWriteArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE },{ &gEfiCapsuleArchProtocolGuid,          (VOID **)NULL,            NULL, NULL, FALSE },{ &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL,            NULL, NULL, FALSE },{ &gEfiResetArchProtocolGuid,            (VOID **)NULL,            NULL, NULL, FALSE },{ &gEfiRealTimeClockArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE },{ NULL,                                  (VOID **)NULL,            NULL, NULL, FALSE }
};
  1. security: 提供 DXE core 验证 firmware volume中的程序是否可用。
  2. cpu: 提供cpu的service如管理cache,管理中断,取得处理器频率,查询处理器的timer.
typedef struct _EFI_METRONOME_ARCH_PROTOCOL {EFI_METRONOME_WAIT_FOR_TICK          WaitForTIck;UINT32                              TickPeriod;}  EFI_METRONOME_ARCH_PROTOCOL;

提供一个微小的延时,百万分之一秒为单位。

  1. Timer: 提供固定时间的中断,使dxe core dispatch 完成所有driver后,会将控制权交给BDS.
    在DXE运行结束,调用gBds->Entry (gBds), 但并不能显式的看到 gBds 是在哪里赋值的。其实bios 没有单独去locate BDS Architectural Protocol. 而是先整出上面这个结构体。然后一把 把这个结构体里面的成员的instance 挨个找到。

DxeMain()

CoreInstallConfigurationTable(
IN EFI_GUID *Guid,
IN VOID *Table
);

VOID
EFIAPI
DxeMain (IN  VOID *HobStart)
{EFI_STATUS                    Status;EFI_PHYSICAL_ADDRESS          MemoryBaseAddress;UINT64                        MemoryLength;PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;UINTN                         Index;EFI_HOB_GUID_TYPE             *GuidHob;EFI_VECTOR_HANDOFF_INFO       *VectorInfoList;EFI_VECTOR_HANDOFF_INFO       *VectorInfo;VOID                          *EntryPoint;//// Setup the default exception handlers// 设置默认的异常处理程序VectorInfoList = NULL;GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart);if (GuidHob != NULL) {VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob));}// 初始化所有CPU异常项,并提供默认的异常处理程序。调用者应该尝试获取一个正在使用的中断和/或异常向量数组,这些向量需要在PI 1.3规范中定义的  // EFI_VECTOR_HANDOFF_INFO中保存。如果调用者不能得到保留的向量列表或者它不存在,将VectorInfo设置为NULL。// 如果VectorInfo不为空,则每个vector属性都会相应地初始化异常向量。Status = InitializeCpuExceptionHandlers (VectorInfoList);ASSERT_EFI_ERROR (Status);//// Initialize Debug Agent to support source level debug in DXE phase// 此函数用于设置调试环境,以支持源代码级的调试。如果某些调试代理库实例有一些私人数据保存在堆栈中,这个函数必须工作模式不返回给调用者,// 然后调用者需要结束后所有其他逻辑InitializeDebugAgent()成一个函数并将其传递到InitializeDebugAgent()。// InitializeDebugAgent()负责在InitializeDebugAgent()的末尾调用传入函数。// 如果参数函数不为空,调试代理库实例将通过在上下文中传递参数来调用它。如果Function()为空,调试代理库实例将在安装调试环境后返回。InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_CORE, HobStart, NULL);//// Initialize Memory Services// 初始化内存服务// 外部函数。基于内存描述符HOBs初始化内存服务。这个函数负责启动内存映射,因此可以进行内存分配和资源分配。// 这个函数的第一部分不能依赖任何内存服务,直到至少有一个内存描述符提供给内存服务。CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength);// 初始化内存概要文件。MemoryProfileInit (HobStart);//// Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData// Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table// 调用内存服务,为系统表和运行时服务申请内存空间gDxeCoreST = AllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate);ASSERT (gDxeCoreST != NULL);gDxeCoreRT = AllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate);ASSERT (gDxeCoreRT != NULL);gDxeCoreST->RuntimeServices = gDxeCoreRT;//// Start the Image Services.// 初始化镜像服务,将映像服务添加到EFI引导服务表中,并为该映像安装协议接口。Status = CoreInitializeImageServices (HobStart);ASSERT_EFI_ERROR (Status);//// Initialize the Global Coherency Domain Services// 初始化全局配置数据库服务// 外部函数。基于内存描述符HOBs初始化GCD和内存服务。这个函数负责启动GCD映射和内存映射,// 因此可以进行内存分配和资源分配。 HobStart将被重新定位到池缓冲区中。Status = CoreInitializeGcdServices (&HobStart, MemoryBaseAddress, MemoryLength);ASSERT_EFI_ERROR (Status);//// Call constructor for all libraries// 调用所有库模块的构造函数,该函数由预处理的python脚本生成,位于  // edk2/Build/${CompiledPkgName}/DEBUG_GCC44/${ARCH}/MdeModulePkg/Core/Dxe/DxeMain/DEBUG 目录下的AutoGen.c 文件中。// 根据由 inf 文件可知DXE模块所需的库,同时自动生成构造函数 ProcessLibraryConstructorList ()ProcessLibraryConstructorList (gDxeCoreImageHandle, gDxeCoreST);PERF_END   (NULL,"PEI", NULL, 0) ;PERF_START (NULL,"DXE", NULL, 0) ;//// Report DXE Core image information to the PE/COFF Extra Action Library// ZeroMem (&ImageContext, sizeof (ImageContext));ImageContext.ImageAddress   = (EFI_PHYSICAL_ADDRESS)(UINTN)gDxeCoreLoadedImage->ImageBase;// 返回一个指向PE/COFF映像的PDB文件名的指针,该映像已经通过PE/COFF加载器库函数加载到系统内存中。返回Pe32Data指定的PE/COFF图像的PDB文件名。  // 如果Pe32Data指定的PE/COFF图像不是有效的,则返回NULL。如果Pe32Data指定的PE/COFF映像不包含调试目录项,则返回NULL。如果Pe32Data指定的// PE/COFF图像中的调试目录项不包含PDB文件名,则返回NULL。如果Pe32Data为空,则ASSERT()。ImageContext.PdbPointer     = PeCoffLoaderGetPdbPointer ((VOID*)(UINTN)ImageContext.ImageAddress);// 返回由Pe32Data指定的PE/COFF头的大小。如果Pe32Data为空,则ASSERT()。ImageContext.SizeOfHeaders  = PeCoffGetSizeOfHeaders ((VOID*)(UINTN)ImageContext.ImageAddress);// 检索并返回一个指向PE/COFF图像入口点的指针,该图像已经通过PE/COFF加载器库函数加载到系统内存中。检索Pe32Data指定的PE/COFF图像的入口点,// 并在EntryPoint中返回这个入口点。如果无法从PE/COFF图像中检索入口点,则返回RETURN_INVALID_PARAMETER。否则返回RETURN_SUCCESS。// 如果Pe32Data为空,则ASSERT()。如果EntryPoint为NULL,则ASSERT()。Status = PeCoffLoaderGetEntryPoint ((VOID*)(UINTN)ImageContext.ImageAddress, &EntryPoint);if (Status == EFI_SUCCESS) {ImageContext.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)EntryPoint;}ImageContext.Handle         = (VOID *)(UINTN)gDxeCoreLoadedImage->ImageBase;ImageContext.ImageRead      = PeCoffLoaderImageReadFromMemory;// 加载和重新定位PE/COFF映像后执行其他操作。如果ImageContext为NULL,则ASSERT()。PeCoffLoaderRelocateImageExtraAction (&ImageContext);//// Install the DXE Services Table into the EFI System Tables's Configuration Table// 将DXE Services表安装到EFI系统表的配置表中,函数启动服务,用于从EFI系统表中添加、修改或删除系统配置表。Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS);ASSERT_EFI_ERROR (Status);//// Install the HOB List into the EFI System Tables's Configuration Table// 将HOB列表安装到EFI系统表的配置表中,Status = CoreInstallConfigurationTable (&gEfiHobListGuid, HobStart);ASSERT_EFI_ERROR (Status);//// Install Memory Type Information Table into the EFI System Tables's Configuration Table// 将内存类型信息表安装到EFI系统表的配置表中Status = CoreInstallConfigurationTable (&gEfiMemoryTypeInformationGuid, &gMemoryTypeInformation);ASSERT_EFI_ERROR (Status);//// If Loading modules At fixed address feature is enabled, install Load moduels at fixed address// Configuration Table so that user could easily to retrieve the top address to load Dxe and PEI// Code and Tseg base to load SMM driver.// 如果在固定地址功能加载模块,安装加载模块在固定地址配置表,这样用户可以很容易地检索顶部地址加载Dxe和PEI代码和Tseg base加载SMM驱动程序。if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {Status = CoreInstallConfigurationTable (&gLoadFixedAddressConfigurationTableGuid, &gLoadModuleAtFixAddressConfigurationTable);ASSERT_EFI_ERROR (Status);}//// Report Status Code here for DXE_ENTRY_POINT once it is available// 在这里报告DXE_ENTRY_POINT可用的状态代码。 如果状态代码类型已启用,则报告带有最小参数的状态代码。// 如果由type指定的状态码类型在PcdReportStatusCodeProperyMask中启用,然后调用ReportStatusCode()传入类型和值。REPORT_STATUS_CODE (EFI_PROGRESS_CODE,(EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT));//// Create the aligned system table pointer structure that is used by external// debuggers to locate the system table...  Also, install debug image info configuration table.// 创建对齐的系统表指针结构,外部调试器使用它来定位系统表…另外,安装调试图像信息配置表。// 创建并初始化DebugImageInfo表。还创建配置表并将其注册到系统表中。CoreInitializeDebugImageInfoTable ();// 在DebugImageInfo表中添加一个新的DebugImageInfo结构。如果表的大小不足以容纳另一个entry,则重新分配该表。CoreNewDebugImageInfoEntry (EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,gDxeCoreLoadedImage,gDxeCoreImageHandle);DEBUG ((DEBUG_INFO | DEBUG_LOAD, "HOBLIST address in DXE = 0x%p\n", HobStart));DEBUG_CODE_BEGIN ();EFI_PEI_HOB_POINTERS               Hob;for (Hob.Raw = HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Memory Allocation 0x%08x 0x%0lx - 0x%0lx\n", \Hob.MemoryAllocation->AllocDescriptor.MemoryType,                      \Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress,               \Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress + Hob.MemoryAllocation->AllocDescriptor.MemoryLength - 1));}}for (Hob.Raw = HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2) {DEBUG ((DEBUG_INFO | DEBUG_LOAD, "FV2 Hob           0x%0lx - 0x%0lx\n", Hob.FirmwareVolume2->BaseAddress, Hob.FirmwareVolume2->BaseAddress + Hob.FirmwareVolume2->Length - 1));} else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) {DEBUG ((DEBUG_INFO | DEBUG_LOAD, "FV Hob            0x%0lx - 0x%0lx\n", Hob.FirmwareVolume->BaseAddress, Hob.FirmwareVolume->BaseAddress + Hob.FirmwareVolume->Length - 1));}}DEBUG_CODE_END ();//// Initialize the Event Services//Status = CoreInitializeEventServices ();ASSERT_EFI_ERROR (Status);// 安装内存配置文件协议。MemoryProfileInstallProtocol ();// 初始化PropertiesTable支持。CoreInitializePropertiesTable ();// 初始化MemoryAttrubutesTable支持。CoreInitializeMemoryAttributesTable ();// 初始化内存保护支持。CoreInitializeMemoryProtection ();//// Get persisted vector hand-off info from GUIDeed HOB again due to HobStart may be updated,// and install configuration table// 由于HobStart可能会被更新,所以再次从guided HOB获取持久化的矢量切换信息,并安装配置表GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart);if (GuidHob != NULL) {VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob));VectorInfo = VectorInfoList;Index = 1;while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {VectorInfo ++;Index ++;}VectorInfo = AllocateCopyPool (sizeof (EFI_VECTOR_HANDOFF_INFO) * Index, (VOID *) VectorInfoList);ASSERT (VectorInfo != NULL);// 启动服务,用于从EFI系统表中添加、修改或删除系统配置表。Status = CoreInstallConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID *) VectorInfo);ASSERT_EFI_ERROR (Status);}//// Get the Protocols that were passed in from PEI to DXE through GUIDed HOBs//// These Protocols are not architectural. This implementation is sharing code between// PEI and DXE in order to save FLASH space. These Protocols could also be implemented// as part of the DXE Core. However, that would also require the DXE Core to be ported// each time a different CPU is used, a different Decompression algorithm is used, or a// different Image type is used. By placing these Protocols in PEI, the DXE Core remains// generic, and only PEI and the Arch Protocols need to be ported from Platform to Platform,// and from CPU to CPU.// 获得从PEI传递到DXE通过GUIDed HOBs的协议。这些协议不是架构性的。这个实现是在PEI和DXE之间共享代码,以节省闪存空间。// 这些协议也可以作为DXE核心的一部分来实现。但是,在每次使用不同的CPU、不同的解压缩算法或不同的映像类型时,这也需要移植DXE内核。// 通过将这些协议放在PEI中,DXE核心仍然是通用的,只有PEI和Arch协议需要从一个平台移植到另一个平台,从一个CPU移植到另一个CPU。//// Publish the EFI, Tiano, and Custom Decompress protocols for use by other DXE components// 发布EFI、Tiano和自定义解压缩协议,供其他DXE组件使用// 在引导服务环境中安装协议接口列表。这个函数在循环中调用InstallProtocolInterface()。如果出现任何错误,// 此函数添加的所有协议都将被删除。这基本上是一个节省空间的lib函数。Status = CoreInstallMultipleProtocolInterfaces (&mDecompressHandle,&gEfiDecompressProtocolGuid,           &gEfiDecompress,NULL);ASSERT_EFI_ERROR (Status);//// Register for the GUIDs of the Architectural Protocols, so the rest of the// EFI Boot Services and EFI Runtime Services tables can be filled in.// Also register for the GUIDs of optional protocols.// 注册体系结构协议的guid,这样就可以填充EFI引导服务和EFI运行时服务表的其余部分。还要注册可选协议的guid。// 该函数为架构协议和可选协议创建一个事件,每次安装特定类型的协议时触发该事件。CoreNotifyOnProtocolInstallation ();//// Produce Firmware Volume Protocols, one for each FV in the HOB list.// 生产固件卷协议,为HOB列表中的每个FV提供一个。// 这个例程使用FV hobs,并根据需要生成FW_VOL_BLOCK_PROTOCOL实例。Status = FwVolBlockDriverInit (gDxeCoreImageHandle, gDxeCoreST);ASSERT_EFI_ERROR (Status);// 这个例程是驱动程序初始化入口点。它注册一个通知功能。这个通知函数负责动态地构建FV堆栈。Status = FwVolDriverInit (gDxeCoreImageHandle, gDxeCoreST);ASSERT_EFI_ERROR (Status);//// Produce the Section Extraction Protocol// 该函数 节提取代码的入口点。初始化节提取接口的实例,并将其安装到一个新的句柄上。Status = InitializeSectionExtraction (gDxeCoreImageHandle, gDxeCoreST);ASSERT_EFI_ERROR (Status);//// Initialize the DXE Dispatcher// 初始化DXE调度程序PERF_START (NULL,"CoreInitializeDispatcher", "DxeMain", 0) ;// 初始化分配器。初始化FV2协议加入系统时运行的通知函数。CoreInitializeDispatcher ();PERF_END (NULL,"CoreInitializeDispatcher", "DxeMain", 0) ;//// Invoke the DXE Dispatcher//PERF_START (NULL, "CoreDispatcher", "DxeMain", 0);// 这是DXE的主调度程序,当没有更多的驱动程序需要运行时,它就会退出。释放mScheduledQueue,为每个驱动加载并启动一个PE映像。// 搜索mDiscoveredList,查看是否可以将任何驱动程序放置在mScheduledQueue上。如果没有在mScheduledQueue上放置驱动程序,// 则退出该函数。退出时,假设Bds()将被调用,当Bds()退出时,调度程序将被再次调用。CoreDispatcher ();PERF_END (NULL, "CoreDispatcher", "DxeMain", 0);//// Display Architectural protocols that were not loaded if this is DEBUG build// 如果是调试构建,则显示未加载的架构协议DEBUG_CODE_BEGIN ();// 显示未加载的、DXE内核运行所需的架构协议。仅在调试构建中使用。CoreDisplayMissingArchProtocols ();DEBUG_CODE_END ();//// Display any drivers that were not dispatched because dependency expression// evaluated to false if this is a debug build// 如果这是一个调试构建,显示任何没有被分派的驱动程序,因为依赖表达式计算为falseDEBUG_CODE_BEGIN ();// 遍历已发现的列表,查找任何已发现但未加载的驱动程序,因为依赖表达式被评估为false。CoreDisplayDiscoveredNotDispatched ();DEBUG_CODE_END ();//// Assert if the Architectural Protocols are not present.// 如果体系结构协议不存在,则断言。// 该函数如果所有AP服务可用则返回TRUE。Status = CoreAllEfiServicesAvailable ();if (EFI_ERROR(Status)) {//// Report Status code that some Architectural Protocols are not present.// 报告一些架构协议不存在的状态代码。REPORT_STATUS_CODE (EFI_ERROR_CODE | EFI_ERROR_MAJOR,(EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_EC_NO_ARCH));    }ASSERT_EFI_ERROR (Status);//// Report Status code before transfer control to BDS// 向BDS移交控制前报告状态码REPORT_STATUS_CODE (EFI_PROGRESS_CODE,(EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT));//// Transfer control to the BDS Architectural Protocol// 传输控制到BDS架构协议gBds->Entry (gBds);//// BDS should never return//ASSERT (FALSE);CpuDeadLoop ();UNREACHABLE ();
}

那么又是如何从DXE切换到BDS的呢,

可以参考https://blog.csdn.net/robinsongsog/article/details/109003375

BIOS追code之DXE phase相关推荐

  1. BIOS追code之SEC phase

    BIOS追code之路 综述 SEC阶段的功能: SEC阶段执行流程及流程图 Resect Vector部分 EarlyBspInitReal16 Main16 进入SEC功能区 EFI_SEC_PE ...

  2. BIOS追code之PEI phase

    PEI 阶段总述 PEI阶段的功能任务: PEI划分: PEI阶段执行流程: 流程描述及流程图 PEI Phase– Boot Flow 代码分析 PEI service instance PeiCo ...

  3. BIOS初始化PEI至DXE阶段hob学习

    EFI 将启动顺序分成了很多阶段,PEI 和DXE 之间的跨度比较大,PEI 阶段是在RAM-limited 环境运行的,但DXE 阶段是在相对充足的内存空间上运行的. 在内存初始化之前,或者初始化内 ...

  4. UEFI BIOS —— PEI阶段分析

    PEI(Pre-EFI Initialization) -预先EFI初始化)阶段 一.PEI 主要功能 PEI阶段资源依然十分有限,内存到了PEI后期才被初始化.其主要功能是为DXE准备执行环境,将需 ...

  5. AMI POST Code含义

    本文提供 AMI BIOS POST Code的含义,使用AMI BIOS的主要厂家是华硕,一般华硕主板的POST Code都可以参考此文. 以前主板的POST Code 可以插一张PCI Debug ...

  6. 键盘 BIOS 扫描码和 ASCII 码表

    ****************************************************************************** ***               Key ...

  7. AMI CORE8 OEM BIOS

    AMI CORE8 OEM BIOS开发入门 收藏 有段时间有写书的想法,可是一直比较懒,到现在也只写了一个提纲. 提纲也好,毕竟是原创,发出来吧. 第一章 SDL System Descriptio ...

  8. AMI CORE8 OEM BIOS开发入门

    有段时间有写书的想法,可是一直比较懒,到现在也只写了一个提纲. 提纲也好,毕竟是原创,发出来吧. 第一章 SDL System Description Language (SDL) 是AMI CORE ...

  9. BIOS工程师需要掌握的知识

    ACPI规范: ACPI Specification 概述(基于ACPI_Spec_6_4_Jan22)_anqi8955的专栏-CSDN博客 ​​​​​​ACPI Specification 第一章 ...

最新文章

  1. 【数据结构】链式栈的实现(C语言)
  2. Scanpy(一)AnnData数据结构与一些API用法介绍
  3. android之数据存储,Android数据存储之File
  4. 游戏必备组件有哪些_面试必备:2019Vue经典面试题总结(含答案)
  5. 挡土墙计算软件_广联达软件如何计算钢板止水带?
  6. 基于光线追踪的渲染中景深(Depth of field)效果的实现
  7. 如何成为“10倍效率”开发者
  8. TI DSP simulator 种类选择
  9. Windows里Anaconda-Navigator无法打开(解决)
  10. Java IO流学习总结(1)
  11. Python爬虫自己写项目之:爬取火车站的时刻表和票务信息
  12. 《Steve Jobs》
  13. 2019 年各地移动 APT事件总结
  14. TensorFlow中的通信机制——Rendezvous(一)本地传输
  15. 第1015期机器学习日报(2017-06-29)
  16. 网页版VIP邮箱有什么宝藏功能?网页邮箱官网注册入口有哪些?
  17. 400 行 C 代码实现一个虚拟机
  18. 新浪微博授权失败,redirect_url与应用注册的网址不一致
  19. 计算机专业就业率2018,2018年就业质量报告发布,这个专业就业率竟高达100%!
  20. 情侣的网站代码java_一个创意满满的情侣网站

热门文章

  1. Macbook Pro Bootcamp 安装触控板驱动mac-precision-touchpad在Windows系统下实现更好的触控板操作
  2. python menuconfig_如何配置 ESP32 Menuconfig
  3. CCAI 2017 人工智能科学与艺术论坛 | 科学、艺术、女性之间的碰撞
  4. 骨传导蓝牙耳机哪款好、骨传导蓝牙耳机品牌排行榜前五名
  5. RF中for循环要加END?
  6. 电子标签与电子标签库存管理
  7. 《小学生C++趣味编程》Scratch、C++
  8. 餐饮水单打印软件_火锅店连锁企业使用哪款生鲜管理系统软件比较好呢?
  9. 8行代码实现天数倒计时
  10. Nwafu-OJ-1437 Problem h C语言实习题六——6.进制转换函数设计