capsuleapp将capsule 拷贝到内存,然后用variable 记录内存中的地址,重启后getvariable, 解析出地址,最后根根capsule 类型,调用相关的处理函数。

这里有个问题,为啥重启后,内存中的内容还在,答案就是这个重启是S3. 可以事先设置好,内存中哪些内容是要reserve的。

updateCapsule 函数

updateCapule 用来将capsule 传递给系统固件,包含虚拟地址和物理地址的对应关系。系统根据Capsule 的类型会采取不同的处理方式,如立即处理capsule, 或者系统重启后再对capsule 进行处理。

EFI_STATUS

EFIAPI

UpdateCapsule (

  in efi_capsule_header           **CapsuleHeaderArray,

   in uintn                                    capsuleCount,

    in efi_physical_address          ScatterGatherList

)

ScatterGather 为EFI_CAPSULE_BLOCK_DESCRIPTOR结构链表的物理地址。每个EFI_CAPSULE_BLOCK_DESCRIPTOR结构描述一段连续的物理内存,从而描述出capsule在系统内所有的数据碎片。

 

如果存在要求重启的capsule, 需要将描述物理内存中capsule 数据碎片的scatterGatherList 物理地址保存为capsule NV 变量,系统重启后,PEI 阶段会根据此变量遍历出所有的capsule 数据碎片,并将它们整理成一段连续的内存。

对于capsule_flags_initiate_reset 类型的capsule, 系统会主动进行重启。

注: EFiResetSystem 根据是否存在Capsule Nv 变量从而得知此次系统重启是为capsuleupdae, 从而实现相应的系统重启,如s3, 以确保内存中的capsule数据在重启后不丢失。

 

PEI 阶段CAPSULE的处理

对于需要系统重启的CAPSULE , pei 阶段根据CAPSULE NV 变量来遍历所有的EFI_CAPSULE_BLOCK_DESCRIPTOR节点,从而找出物理内存中所有的数据碎片,并将它们整理在一个连续的物理内存中,并通过HOB报告给BDS阶段。

 

BDS 阶段会对PEI 阶段整理好的CAPSULE 进行相应的处理。一般是在endofdxe

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