ROM镜像的备份与还原
实现Setup下面BIOS的备份还原
该功能实现两个方面,备份到U盘、从U盘还原
1、备份到U盘
把rom里的数据复制到盘中
1)找到FAT32的文件系统
每个UEFI系统至少有一个ESP(EFI System Partition)分区,在这个分区上存放了启动文件。既然操作系统加载器以文件的形式存放在ESP分区内,UEFI就需要有读写文件的功能。
Status = gBS->LocateHandleBuffer(ByProtocol,&gEfiSimpleFileSystemProtocolGuid,NULL,&HandleCount,&FileSystemHandles);
2) 通过EFI_SIMPLE_FILE_SYSYTEM_PROTOCOL中的OpenVolume,可以获得FAT文件系统上的根目录句柄,目录句柄(EFI_FILE_PROTOCOL)包含了操作该目录里文件的文件操作接口。
struct _EFI_FILE_PROTOCOL {////// The version of the EFI_FILE_PROTOCOL interface. The version specified/// by this specification is EFI_FILE_PROTOCOL_LATEST_REVISION./// Future versions are required to be backward compatible to version 1.0.///UINT64 Revision;EFI_FILE_OPEN Open;EFI_FILE_CLOSE Close;EFI_FILE_DELETE Delete;EFI_FILE_READ Read;EFI_FILE_WRITE Write;EFI_FILE_GET_POSITION GetPosition;EFI_FILE_SET_POSITION SetPosition;EFI_FILE_GET_INFO GetInfo;EFI_FILE_SET_INFO SetInfo;EFI_FILE_FLUSH Flush;EFI_FILE_OPEN_EX OpenEx;EFI_FILE_READ_EX ReadEx;EFI_FILE_WRITE_EX WriteEx;EFI_FILE_FLUSH_EX FlushEx;
};
文件打开方式
文件打开模式 | 用途 |
---|---|
EFI_FILE_MODE_READ | 文件用于读 |
:EFI_FILE_MODE_WRITE | 文件用于写 |
EFI_FILE_MODE_CREATE | 若文件不存在,则创建: |
3)使用SpiFlashRead读BIOS中的数据,再用EFI_FILE_PROTOCOL->Write写到文件中
写文件
FileIo的Write函数
typedef
EFI_STATUS
(EFIAPI *EFI_FILE_WRITE)(IN EFI_FILE_PROTOCOL *This, //文件句柄IN OUT UINTN *BufferSize, //输入:要写入的数据长度;输出:实际写入的数据长度IN VOID *Buffer //待写入数据);
Write 只能写数据到文件,不能写数据到目录。通过,Write函数会写BufferSize指定的字节数到文件中(实际写的字节数等于指定要写的字节数),仅在遇到错误时(例如,卷上没有多余空间时)会写部分数据到文件,此时bufferSize返回实际写的字节数。
4)使用gEfiSimpleFileSystemProtocolGuid寻找FAT32 分区,如果U盘或者硬盘没有该分区,也无法备份
2、从U盘恢复镜像
从盘中读数据写到rom上
1)找到FAT32的文件系统
每个UEFI系统至少有一个ESP(EFI System Partition)分区,在这个分区上存放了启动文件。既然操作系统加载器以文件的形式存放在ESP分区内,UEFI就需要有读写文件的功能。
Status = gBS->LocateHandleBuffer(ByProtocol,&gEfiSimpleFileSystemProtocolGuid,NULL,&HandleCount,&FileSystemHandles);
2) 通过EFI_SIMPLE_FILE_SYSYTEM_PROTOCOL中的OpenVolume,可以获得FAT文件系统上的根目录句柄,目录句柄(EFI_FILE_PROTOCOL)包含了操作该目录里文件的文件操作接口。
struct _EFI_FILE_PROTOCOL {////// The version of the EFI_FILE_PROTOCOL interface. The version specified/// by this specification is EFI_FILE_PROTOCOL_LATEST_REVISION./// Future versions are required to be backward compatible to version 1.0.///UINT64 Revision;EFI_FILE_OPEN Open;EFI_FILE_CLOSE Close;EFI_FILE_DELETE Delete;EFI_FILE_READ Read;EFI_FILE_WRITE Write;EFI_FILE_GET_POSITION GetPosition;EFI_FILE_SET_POSITION SetPosition;EFI_FILE_GET_INFO GetInfo;EFI_FILE_SET_INFO SetInfo;EFI_FILE_FLUSH Flush;EFI_FILE_OPEN_EX OpenEx;EFI_FILE_READ_EX ReadEx;EFI_FILE_WRITE_EX WriteEx;EFI_FILE_FLUSH_EX FlushEx;
};
3)SPI 接口可以用于连接 FLASH 芯片
struct _EFI_SPI_PROTOCOL {EFI_SPI_INIT Init;EFI_SPI_LOCK Lock;EFI_SPI_ERASE Erase;EFI_SPI_PROGRAM Program;EFI_SPI_READ Read;EFI_SPI_EXECUTE Execute;EFI_SPI_GET_INFO GetInfo;
};
使用 SpiFlashRead 读BIOS中的数据,
使用 SpiFlashBlockErase 擦掉BIOS中的数据,
使用 SpiFlashWrite 把文件数据写入rom里
3、设备区分
如果多个FAT文件块,怎么区分备份到U盘还是SATA盘
Status = gBS->LocateHandleBuffer(ByProtocol,&gEfiSimpleFileSystemProtocolGuid,NULL,&HandleCount,&FileSystemHandles);
for (Index = 0; Index < HandleCount; Index++){
Status = gBS->HandleProtocol (FileSystemHandles[Index],&gEfiBlockIoProtocolGuid,(VOID **) &BlkIo
USB:BlkIo->Media->RemovableMedia = 1
SATA:BlkIo->Media->RemovableMedia = 0