Security core(SecCore) 是平台初始化的第一个阶段。它通常需要处理所有的系统启动/重启动的异常
(Exception) 事件,例如系统冷启动,同时,它还会在主存储被初始化之前,构建少量临时存储单元,
用于系统在软件结构中所需的堆栈等。由于它是系统运行的第一阶段,它还可以是所有安全校验的根。当系统
成功完成第一步的SEC初始化,它将把系统控制权交给PeiCore。 当系统启动,CPU 的指针指向Oxf:0xffe0的
实模式地址并开始执行该地址下的代码。代码首先通过Boot Firmware Volume(BFV) 的唯一标识找到它的基地址,
进而找到SecCore 的入口函数 _ModuleEntryPoint() , 然后将控制交给_ModuleEntryPoint().
全局变量
mTemporaryRamSupportPpi | EFI_PEI_TEMPORYARY_RAM_SUPPORT_PPI | 堆栈从cache as Ram 切换到memory 的PPI |
mPrivateDispatchTable | EFI_PEI_PPI_DESCRIPTOR | 堵栈从cacha as RAM 切换到memory 的ppi 的描述符 |
mIdtEntryTemplate | IA32_IDT_GATE_DESCRIPTOR | IDT 中断门描述符 |
SecCore 关键数据结构
SEC_IDT_TABLE 数据结构
Sec 阶段的中断描述表
typedef struct _SEC_IDT_TABLE {
EFI_PEI_SERVICES *PeiService;
IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
} SEC_IDT_TABLE;
EFI_FIRMWARE_VOLUME_HEADER 数据结构
///
/// Describes the features and layout of the firmware volume.
///
typedef struct {
///
/// The first 16 bytes are reserved to allow for the reset vector of
/// processors whose reset vector is at address 0.
///
UINT8 ZeroVector[16];
///
/// Declares the file system with which the firmware volume is formatted.
///
EFI_GUID FileSystemGuid;
///
/// Length in bytes of the complete firmware volume, including the header.
///
UINT64 FvLength;
///
/// Set to EFI_FVH_SIGNATURE
///
UINT32 Signature;
///
/// Declares capabilities and power-on defaults for the firmware volume.
///
EFI_FVB_ATTRIBUTES_2 Attributes;
///
/// Length in bytes of the complete firmware volume header.
///
UINT16 HeaderLength;
///
/// A 16-bit checksum of the firmware volume header. A valid header sums to zero.
///
UINT16 Checksum;
///
/// Offset, relative to the start of the header, of the extended header
/// (EFI_FIRMWARE_VOLUME_EXT_HEADER) or zero if there is no extended header.
///
UINT16 ExtHeaderOffset;
///
/// This field must always be set to zero.
///
UINT8 Reserved[1];
///
/// Set to 2. Future versions of this specification may define new header fields and will
/// increment the Revision field accordingly.
///
UINT8 Revision;
///
/// An array of run-length encoded FvBlockMapEntry structures. The array is
/// terminated with an entry of {0,0}.
///
EFI_FV_BLOCK_MAP_ENTRY BlockMap[1];
} EFI_FIRMWARE_VOLUME_HEADER;
EFI_SEC_PEI_HAND_OFF 数据结构含有sec-pei core 握手交接控制权时所需信息,如临时RAM 的地址和大小,栈的地
址和boot Firmware Volume 的址址,这些信息pei core 执行时都需要用到。
///
/// EFI_SEC_PEI_HAND_OFF structure holds information about
/// PEI core's operating environment, such as the size of location of
/// temporary RAM, the stack location and BFV location.
///
typedef struct _EFI_SEC_PEI_HAND_OFF {
///
/// Size of the data structure.
///
UINT16 DataSize;
///
/// Points to the first byte of the boot firmware volume,
/// which the PEI Dispatcher should search for
/// PEI modules.
///
VOID *BootFirmwareVolumeBase;
///
/// Size of the boot firmware volume, in bytes.
///
UINTN BootFirmwareVolumeSize;
///
/// Points to the first byte of the temporary RAM.
///
VOID *TemporaryRamBase;
///
/// Size of the temporary RAM, in bytes.
///
UINTN TemporaryRamSize;
///
/// Points to the first byte of the temporary RAM
/// available for use by the PEI Foundation. The area
/// described by PeiTemporaryRamBase and PeiTemporaryRamSize
/// must not extend outside beyond the area described by
/// TemporaryRamBase & TemporaryRamSize. This area should not
/// overlap with the area reported by StackBase and
/// StackSize.
///
VOID *PeiTemporaryRamBase;
///
/// The size of the available temporary RAM available for
/// use by the PEI Foundation, in bytes.
///
UINTN PeiTemporaryRamSize;
///
/// Points to the first byte of the stack.
/// This are may be part of the memory described by
/// TemporaryRamBase and TemporaryRamSize
/// or may be an entirely separate area.
///
VOID *StackBase;
///
/// Size of the stack, in bytes.
///
UINTN StackSize;
} EFI_SEC_PEI_HAND_OFF;
数据结构关系图
FindAndReportEntryPoints函数在flash 中寻找pei core 并返回其入口地址,同时也会寻找sec 和pei core 的相关调试信息,
如果远程高度打开就显示相关调试信息。
//
// Find SEC Core and PEI Core image base
//
Status = FindImageBase (BootFirmwareVolumePtr, &SecCoreImageBase, &PeiCoreImageBase);
ASSERT_EFI_ERROR (Status);
在flash 中寻找PEI Core
//
// Find PEI Core entry point
//
Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
if (EFI_ERROR (Status)) {
*PeiCoreEntryPoint = 0;
}
在已经找到的PEI Core 中寻找执行的入口地址。
SecCore 关键函数
SecCoreStartupWithStack 函数
SecCoreStartupWithStack 初始化IDT, 初始化SEC-PEI 交接的状态信息,以及初始化debug agent 用用sec/pei 阶段用作
SEC/PEI 阶段的源代码调试。