3111

Firmware Image Download 命令(UEFI EDKII)

Firmware Image Download 命令

在 NVMe 规范中,Firmware Image Download 命令用于从主机向 NVMe 控制器下载固件镜像。该命令是 NVMe 管理命令集的一部分,通常用于更新或安装新的固件。

1. 目的:

从主机传输固件镜像到 NVMe 控制器。

2. 流程:

通常在该命令之后跟随一个 Firmware Commit 命令,指示控制器验证并激活新下载的固件。

3.命令结构:

操作码:0x11(Firmware Image Download 命令)。

CDW10:包含要传输的 dword(4 字节单位)的数量。

CDW11:包含在固件镜像中的偏移量(以 dword 为单位),从这个偏移量开始传输。

4.数据传输:

固件镜像分块传输,每个块的大小在命令中指定。

可能需要多个 Firmware Image Download 命令才能传输整个镜像。

5.Firmware Commit 命令:

操作码:0x10(Firmware Commit 命令)。

在完整的固件镜像下载后发出此命令。

指示控制器验证并可选地激活新的固件镜像。

流程示例

1. 准备工作:

确保固件镜像在主机上可用,并准备传输。确定块大小和传输整个镜像所需的块数量。

2. 下载块:

发出多个 Firmware Image Download 命令,每个命令传输固件镜像的一块。每个命令指定块大小和固件镜像中的偏移量。

3. 提交固件:

在所有块下载完成后,发出 Firmware Commit 命令以验证并激活新的固件。

示例代码

以下是一个简化的伪代码示例,用于说明这一过程:

EFI_STATUS

FirmwareImageDownload(

IN EFI_PCI_IO_PROTOCOL *PciIo,

IN VOID *Buffer,

IN UINTN BufferSize

)

{

EFI_STATUS Status;

NVME_COMMAND Command;

UINT64 Data;

UINTN Offset = 0;

UINTN ChunkSize = 4096; // 每次传输的块大小

UINT8 QueueEntrySize = sizeof(NVME_COMMAND);

// 准备命令

ZeroMem(&Command, sizeof(NVME_COMMAND));

Command.Opcode = FIRMWARE_IMAGE_DOWNLOAD_OPCODE;

Command.Prp1 = (UINT64)(UINTN)Buffer; // 指向要下载的固件数据缓冲区

while (Offset < BufferSize) {

UINTN BytesToTransfer = MIN(ChunkSize, BufferSize - Offset);

Command.Cdword10 = (UINT32)(BytesToTransfer / 4); // 传输的 dword 数量

Command.Cdword11 = (UINT32)(Offset / 4); // 偏移量

// 写入命令到 NVMe 控制器

Status = PciIo->Mem.Write(

PciIo,

EfiPciIoWidthUint32,

NVME_BAR,

NVME_ASQ,

QueueEntrySize,

&Command

);

if (EFI_ERROR(Status)) {

return Status;

}

// 轮询完成队列

// 在这里添加等待完成的代码

Offset += BytesToTransfer;

}

// 提交固件

ZeroMem(&Command, sizeof(NVME_COMMAND));

Command.Opcode = FIRMWARE_COMMIT_OPCODE;

Status = PciIo->Mem.Write(

PciIo,

EfiPciIoWidthUint32,

NVME_BAR,

NVME_ASQ,

QueueEntrySize,

&Command

);

return Status;

}

读写命令:

使用 PciIo->Mem.Write 方法向 NVMe 控制器的命令队列写入命令。地址转换:

将固件缓冲区的虚拟地址转换为物理地址,写入命令结构中的 Prp1 字段。轮询完成:

在写入命令后,轮询或等待完成队列以确保命令成功执行。提交固件:

完成固件镜像下载后,发送固件提交命令以激活新的固件。

总结

通过 Firmware Image Download 命令,可以从主机向 NVMe 控制器下载固件镜像,通常在下载完成后,需要发出 Firmware Commit 命令以验证并激活新固件。该过程包括准备工作、分块下载固件镜像、提交固件等步骤。