UEFI实战SBL中的OsLoader代码分析
Posted jiangwei0512
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UEFI实战SBL中的OsLoader代码分析相关的知识,希望对你有一定的参考价值。
入口
对应的模块是PayloadPkg\\OsLoader\\OsLoader.inf,在BootloaderCorePkg\\BootloaderCorePkg.dsc中的声明:
PayloadPkg/OsLoader/OsLoader.inf
<PcdsFixedAtBuild>
gPlatformCommonLibTokenSpaceGuid.PcdDebugOutputDeviceMask | $(DEBUG_OUTPUT_DEVICE_MASK)
<LibraryClasses>
MemoryAllocationLib | BootloaderCommonPkg/Library/FullMemoryAllocationLib/FullMemoryAllocationLib.inf
PayloadEntryLib | PayloadPkg/Library/PayloadEntryLib/PayloadEntryLib.inf
PayloadSupportLib | PayloadPkg/Library/PayloadSupportLib/PayloadSupportLib.inf
BootloaderLib | PayloadPkg/Library/PayloadLib/PayloadLib.inf
PlatformHookLib | PayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf
AbSupportLib | PayloadPkg/Library/AbSupportLib/AbSupportLib.inf
SblParameterLib | PayloadPkg/Library/SblParameterLib/SblParameterLib.inf
TrustyBootLib | PayloadPkg/Library/TrustyBootLib/TrustyBootLib.inf
OsLoader.inf的实现主体:
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = OsLoader
FILE_GUID = A257AA67-53F3-491B-8CFF-E9A4E2E2A514
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
#
# This flag specifies whether HII resource section is generated into PE image.
#
UEFI_HII_RESOURCE_SECTION = TRUE
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
BlockIoTest.h
OsLoader.h
OsLoader.c
BootOption.c
BootConfig.c
LoadImage.c
PerformanceData.c
BootParameters.c
BlockIoTest.c
KeyManagement.c
PreOsSupport.c
ModService.c
ExtraModSupport.c
比较奇怪的是没有入口,不过似乎SBL的模块都没有入口。
通过代码可以找到OsLoader的入口:
/**
Payload main entry.
This function will continue Payload execution with a new memory based stack.
@param Param parameter passed from SwitchStack().
@param PldBase payload base passed from SwitchStack().
**/
VOID
EFIAPI
PayloadMain (
IN VOID *Param,
IN VOID *PldBase
)
实际上SBL的模块入口是按照如下的调用逻辑:
最开始的SecEntry
来自通用的Lib:ModuleEntryLib
。
流程
OsLoader的基本流程:
最终如果没有找到启动项就会挂起。
遍历启动项
是通过一个while循环来完成的:
while (BootIdx < OsBootOptionList->OsBootOptionCount)
mCurrentBoot = CurrIdx;
DEBUG ((DEBUG_INFO, "\\n======== Try Booting with Boot Option %d ========\\n", CurrIdx));
// Get current boot option and try boot
CopyMem ((VOID *)&OsBootOption, (VOID *)&OsBootOptionList->OsBootOption[CurrIdx], sizeof (OS_BOOT_OPTION));
BootOsImage (&OsBootOption);
// De-init the current boot devices
// If USB keyboard console is used, don't DeInit USB yet at this moment.
// It will be handled just before transfering to OS.
if (!((OsBootOption.DevType == OsBootDeviceUsb) &&
((PcdGet32 (PcdConsoleInDeviceMask) & ConsoleInUsbKeyboard) != 0)))
MediaInitialize (0, DevDeinit);
if (OsBootOptionList->RestrictedBoot != 0)
// Restricted boot should not try other boot option
break;
else
// Move to next boot option
CurrIdx = GetNextBootOption (OsBootOptionList, CurrIdx);
if (CurrIdx >= OsBootOptionList->OsBootOptionCount)
CurrIdx = 0;
BootIdx++;
这里最重要的函数是BootOsImage()
,其流程如下: