UEFI启动阶段的SEC

SEC阶段(安全校验)

 SEC阶段是平台初始化的第一个阶段,计算机系统加载或重启后进入这个阶段

SEC阶段功能

主要是这下面几个功能

这是一段红色的文本。

*接收并除了系统启动和重启信号:系统加电、重启、运行异常信号
*初始化临时存储区域:CAR(cache as ram),Cache被配置为no-eviction模式.
*作为可信系统的根
*传递参数给下一阶段:系统当前状态、可启动固件(Boot Firmware Volume)的临时RAM区域的地址和大小、栈的地址和大小

提示:详细功能解释如下:
1、接收并处理系统启动信号:系统加电信号、系统重启信号、系统运行过程中的严重异常信号。
2、初始化临时存储区域:当系统运行在SEC阶段时,仅CPU和CPU内部资源被初始化,各种外部设备和内存都没有被初始化,因而系统需要一些临时的RAM区域,用于代码和数据的存取,我们将之称为临时RAM,以示与内存的区别。这些临时的RAM只能位于CPU内部。最常用的临时RAM就是Cache,当Cache被配置为no-eviction模式时,可以作为内存使用,读命中时返回Cache中的数据,读缺失时不会向主存发出缺失事件;写命中时将数据写入Cache,写缺失时不会向主存发出缺失事件,这种计数称为CAR(Cache As Ram)
3、作为可信系统的根:作为取得对系统控制权的第一部分,SEC阶段是整个可信系统的根。SEC能被系统信任,以后各个阶段才有被信任的基础。通常,SEC在将控制权转移给PEI之前,可以验证PEI
4、传递系统参数给下一个阶段(即PEI):SEC阶段的一切工作都是为了PEI阶段做准备,最终SEC要把控制权转交给PEI,同时要将现阶段的成果汇报给PEI。汇报的手段就是将如下信息作为参数传递给PEI的入口函数。
• 系统当前的状态,PEI可以根据这些状态判断系统的健康状况。
• 可启动固件的地址和大小
• 临时RAM区域的地址和大小
• 栈的地址和大小

SEC阶段执行流程

 以临时RAM初始化为界,SEC的执行又分为两大部分:临时的RAM生效之前称为Reset Vector阶段,临时RAM生效后调用SEC入口函数从而进入SEC功能区。

大致如下图:
在这里插入图片描述

Reset Vector

 UEFI第一条指令所在的位置被称为ResetVector,之后便会进入ResetVector执行阶段。Reset Vector的执行流程如下:
• 进入UEFI固件入口
• 从实模式转换到32位保护模式
• 定位固件中的Boot Firmware Volume
• 定位BFV中的SEC映像
• 若是64位系统,从32位模式转换成64位模式
• 调用SEC入口函数

在Reset Vector部分,因为系统还没有栈的概念,所以不能使用基于栈的程序设计,需要使用 汇编语言来完成一些操作。

注:
第一条指令:所在的位置是0xFFFFFFF0(这个地址有个专有的名称Reset Vector)
实模式:程序中用到的地址都是真实的物理地址,即程序员可见的地址完全是真实的内存地址,在实模式下所有的段都是可以读、写、可执行的。
保护模式:保护进程地址空间,程序A的地址空间,不能随意被程序B访问。

Reset Vector的执行流程代码分析:

1、Reset Vector进入UEFI固件的入口

; The VTF signature
;
; VTF-0 means that the VTF (Volume Top File) code does not require
; any fixups.
;
vtfSignature:
    DB      'V', 'T', 'F', 0

ALIGN   16

resetVector:
;
; Reset Vector
;
; This is where the processor will begin execution
;
    nop
    nop
    jmp     EarlyBspInitReal16

ALIGN   16

fourGigabytes:

2、通过jmp跳转到Init16.asm的EarlyBspInitReal16位置
注:
DI(destination index)目的变址寄存器:用做隐含的目的串地址,默认在ES中。根据DI来确定是BSP(boot strap processor)启动还是AP(application processor)启动。
ES(Extra segment register)额外的段寄存器:它通常跟DI一起用来做指针使用。
BP(Base Pointer)基指针:通常BP用来保存使用局部变量的地址。

EarlyBspInitReal16:
    mov     di, 'BP'
    jmp     short Main16

;
; @param[out] DI    'AP' to indicate application processor
;
EarlyApInitReal16:
    mov     di, 'AP'
    jmp     short Main16
;

3、Main16(从实模式转换到32位保护模式;找到UEFI固件中的BFV;从BFV中找到Sec的镜像;如果是64位系统,则从32位模式转换至64位模式)
•EarlyInit16:获取BIST信息
•TransitionFromReal16To32BitFlat:通过CR0和CR4寄存器初始化CAR,及GDT信息获取完成16位实模式转换到32位保护模式
•Flat32SearchForBfvBase:从Top 16M中根据GUID,每4k去匹配查找BFV
•Flat32SearchForSecEntryPoint:从BFV中获取FFS
•其余部分:如果是64位系统,则从32位模式转换至64位模式;否则启动SecCore EntryPoint

