地址映射 Flash BIOS
第一条指令所在位置被称为 Reset Vector,之后进入Reset Vector阶段。
SEC代码流程图如下:
resetVector
追踪下代码执行流程,复位之后第一条指令位置对应
- 进入固件入口。
- 从实模式转换到32位平坦模式(包含模式)。
- 定位固件中的BFV(Boot Firmware Volume)。
- 定位BFV中的SEC映像。
- 如果是64位系统,则从32位模式转换至64位模式。
- 调用SEC入口函数
可以看出,最开始指令是两个啥也不干的NOP和一个短跳转,那么:
1. 为什么开局是CPU不做操作(有时候作为占位符和微调timing用)的NOP,而不是直接有用的JMP开局?
关于为什么是NOP在IA32手册有说明
二进制对应的汇编 执行了多个Nop,然后跳转
2. 为啥一个NOP不够,而要两个?
第二个NOP是占位符,为了让随后的JMP可以16位地址对齐,这样性能高一些。
3. JMP后面的占位符是谁Fixed UP的?
这里实际是要跳转到UEFI的SEC Core中去,但在写代码时候是不知道SEC Core在Flash哪里的,所以这里仅仅占位两个字节。其后,UEFI的BaseTools在产生FV的时候会找到SEC Core的入口,然后填写一个相对地址在这里。具体
在Edk2\BaseTools\Source\C\GenFv\GenFvInternalLib.c
Main16
通过jmp跳转到UefiCpuPkg\ResetVector\Vtf0\Main.asm下的Main16位置
在Reset Vector部分,因为系统还没有RAM,因而不能使用基于栈的程序设计,所有函数调用都使用 jmp 指令模拟
OneTimeCall是宏,用于模拟call指令。例:
OneTimeCall Flat32SearchForBfvBase 怎么定位 BFV ?
We check for a firmware volume at every 4KB address in the top 16MB ; just below 4GB. (Addresses at 0xffHHH000 where H is any hex digit.)
通过file GUID 定位到BFV 中的seccore 0xFF000000-0xfffff000 每4K搜寻
0xffA000定位到ffs2 file Guid
BFV其实就是uefi image的起点,这里就是BFV,结构可以参考uefi手册3.2.1章节
OneTimeCall Flat32SearchForSecEntryPoint 怎么定位 BFV 的 SEC
最后esi 寄存器存放了SEC 的入口地址
SecCore 也被称之为 VTF,被映射到 Boot Firmware Volume (BFV),BFV 的地址被放置在 0xFFFFFFE0 连续的 4 个字节(小端模式)。 SecCore 是一个 FFS firmware file,其文件末端地址与于 BFV 的末端 地址重合。一般会在,reset vector(地址 0xFFFFFFF0)放置一条跳转指令(ResetVec.nasmb),跳转 到 SecCore 入口,其地址为 PlatformSecLib 的 SecEntry.nasm 汇编_ModuleEntryPoint 宏定义处, SecCore 完成基本的初始化之后会调用 PeiCoreEntry.nasm 内的 CallPeiCoreEntryPoint()函数,跳转到 PeiCore。流程就是 Hardware Reset ->跳转指令->SecEntry.nasm (_ModuleEntryPoint)-> PeiCoreEntry.nasm(CallPeiCoreEntryPoin()))
2.2.1 SEC Core功能分析
进入SEC功能区后,首先利用 CAR 技术初始化栈,初始化 IDT,初始化EFI_SEC_PEI_HAND_OFF,将控制权转交
给PEI,并将 EFI_SEC_PEI_HAND_OFF 传递给PEI。
- CAR (Cache ASRAM),在Cashe上开辟一段空间作为内存使用(此时内存尚未初始化,相关C语言运行需要内存和栈的空间) ;
- IDT ( Interrupt Descriptor Table ) 中断描述表,,记录了0~255的中断号和调用函数之间的关系。结构体如下所述:
- 流程:
- EarlyInit16:获取BIST信息
- TransitionFromReal16To32BitFlat:通过CR0和CR4寄存器初始化CAR,及GDT信息获取完成16位实模式转换到32位保护模式
- Flat32SearchForBfvBase:从Top 16M中根据GUID,每4k去匹配查找BFV
- Flat32SearchForSecEntryPoint:从BFV中获取FFS
- 其余部分:如果是64位系统,则从32位模式转换至64位模式;否则启动SecCore EntryPoint
5、SecStartup(SecCore EntryPoint)做的动作
- 初始化FPU
- 初始化IDT
- 获取SecCore参数,往后传递给PEI用
- 启动SecStartupPhase2
6、SecStartupPhase2
一系列查找操作后,最终会调用PeiCore