系统表

对UEFI应用程序和驱动程序开发人员来讲,系统表是最重要的数据结构之一,它是用户空间通往内核空间的通道。有了它,UEFI应用程序和驱动才可以访问UEFI内核、硬件资源和I/O设备。

  • 1 在应用程序和驱动中访问系统表

计算机系统进入DXE阶段后系统表被初始化,因而系统表只能用于DXE阶段以及以后的应用程序和驱动中。系统表是UEFI内核的一个全局结构体,其指针作为程序映像(Image)入口函数的参数传递到用户空间。程序映像(包括UEFI应用程序、DXE驱动程序以及UEFI驱动程序)的入口函数有统一的格式,其函数原型如下:

typedef
EFI_STATUS
(EFIAPI *EFI_IMAGE_ENTRY_POINT) (
IN EFI_HANDLE ImageHandle, //程序映像(Image)的句柄
IN EFI_SYSTEM_TABLE *SystemTable //系统表指针
);
  • 2 系统表指针从内核传递到用户空间的过程

通常,程序映像的入口函数是_ModuleEntryPoint(当一个Image被启动服务的StartImage服务启动时,执行的就是这个入口函数)。当应用程序或驱动加载到内存形成Image后(ImageHandle是这个Image的句柄),_ModuleEntryPoint函数地址被赋值给Image对象的EntryPoint,然后Image->EntryPoint(ImageHandle,SystemTable)会被执行,最终会从Image的入口函数_ModuleEntryPoint执行到模块的入口函数(模块的入口函数是通过.inf文件中ENTRY_POINT指定的那个函数)

1 系统表的组成

*系统表可分为以下6部分:

表头:包括表的版本号、表的CRC校验码等。

固件信息:包括固件开发商名字的字符串和固件的版本号。

标准输入控制台、标准输出控制台、标准错误控制台。

启动服务表

运行时服务表

系统配置表


//@file path: MdePkg\Include\Uefi\UefiSpec.h ///
/// EFI System Table
///
typedef struct {
///
/// The table header for the EFI System Table.
///
EFI_TABLE_HEADER Hdr;
///
/// A pointer to a null terminated string that identifies the vendor
/// that produces the system firmware for the platform.
///
CHAR16 *FirmwareVendor;
///
/// A firmware vendor specific value that identifies the revision
/// of the system firmware for the platform.
///
UINT32 FirmwareRevision;
///
/// The handle for the active console input device. This handle must support
/// EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
///
EFI_HANDLE ConsoleInHandle;
///
/// A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL interface that is
/// associated with ConsoleInHandle.
///
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
///
/// The handle for the active console output device.
///
EFI_HANDLE ConsoleOutHandle;
///
/// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
/// that is associated with ConsoleOutHandle.
///
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
///
/// The handle for the active standard error console device.
/// This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
///
EFI_HANDLE StandardErrorHandle;
///
/// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
/// that is associated with StandardErrorHandle.
///
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr;
///
/// A pointer to the EFI Runtime Services Table.
///
EFI_RUNTIME_SERVICES *RuntimeServices; // 运行时服务
///
/// A pointer to the EFI Boot Services Table.
///
EFI_BOOT_SERVICES *BootServices; // 启动时服务
///
/// The number of system configuration tables in the buffer ConfigurationTable.
///
UINTN NumberOfTableEntries; // CongratulationTable数组的大小
///
/// A pointer to the system configuration tables.
/// The number of entries in the table is NumberOfTableEntries.
///
EFI_CONFIGURATION_TABLE *ConfigurationTable; //系统配置表数组
} EFI_SYSTEM_TABLE;

表头:

// file :  EdkCompatibilityPkg\Foundation\Efi\Include\EfiTypes.h
typedef struct {
UINT64 Signature;
UINT32 Revision;
UINT32 HeaderSize; //是整个表的长度,对系统表来讲,就是sizeof(EFI_SYSTEM_TABLE)
UINT32 CRC32;
UINT32 Reserved;
} EFI_TABLE_HEADER;

系统配置表:

//file : EdkCompatibilityPkg\Foundation\Efi\Include\EfiApi.h
//
// EFI Configuration Table
//
typedef struct {
EFI_GUID VendorGuid; // 配置表标识符
VOID *VendorTable; // 指向配置表的数据
} EFI_CONFIGURATION_TABLE;

启动服务

启动服务也称启动服务表,它由UEFI表头表项组成,表中每一项是一个函数指针,该函数用于提供一项服务。

启动服务是UEFI的核心数据结构,可以分为以下8类:

  • UEFI事件服务

  • 内存管理服务

  • Protocol管理服务

  • 驱动管理服务

  • Image 管理服务

  • ExitBootServices

  • 其他服务。

