【UEFI系列】FlashLayout


前言

Flash,刷写。
FlashLayout主要是讲它的刷写bin不同区域的分布。
或许有ME区域,是跟bios不同的区域,.map文件可以看具体分段。
这里主要讲bios的FlashLayout。


一、fdf:Flash Description File

EDKII的代码中,它描述对应的bios binary包含哪些东西、binary的大小、guid之类的,例如:
Size=BlockSize x NumBlocks
FD意思是Flash Device,这些fdf最终会被整合到一个总的fdf里。
在这里插入图片描述

$(VARS_SIZE)|$(FVMAIN_SIZE)
FV = FVMAIN_COMPACT

$(SECFV_OFFSET)|$(SECFV_SIZE)
FV = SECFV

这里FV就是它包含的FV,前面的数据是地址,后面是占用大小。
在总的fdf里,这里的显示,各个FV大小加起来就是bios flash image的大小。

二、FV构成

实际上FV命名等都是自己写的,通常会这样命名分配:
FV_NVRAM:存放变量等数据。
(可能会有FV_NVRAM_Backup:实际运行中的 NVRAM 数据的“后备”来源。它不是日常运行中读写的地方,而是在“救急”时使用的只读副本。)
FV_MAIN:存放DXE、BDS阶段的模块代码(DXE_DRIVER)。也有可能是FV_MAIN_WRAPPER,就是多包含了其他比如LOGOROMHOLE(里面存logo.txt或者其他的)什么的。
FV_DATA:一般包点第三方文件。
FV_BB:BB的意思是Boot Block。存放SEC、PEI阶段代码(SEC、PEIM)。

他们的大小都在代码中有地方可以修改,修改之后layout布局就不一样了(FV_MAIN调大的话,其他的FV就要调小,不然不能让rom image总大小不变)。

每个FV都有它自己的guid:
在这里插入图片描述
下面会写它包含的inf:
在这里插入图片描述

FV在flash image文件中的表示

标识开头:_FVH

在这里插入图片描述
有_FVH的地方就是一个FV的开头(header),后面会跟它的guid。
FV_MAIN的ffs是通过加密压缩的,PEI的会原封不动,能在image里通过地址确定guid、找到ffs。

flash image结尾

机器上电执行的第一条指令在0xFFFFFFF0,是物理地址空间中的位置,但此时内存(DRAM)尚未初始化,实际内容由芯片组(如Intel PCH/AMD FCH) 映射到 SPI闪存芯片(BIOS芯片) 的特定区域。
所以最末尾这里,是两个NOP空指令一个JMP指令(或者直接JMP指令,看厂家怎么设计)跳转。
flash layout中可以看到:
在这里插入图片描述

三、ffs:Firmware File System

实际上就是每个模块的统称,一个PEIM、DXE_DRIVER、UEFI_DRIVER都可以是一个ffs,他们被包进对应的FV里(inf文件有写都是什么模块类型)。

如果新添加的模块被成功加进项目中编译,编译完会有对应的ffs。

ffs里的构成

一个imge分为多个FV,一个FV包含多个ffs,一个ffs里有多个section,其中比较常见的section类型如下:

[FV]
 └── [FFS File]
            ├── Section: PE32 (含 PE 文件,实际执行文件)
            ├── Section: UI (描述信息)
            └── Section: DEPEX(依赖信息)

也有包含二进制的section,这是其中之一:
EFI_SECTION_RAW (0x19) Raw Section 原始二进制数据(如 logo、音频、字体等)。

四、EFI_FIRMWARE_VOLUME2_PROTOCOL

这个protocol的功能就是读取flashlayout。
boot的时候,code已经跑起来了,但有的时候还是要去访问flash上的内容。
通过这个protocol就可以读写FV。

它的结构体定义:

struct _EFI_FIRMWARE_VOLUME2_PROTOCOL {
  EFI_FV_GET_ATTRIBUTES    GetVolumeAttributes;
  EFI_FV_SET_ATTRIBUTES    SetVolumeAttributes;
  EFI_FV_READ_FILE         ReadFile; //读FV里的ffs,比如显示logo的时候,先读到内存里,再打到屏幕上
  EFI_FV_READ_SECTION      ReadSection; //把FV里的某个区域的内容,单独的section给读出来
  EFI_FV_WRITE_FILE        WriteFile; //需要去更改flash上的某个内容
  EFI_FV_GET_NEXT_FILE     GetNextFile; //下一个ffs
  ///
  /// Data field that indicates the size in bytes
  /// of the Key input buffer for the
  /// GetNextFile() API.
  ///
  UINT32                   KeySize;
  ///
  /// Handle of the parent firmware volume.
  ///
  EFI_HANDLE               ParentHandle;
  EFI_FV_GET_INFO          GetInfo;
  EFI_FV_SET_INFO          SetInfo;
};

其实就是SPI flash的读写,写是以先擦除再写的方式,单位是4K(一个block),而不是1byte。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萨摩耶饭团

如果我能帮到的话嗯万一呢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值