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
SecStartup
SwitchStack
PayloadMain

最开始的SecEntry来自通用的Lib:ModuleEntryLib

流程

OsLoader的基本流程:

开始
获取启动项
进入Shell?
进入Shell
结束
遍历启动项
进入启动项?
CPU挂起

最终如果没有找到启动项就会挂起。

遍历启动项是通过一个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(),其流程如下:

以上是关于UEFI实战SBL中的OsLoader代码分析的主要内容,如果未能解决你的问题,请参考以下文章

UEFI实战SlimBootloader代码流程分析

UEFI实战SlimBootloader定制化

UEFI实战SlimBootloader定制化

UEFI实战SlimBootloader集成UEFI Payload

UEFI实战SlimBootloader集成UEFI Payload

UEFI实战SlimBootloader使用