1 UEFI事件服务

事件是异步操作的基础,使得在 UEFI 系统内可以执行并发操作。UEFI 事件服务包含事件(Event)、定时器(Timer)、任务优先级(TPL)三类服务。

  • 事件服务用于产生、关闭、触发、等待事件和检查事件状态。
  • 定时器服务用于设置定时器属性。
  • 任务优先级服务用于提升、降低当前程序的优先级。
2 内存管理服务

内存管理服务主要提供内存的分配与释放服务、管理系统内存映射。主要包括:AllocatePages、FreePages、GetMemoryMap, AllocatePool、FreePool 5个服务。

3 Protocol管理服务

Protocol 管理服务提供安装与卸载 Protocol 的服务,以及注册 Protocol 通知函书(安装时调用)的服务(详见第八,九章)。

4 Protocol使用类服务

Protocol使用类服务包括 Protocol 的打开与关闭,查找支持 Protocol 的控制器,主要提供 Protocol 使用者使用(详见第四章)

5 驱动管理服务

驱动管理服务包括将驱动安装到控制器的 connect 服务和将驱动从控制器上卸载的 disconnect 服务(详见第九章)。

6 Image 管理服务

Image 管理服务包括加载、卸载、启动、退出 UEFI 应用程序或驱动.

Image 管理服务 作用
LoadImage 加载 .efi 文件至内存并生成 Image
StartImage 启动 Image,调用 Image 的入口函数
Exit 退出Image
UnloadImage 卸载Image
7 ExitBootServices

ExitBootService 用于结束启动服务,该服务成功返回后,系统进入 RT 期。操作系统加载器从启动服务接过对计算机系统的控制权后必须调用该服务

8 其他服务

启动服务中的其他服务

服务名 作用
InstallConfigurationTable 增加、更新、删除系统配置表项
GetNextMonotonicCount 获得系统单调计数器的下一个值
Stall 暂停 CPU 指定的微秒数
SetWatchdogTimer 设置看门狗定时器(指定的时间内若无系统反应,则重启)
CalculateCrc32 计算 CRC32 校验码
CopyMem 复制内存
SetMem 设置指定内存区域的值

运行时服务

从进入DXE阶段运行时服务被初始化,直到操作系统结束,运行时服务都一直存在并向上层(操作系统,操作系统加载器,UEFI应用程序或者UEFI驱动)提供服务。运行时服务主要包括:

  • 时间服务
  • 读写系统变量
  • 虚拟内存服务
  • 其他服务。
1 时间服务

时间服务包括:读取/设置硬件事件、读取/设置唤醒定时器。

GetTime/SetTime

计算机硬件时钟由单独的电池供电,操作系统启动时通过读取硬件时钟获得事件。


//file: MdePkg\Include\Uefi\UefiSpec.h
/**
Returns the current time and date information, and the time-keeping capabilities
of the hardware platform. @param[out] Time A pointer to storage to receive a snapshot of the current time.
@param[out] Capabilities An optional pointer to a buffer to receive the real time clock
device's capabilities. @retval EFI_SUCCESS The operation completed successfully.
@retval EFI_INVALID_PARAMETER Time is NULL.
@retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error. **/
typedef
EFI_STATUS
(EFIAPI *EFI_GET_TIME)(
OUT EFI_TIME *Time, //当前时间
OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL // 时钟硬件的性能
); /**
Sets the current local time and date information. @param[in] Time A pointer to the current time. @retval EFI_SUCCESS The operation completed successfully.
@retval EFI_INVALID_PARAMETER A time field is out of range.
@retval EFI_DEVICE_ERROR The time could not be set due due to hardware error. **/
typedef
EFI_STATUS
(EFIAPI *EFI_SET_TIME)(
IN EFI_TIME *Time
);