BITS    16

;
; Modified:  EBX, ECX, EDX, EBP
;
; @param[in,out]  RAX/EAX  Initial value of the EAX register
;                          (BIST: Built-in Self Test)
; @param[in,out]  DI       'BP': boot-strap processor, or
;                          'AP': application processor
; @param[out]     RBP/EBP  Address of Boot Firmware Volume (BFV)
; @param[out]     DS       Selector allowing flat access to all addresses
; @param[out]     ES       Selector allowing flat access to all addresses
; @param[out]     FS       Selector allowing flat access to all addresses
; @param[out]     GS       Selector allowing flat access to all addresses
; @param[out]     SS       Selector allowing flat access to all addresses
;
; @return         None  This routine jumps to SEC and does not return
;
Main16:
    OneTimeCall EarlyInit16

    ;
    ; Transition the processor from 16-bit real mode to 32-bit flat mode
    ;
    OneTimeCall TransitionFromReal16To32BitFlat

BITS    32

    ;
    ; Search for the Boot Firmware Volume (BFV)
    ;
    OneTimeCall Flat32SearchForBfvBase

    ;
    ; EBP - Start of BFV
    ;

    ;
    ; Search for the SEC entry point
    ;
    OneTimeCall Flat32SearchForSecEntryPoint

    ;
    ; ESI - SEC Core entry point
    ; EBP - Start of BFV
    ;

%ifdef ARCH_IA32

    ;
    ; Restore initial EAX value into the EAX register
    ;
    mov     eax, esp

    ;
    ; Jump to the 32-bit SEC entry point
    ;
    jmp     esi

%else

    ;
    ; Transition the processor from 32-bit flat mode to 64-bit flat mode
    ;
    OneTimeCall Transition32FlatTo64Flat

BITS    64

    ;
    ; Some values were calculated in 32-bit mode.  Make sure the upper
    ; 32-bits of 64-bit registers are zero for these values.
    ;
    mov     rax, 0x00000000ffffffff
    and     rsi, rax
    and     rbp, rax
    and     rsp, rax

    ;
    ; RSI - SEC Core entry point
    ; RBP - Start of BFV
    ;

    ;
    ; Restore initial EAX value into the RAX register
    ;
    mov     rax, rsp

    ;
    ; Jump to the 64-bit SEC entry point
    ;
    jmp     rsi

%endif
SEC Core

 进入SEC功能区后,首先利用 CAR 技术初始化栈,初始化 IDT,初始化EFI_SEC_PEI_HAND_OFF,将控制权转交给PEI,并将 EFI_SEC_PEI_HAND_OFF 传递给PEI。
注:
CAR (Cache As RAM):在Cache上开辟一段空间作为内存使用(此时内存尚未初始化,相关C语言运行需要内存和栈的空间);
IDT ( Interrupt Descriptor Table ) 中断描述表:记录了0~255的中断号和调用函数之间的关系。

提示:
在这里插入图片描述
 _SEC_IDT_TABLE在IDT之前保留8个字节来存储 EFI_PEI_SERVICES**,因为 IDT 基础地址应该是 8 字节对齐。注意:对于IA32,只有IDT前面的4个字节用于存储EFI_PEI_SERVICES**。如下:

typedef struct _SEC_IDT_TABLE {
  //
  // Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT base
  // address should be 8-byte alignment.
  // Note: For IA32, only the 4 bytes immediately preceding IDT is used to store
  // EFI_PEI_SERVICES**
  //
  UINT64                      PeiService;
  IA32_IDT_GATE_DESCRIPTOR    IdtTable[SEC_IDT_ENTRY_COUNT];
} SEC_IDT_TABLE;

EFI_SEC_PEI_HAND_OFF实际上就是一个结构体,是UEFI当中在SEC阶段最重要的一个数据结构,将环境从以汇编语言执行转向C语言执行。如下:

> 这里是引用

跳转到SEC入口地址

在这里插入图片描述
根据最后的call指令找到跳转到SecCoreStartupWithStack函数,在IA32平台下的入口函数在EDKII\Edk2\UefiPayloadPkg\SecCore\SecMain.c中SecStartup(SecCore EntryPoint)做的动作如下:
•初始化FPU
•初始化IDT
•获取SecCore参数,往后传递给PEI用
•启动SecStartupPhase2

PEI入口函数

PeiCoreEntryPoint这个值就是一个64位的虚拟地址,这个地址是PEI阶段的Entry point函数的入口地址,然后通过(*PeiCoreEntryPoint) (SecCoreData, PpiList); 跳转到PEI阶段。如下:
在这里插入图片描述
UEFI最重要的特点就是模块化设计,模块载入内存生成Image。Image的入口函数是_ModuleEntryPoint。而PEI也是一个模块, PEI入口函数如下图:
在这里插入图片描述
ProcessModuleEntryPointList的细节部分如下:
在这里插入图片描述
最终调用PEI入口函数 PeiCore(edk2\MdeModulePkg\Core\Pei\PeiMain\PeiMain.c)

总结:站在巨人的肩膀上学习总结

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值