当前位置: 首页 > news >正文

[UEFI]ROM镜像的备份与还原

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

相关文章:

  • 性能优化-OpenCL 介绍
  • 【Linux】-对于信号章节补充的知识点,以及多线程知识的汇总
  • CentOS 7 安装配置MySQL
  • yum方式搭建redis一主两从和哨兵模式
  • 大数据学习之Flink,了解Flink的多种部署模式
  • HTTP 基本概念
  • 【C++】类和对象(上篇)
  • null 和 undefined 的区别?
  • 事务相关的错误
  • ImageMagick使用手册
  • 8. UE5 RPG创建UI(上)
  • 电脑网卡ip修改
  • Linux下软件安装的命令【RPM,YUM】及常用服务安装【JDK,Tomcat,MySQL】
  • 计算机视觉的应用
  • 特征融合篇 | YOLOv8 引入长颈特征融合网络 Giraffe FPN
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • eclipse的离线汉化
  • IndexedDB
  • Java 内存分配及垃圾回收机制初探
  • Java|序列化异常StreamCorruptedException的解决方法
  • Java多线程(4):使用线程池执行定时任务
  • Java精华积累:初学者都应该搞懂的问题
  • JWT究竟是什么呢?
  • linux学习笔记
  • node.js
  • Redis 中的布隆过滤器
  • SegmentFault 2015 Top Rank
  • Spring框架之我见(三)——IOC、AOP
  • XForms - 更强大的Form
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 排序算法之--选择排序
  • 写给高年级小学生看的《Bash 指南》
  • 正则表达式小结
  • hi-nginx-1.3.4编译安装
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • "无招胜有招"nbsp;史上最全的互…
  • (4.10~4.16)
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (附源码)计算机毕业设计高校学生选课系统
  • (十六)一篇文章学会Java的常用API
  • (一)基于IDEA的JAVA基础1
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .net framework4与其client profile版本的区别
  • .net websocket 获取http登录的用户_如何解密浏览器的登录密码?获取浏览器内用户信息?...
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .net 微服务 服务保护 自动重试 Polly
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)
  • .NET企业级应用架构设计系列之开场白
  • :“Failed to access IIS metabase”解决方法
  • @SentinelResource详解
  • [\u4e00-\u9fa5] //匹配中文字符
  • [Android]一个简单使用Handler做Timer的例子
  • [Android学习笔记]ScrollView的使用