UEFI原理与编程(二)的更多相关文章

  1. 【读书笔记】UEFI原理与编程(1)概述及开发环境的搭建

    一.概述: 0.为什么会有这篇文章 说实在的,在2016初的时候,我就萌生了写一个操作系统的念头,但是这对于我一个菜鸟来说,犹如登天. 既然想了就去写,即使最后做不完,也不后悔. 抱着这样的念头,我开 ...

  2. 【原创】高性能网络编程(二):上一个10年,著名的C10K并发连接问题

    1.前言 对于高性能即时通讯技术(或者说互联网编程)比较关注的开发者,对C10K问题(即单机1万个并发连接问题)应该都有所了解."C10K"概念最早由Dan Kegel发布于其个人 ...

  3. trident原理及编程指南

    目录 trident原理及编程指南 一.理论介绍 1.trident是什么? 2.trident处理单位 3.事务类型 二.编程指南 1.定义输入流 2.统计单词数量 3.输出统计结果 4.split ...

  4. Spring事务原理分析-部分二

    Spring事务原理分析-部分二 说明:这是我在蚂蚁课堂学习了余老师Spring手写框架的课程的一些笔记,部分代码代码会用到余老师的课件代码.这不是广告,是我听了之后觉得很好. 课堂链接:Spring ...

  5. 超级干货:动态防御WAF技术原理及编程实战!

    本文带给大家的内容是动态防御WAF的技术原理及编程实战. 将通过介绍ShareWAF的核心技术点,向大家展示动态防御的优势.实现思路,并以编程实战的方式向大家展示如何在WAF产品开发过程中应用动态防御 ...

  6. Linux shell脚本编程(二)

    Linux shell脚本编程(二) 练习:求100以内所有偶数之和; 使用至少三种方法实现; 示例1: #!/bin/bash # declare -i sum=0 #声明一个变量求和,初始值为0 ...

  7. Java并发编程二三事

    Java并发编程二三事 转自我的Github 近日重新翻了一下<Java Concurrency in Practice>故以此文记之. 我觉得Java的并发可以从下面三个点去理解: * ...

  8. Python进阶之面向对象编程(二)

    Python面向对象编程(二) .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB& ...

  9. Linux网络编程(二)

    Linux网络编程(二) 使用多进程实现服务器并发访问. 采用多进程的方式实现服务器的并发访问的经典范例. 程序实现功能: 1.客户端从标准输入读入一行文字,发送到服务器. 2.服务器接收到客户端发来 ...

  10. java GUI编程二

    java基础学习总结--GUI编程(二) 一.事件监听 测试代码一: 1 package cn.javastudy.summary; 2 3 import java.awt.*; 4 import j ...

随机推荐

  1. 神经网络之卷积篇:详解计算机视觉(Computer vision)

    详解计算机视觉 计算机视觉是一个飞速发展的一个领域,这多亏了深度学习.深度学习与计算机视觉可以帮助汽车,查明周围的行人和汽车,并帮助汽车避开它们.还使得人脸识别技术变得更加效率和精准,即将能够体验到或 ...

  2. 探索Amazon S3:存储解决方案的基石(Amazon S3使用记录)

    探索Amazon S3:存储解决方案的基石 本文为上一篇minio使用的衍生版 相关链接:1.https://www.cnblogs.com/ComfortableM/p/18286363 ​ 2.h ...

  3. Python和RPA网页自动化-让非标准下拉框选择指定文本的方法

    以下方"节点审批"下拉框为例 该下拉框没有<select>标签,而是<div><ul><li>标签.分别使用Python和RPA网页 ...

  4. 【Tool】常用软件地址(装机备用)

    浏览器: 360极速 https://browser.360.cn/ee/ 谷歌 https://www.google.cn/chrome/ 社交通讯 微信 https://weixin.qq.com ...

  5. 【金猿人物展】白鲸开源CEO郭炜:数据要素是未来数据“新能源”产业么?

    纵观2023年中国数据行业发展与2024年数据产业趋势,就不得不提到2023年全年国家全年强调的数据要素的概念以及在2023年12月中国国家数据局等17个部门联合印发了<"数据要素×& ...

  6. GOT & PLT 易于理解的个人笔记

    为什么我们用动态链接和GOT表 我们知道静态链接就没那么多事,直接把全部要用的函数都绑定在一起,各个变量和函数之间的偏移量当然能算出来. 但是这也恰恰是静态链接的缺点,相同的代码段反复调用真是太臃肿了 ...

  7. IP一致性论文

    IP一致性:指的是给定输入的图像,要求保持图像中的ID不变,IP可能是Identity Property,要求能够识别出是同一个身份. 目前通过IP的一致性技术,可以用于短视频短剧上,是一个新兴的市场 ...

  8. 神经网络之卷积篇:详解Padding

    详解Padding 为了构建深度神经网络,需要学会使用的一个基本的卷积操作就是padding,让来看看它是如何工作的. 如果用一个3×3的过滤器卷积一个6×6的图像,最后会得到一个4×4的输出,也就是 ...

  9. 8. 从0学ARM-内联汇编、混合汇编、ATPCS规则

    一.gcc 内联汇编 内联汇编即在C中直接使用汇编语句进行编程,使程序可以在C程序中实现C语言不能完成的一些工作,例如,在下面几种情况中必须使用内联汇编或嵌入型汇编. 程序中使用饱和算术运算(Satu ...

  10. Visual Studio Code 重置“不再询问”选项

    有一次使用 VS Code 重命名一个 Python 文件时,VS Code 询问"扩展'Python'希望通过移动此文件来进行重构更改".当时没有多想,选中"不再提问& ...