Cstyle的UEFI导读之SEC --- Reset Vector(下篇)

   接着上一篇, 这次还是从0xFFFFFFF0这个位置开始,在开始之前先声明下,我要分析的ROM大小为8MByte,所以从下图1的左边的地址列可以看出最大的地址是0x007ffff0这个地址就是前面说的0xfffffff0,可以把这两个地址完全对等来看待,同理0x007fffff就等于0xfffffff。下面的计算和地址(32bit)都是基于这个逻辑,不再赘述。我们这次关注的点不是第一条指令,而重点关注FwVol所以我们需要从0xfffffffc(0x007ffffc)开始,我们获取到它的值是0xfff40000,然后再找 【0xfff40000】 是什么?答案在下面,请接着图2往下看:

                                                                          图1
 
    计算公式是这样的:【0xfff40000】=0x007fffff - (0xffffffff-【0xfffffffc】)=0x007fffff-(0xffffffff-0xfff40000)=0x00740000,其中【xxxxxxxx】表示取值的意思,其他的是基本的四则运算,实在不会算的话,你可以回去找那些曾经教过你数学的体育老师把你的学费要回来了^_^。图2是我们从【0xfff40000】读到的东西,这个是什么呢,大家可以仔细看下,跟上一篇讲的很类似,这里其实就是一个FV的开始的文件头,一个完整的BIOS应该是由N多个的FV组成的,这一个应该算是最重要的一个,我们把他称之为BFV,是不是很熟悉,上一篇我们提到了一个叫做VTF的东西,这次我们要说说这个BFV,好开始了,我们先打开那一堆的intel大叔们写的E文文档,一个一个字节来对着看,顺便检验下那堆文档是否真的是对的,或许他们写的文档和code不匹配也说不准,只有自己真正的读了才知道。
对着下面的FV header/File header/Section header的结构和BIOS rom我们很容易就能读出端倪来,从下图我们大概可以读出如下信息:
1.该FV是基于FFS2的文件格式。
2.该FV的长度是0xc0000Byte
3.该FV的文件属性是0xfffe0300
4.该FV的文件头长度为0x48
5.该FV包含的logical block 数量为0x0c
6.该FV的logical block大小为0x1000(4KByte,LBAS xLBAN=4K x 0x0c =0xc0000)
7.0x007400408开始就是这个FV里面包含的第一个File,可以根据上一篇的方法对照EFI_FFS_FILE_HEADER和EFI_COMMON_SECTION_HEADER来一个一个递归的找出来,细节可看PI 1.3
8.疑问:标号为1的位置是,ZeroVector在spc上The first 16 bytes are reserved to allow for the reset vector of processors whose reset vector is at address 0,看了其他的几个FV这个位置都是0,但是BFV这里是非零值,不知道用意何在,或许是记录的某个地址,供PEICore来参考,或许是一个jmp的目标地址???

typedef struct {
        UINT8      ZeroVector[16];
        EFI_GUID  FileSystemGuid;
        UINT64     FvLength;
        UINT32     Signature;
        EFI_FVB_ATTRIBUTES_2     Attributes;
        UINT16     HeaderLength;
        UINT16     Checksum;
        UINT16      ExtHeaderOffset;
        UINT8         Reserved[1];
        UINT8         Revision;
    EFI_FV_BLOCK_MAP BlockMap[];
}  EFI_FIRMWARE_VOLUME_HEADER;

typedef struct {
        EFI_GUID     Name;
        EFI_FFS_INTEGRITY_CHECK     IntegrityCheck;
        EFI_FV_FILETYPE     Type;
        EFI_FFS_FILE_ATTRIBUTES     Attributes;
        UINT8     Size[3];
        EFI_FFS_FILE_STATE     State;
}   EFI_FFS_FILE_HEADER;

typedef struct {
    UINT8 Size[3];
    EFI_SECTION_TYPE Type;
}   EFI_COMMON_SECTION_HEADER;

Cstyle的UEFI导读之SEC --- Reset Vector(下篇)_第1张图片
                                                        图2
 
    至此,我们对BIOS ROM的分析算是告一段落,分析ROM只是一个手段,下面我们看下通过分析ROM我们能得到那些其他的信息。我们来看SECcore和PEICore是如果使用这些信息的。

/// EFI_SEC_PEI_HAND_OFF structure holds information about
/// PEI core's operating environment, such as the size of location of
/// temporary RAM, the stack location and BFV location.
typedef struct   _EFI_SEC_PEI_HAND_OFF {
  /// Size of the data structure.
  UINT16  DataSize;
  /// Points to the first byte of the boot firmware volume, 
  /// which the PEI Dispatcher should search for 
  /// PEI modules.
   VOID    *BootFirmwareVolumeBase;
  /// Size of the boot firmware volume, in bytes.
  UINTN   BootFirmwareVolumeSize;
  /// Points to the first byte of the temporary RAM.
   VOID    *TemporaryRamBase;
  /// Size of the temporary RAM, in bytes.
  UINTN   TemporaryRamSize;
  /// Points to the first byte of the temporary RAM 
  /// available for use by the PEI Foundation. The area 
  /// described by PeiTemporaryRamBase and PeiTemporaryRamSize 
  /// must not extend outside beyond the area described by
  /// TemporaryRamBase & TemporaryRamSize. This area should not
  /// overlap with the area reported by StackBase and 
  /// StackSize.
  VOID    *PeiTemporaryRamBase;
  /// The size of the available temporary RAM available for 
  /// use by the PEI Foundation, in bytes.
    UINTN   PeiTemporaryRamSize;
  /// Points to the first byte of the stack. 
  /// This are may be part of the memory described by 
  /// TemporaryRamBase and TemporaryRamSize 
  /// or may be an entirely separate area.
  VOID    *StackBase;
  /// Size of the stack, in bytes.
  UINTN   StackSize;
} EFI_SEC_PEI_HAND_OFF;

    上面有一个数据结构EFI_SEC_PEI_HAND_OFF,这个是UEFI当中在SEC阶段最最重要的一个数据结构,他完成了从汇编语言执行环境向C语言执行环境的蜕变。在此之前,我们的SECCore完成了cpu,chipset的最基本的初始化包括但不限于:cpu模式的切换,RCBA,PCIEXBAR,MCHBAR,DMIBAR,Interrupt,SPI,ROM Decode,PMBase,GPIOBase,CMOS,Microcode的加载,CAR的设置等,甚至还可以在里面完成一些OEM的特殊功能,比如设置一个PCH的引脚为GPO,然后在POST过程中用示波器来测量信号变化,以此来测量POST的各个阶段的耗时;对各种需要上电就比较早做设定的外设进行设定等等。
    这个数据结构里面有一项很重要的部分就是用来指示BFV的位置的(这个就是了 BootFirmwareVolumeBase),SECCore调用  call dword PTR DataSector:[0FFFFFFE0h]服务,完成从SEC阶段到PEI阶段的正式权利交接,然后大权就由PEICore来掌控,当然在交接之前必须的的一些前提条件是要必须完成的,就类似于新旧政府权利交接之前,先的把各种绊脚石移除了。这个相信大家都懂的。
        好了SEC的部分就先这样,暂时先这样,下面来研究PEICore。


转载请注明出处
[email protected]  //  http://blog.csdn.net/CStyle_0x007

你可能感兴趣的:(Cstyle的UEFI导读)