BIOS追code之DXE phase
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.
涉及元件及功能
- DXE Core,可视为dxe的核心,用来dispatch dxe driver 和产生efi system
table,以提供boot service, runtime service, dxe service,负责DXE基础服务和执行流程. - dxe driver, 被dxe core 所读取,用来做各种硬件的初始化,产生protocol和其他service.
- dxe dispatcher: dxe core 的一部分,以正确的顺序来搜寻和执行dxe driver,负责调度执行DXE驱动,初始化系统设备。 DXE提供的基础服务包括系统表、启动服务、Run Time Services.
- dxe architecture protocol: 由dxe driver所产生,是dxe core和hardware沟通的唯一介面,所以没有install 完全不能开机。
- 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 }
};
- security: 提供 DXE core 验证 firmware volume中的程序是否可用。
- cpu: 提供cpu的service如管理cache,管理中断,取得处理器频率,查询处理器的timer.
typedef struct _EFI_METRONOME_ARCH_PROTOCOL {EFI_METRONOME_WAIT_FOR_TICK WaitForTIck;UINT32 TickPeriod;} EFI_METRONOME_ARCH_PROTOCOL;
提供一个微小的延时,百万分之一秒为单位。
- 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相关推荐
- BIOS追code之SEC phase
BIOS追code之路 综述 SEC阶段的功能: SEC阶段执行流程及流程图 Resect Vector部分 EarlyBspInitReal16 Main16 进入SEC功能区 EFI_SEC_PE ...
- BIOS追code之PEI phase
PEI 阶段总述 PEI阶段的功能任务: PEI划分: PEI阶段执行流程: 流程描述及流程图 PEI Phase– Boot Flow 代码分析 PEI service instance PeiCo ...
- BIOS初始化PEI至DXE阶段hob学习
EFI 将启动顺序分成了很多阶段,PEI 和DXE 之间的跨度比较大,PEI 阶段是在RAM-limited 环境运行的,但DXE 阶段是在相对充足的内存空间上运行的. 在内存初始化之前,或者初始化内 ...
- UEFI BIOS —— PEI阶段分析
PEI(Pre-EFI Initialization) -预先EFI初始化)阶段 一.PEI 主要功能 PEI阶段资源依然十分有限,内存到了PEI后期才被初始化.其主要功能是为DXE准备执行环境,将需 ...
- AMI POST Code含义
本文提供 AMI BIOS POST Code的含义,使用AMI BIOS的主要厂家是华硕,一般华硕主板的POST Code都可以参考此文. 以前主板的POST Code 可以插一张PCI Debug ...
- 键盘 BIOS 扫描码和 ASCII 码表
****************************************************************************** *** Key ...
- AMI CORE8 OEM BIOS
AMI CORE8 OEM BIOS开发入门 收藏 有段时间有写书的想法,可是一直比较懒,到现在也只写了一个提纲. 提纲也好,毕竟是原创,发出来吧. 第一章 SDL System Descriptio ...
- AMI CORE8 OEM BIOS开发入门
有段时间有写书的想法,可是一直比较懒,到现在也只写了一个提纲. 提纲也好,毕竟是原创,发出来吧. 第一章 SDL System Description Language (SDL) 是AMI CORE ...
- BIOS工程师需要掌握的知识
ACPI规范: ACPI Specification 概述(基于ACPI_Spec_6_4_Jan22)_anqi8955的专栏-CSDN博客 ACPI Specification 第一章 ...
最新文章
- 【数据结构】链式栈的实现(C语言)
- Scanpy(一)AnnData数据结构与一些API用法介绍
- android之数据存储,Android数据存储之File
- 游戏必备组件有哪些_面试必备:2019Vue经典面试题总结(含答案)
- 挡土墙计算软件_广联达软件如何计算钢板止水带?
- 基于光线追踪的渲染中景深(Depth of field)效果的实现
- 如何成为“10倍效率”开发者
- TI DSP simulator 种类选择
- Windows里Anaconda-Navigator无法打开(解决)
- Java IO流学习总结(1)
- Python爬虫自己写项目之:爬取火车站的时刻表和票务信息
- 《Steve Jobs》
- 2019 年各地移动 APT事件总结
- TensorFlow中的通信机制——Rendezvous(一)本地传输
- 第1015期机器学习日报(2017-06-29)
- 网页版VIP邮箱有什么宝藏功能?网页邮箱官网注册入口有哪些?
- 400 行 C 代码实现一个虚拟机
- 新浪微博授权失败,redirect_url与应用注册的网址不一致
- 计算机专业就业率2018,2018年就业质量报告发布,这个专业就业率竟高达100%!
- 情侣的网站代码java_一个创意满满的情侣网站
热门文章
- Macbook Pro Bootcamp 安装触控板驱动mac-precision-touchpad在Windows系统下实现更好的触控板操作
- python menuconfig_如何配置 ESP32 Menuconfig
- CCAI 2017 人工智能科学与艺术论坛 | 科学、艺术、女性之间的碰撞
- 骨传导蓝牙耳机哪款好、骨传导蓝牙耳机品牌排行榜前五名
- RF中for循环要加END?
- 电子标签与电子标签库存管理
- 《小学生C++趣味编程》Scratch、C++
- 餐饮水单打印软件_火锅店连锁企业使用哪款生鲜管理系统软件比较好呢?
- 8行代码实现天数倒计时
- Nwafu-OJ-1437 Problem h C语言实习题六——6.进制转换函数设计