系统表

对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. 很呆的一个问题:我的新项目又找不到mapper这个bean了

    1.选springboot版本 <properties> <java.version>8</java.version> <project.build.sour ...

  2. 区块链DApp学习开发入门 视频

    学习视频: https://www.bilibili.com/video/BV13E411P7km?p=1 https://www.bilibili.com/video/BV14z4y1Z7Jd?p= ...

  3. 在 MindSpore 中 dataset_sink_mode 的设置对算法的性能有多少影响呢???

    参考代码: https://www.cnblogs.com/devilmaycry812839668/p/14971668.html dataset_sink_mode=True  时,我们可以理解是 ...

  4. Chrome(Google) 浏览器安装Vue2、Vue3插件方法 (亲测有效)

    1.背景 2.步骤 步骤一:下载插件 网站:https://chrome.zzzmh.cn/#/search 百度网盘下载: 链接:https://pan.baidu.com/s/1xdEK-7qVx ...

  5. maven实战教程-含视频讲解

    1.背景 2.什么是maven? 通俗的说就是,不用手动拷贝jar包,帮我们管理项目结构,只需要配置坐标,自动从中央仓库下载(其他介绍请百度...). 3.Maven的安装与配置 注意:Maven在使 ...

  6. Linux的命令合集

    Linux常用的命令 这里分享一个博客,里面有很丰富的Linux的常用指令. https://blog.csdn.net/qq_23329167/article/details/83856430. 然 ...

  7. 无缝融入,即刻智能[一]:Dify-LLM大模型平台,零编码集成嵌入第三方系统,42K+星标见证专属智能方案[含ollama部署]

    无缝融入,即刻智能[一]:Dify-LLM大模型平台,零编码集成嵌入第三方系统,42K+星标见证专属智能方案 1.Dify 简介 1.1 功能情况 Dify,一款引领未来的开源大语言模型(LLM)应用 ...

  8. games101 作业6 详解SAH

    games101 作业6 详解SAH 可参考资料:https://www.pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/ ...

  9. GDB原始函数信息中获取函数名

    示例: kwdbts::Logger::log(kwdbts::_kwdbContext_t*, kwdbts::KwdbModule, kwdbts::LogSeverity, char const ...

  10. Devexpress PdfViewer汉化及隐藏右键菜单

    先看效果图 1.效果图 隐藏了打印与文档属性功能 2.原图 1.关键事件 PopupMenuShowing public From() { InitializeComponent(); //弹出菜单加 ...