Firmware volume Block 驱动

dxe Foundation 的firmware volume block驱动是只读版本的,所以协议中所有写相关的函数setAttribute()

write(), EraseBlock() 都只是简单的返回EFI_UNSUPPORTED.

FwVolBlockDriverInit() 函数

FwVolBlockDriverInit()函数是内置的Firmware Volume Block 驱动的入口函数。

//

// Core needs Firmware Volumes to function

// 

FvHob.Raw = GetHobList();

while (( FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL){

    //

    // Produce an FVB protocol for it 

    //

    ProduceFVBProtocolOnBuffer(FvHob.FirmwareVolume->BaseAddress, FvHob.FirmwareVoluem-Length, NULL, NULL);

    FvHob.Raw = GET_NEXT_HOB(FvHob);

  }

  return EFI_SUCCESS;

函数很简单,取得HOB 表头,然后依次为每一个FV HOB 报告的FV 调用ProduceFVBProtocolOnBuffer() 函数安装Firmware

Volume Block协议。

CoreProcessFirmwareVolume()函数

CoreProcessFirmwareVolume()函数是ProcessFirmwareVolume() DXE Service的实现。这个DXE Service 主要用来处理

Capsule 中的FV.

此函数检查内存中的一个缓冲区中的内容,如果是一个合法的FV, 创建一个新句柄,并在上面安装Firmware Volume 2 协议和

FV device path 协议。新的句柄被返回给调用者。

*FVProtocolHandle = NULL;

 Status = ProduceFVBProtocolOnBuffer(

                (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,

                 (UINT64)Size,

                  NULL,

                  FVProtocolHandle

                  );

//

// Since in our implementation we use register-protocol-notify to put a FV protocol on the FVB protocol

// handle, we can't directly verify that the FV protocol was produced. Therefore here we will check the handle and make sure an // an FV protocol is on it. This indicates that all went well, Otherwise we have to assume that the volume was corrupted somehow.

if (!EFI_ERROR(Status)) {

    Ptr = NULL;

    Status = CoreHandleProtocol(*FVProtocolHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&pTR);

    if (EFI_ERROR(Status) || (Ptr == NULL)) {

        return EFI_VOLUME_CORRUPTED;

    }

  return EFI_SUCCESS;

}

return Status;

预设返回的句柄为NULL。

调用ProduceFVBProtocolOnBuffer() 函数为指定的内存中的FV安装Firmware Volume Block协议的实例。

ProduceFVBProtocolOnBuffer() 函数

此函数为指定的一块内存缓冲区产生Firmware Volume Block2协议。

FvAlignment  = 0;

FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) BaseAddress;

//

//  Validate FV Header, if not as expected, return 

//

if (FwVolHeader->Signature != EFI_FVH_SIGNATURE) {

     return EFI_VOLUME_CORRUPTED;

}

首先检查FV头的签名,如果签名不对,返回卷损坏错误码。

//

// Get FvHeader alignment

//

FvAlignment = 1 << ((FwVolHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);

//

// FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.

//

if (FvAlignment < 8) {

   FvAlignment = 8;

}

if ((UINTN)BaseAddress & FvAlignment != 0) {

    //

   // FvImage buffer is not at its required alignment.

   //

   return EFI_VOLUME_CORRUPTED;

}

根据FV属性中的对齐信息算出实际FV对齐值。

PI 规范规定FFS文件头相对于FV的基地址为8字节对齐。所以FV的对齐值必须大于8.否则无法保证

FFS文件的对齐。

检查FV的基地址是否满足对齐要求,不满足的话,返回卷损坏错误。

//

// Allocate EFI_FW_VOL_BLOCK_DEVICE

FvDev = AllocateCopyPool(sizeof(EFI_VOL_BLOCK_DEVICE), & mFwVolBlock);

   if (FvDev == NULL) {

    return EFI_OUT_OF_RESOURCES;

}

FvbDev->BaseAddress = BaseAddress;

FvbDev->FvbAttributes = FwVolHeader->Attributes;

FvDev->FwVolBlockInstance.ParentHandle = ParentHandle;

为Firmware Volume Block 2协议私有数据结构分配内存,并以m

猜你喜欢

转载自blog.csdn.net/robinsongsog/article/details/105630758