文章目录
前言
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。
2万+

被折叠的 条评论
为什么被折叠?



