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

【UEFI系列】ACPI

文章目录

  • 一、APM ACPI
  • 二、S state介绍
  • 三、ACPI table,ASL,ACPI method
    • 1.ACPI table
    • 2.ASL
  • 四、添加ACPI表


一、APM ACPI

ACPI: Advanced Configuration and Power Management Interface,高级配置和电源管理接口。以前的电源管理规范是APM,现在ACPI已经把它替代了。
ACPI是OSPM(operating system-directed configuration and power management)的重要组成部分。
ACPI system定义了ACPI硬件、ACPI bios、ACPI OS,都follow ACPI的规范。
ACPI规范中,硬件由OS管理控制,bios是一个reporter。

ACPI是一套协议标准,这是OSPM/ACPI global system,图中列出了与OSPM/ACPI相关的软硬件以及之间的关系,描述了各部分的接口。
在这里插入图片描述

利用ACPI定义的接口,OS实现功能:
(例如ACPI汇报一个设备,这个设备在OS下由OS driver实现功能)

  1. system,device和CPU的电源管理
  2. device和CPU performance management
  3. 设备的配置/插拔和设置

其他规范:

  1. system event
  2. battery management电池管理
  3. 定义了硬件规范,smbus controller(低速的一种总线,通过它了解设备的信息例如内存信息)
  • OSPM如何实现?

OS使用ACPI table中的定义,用ASL(ACPI source language,一种编程语言)控制硬件。

硬件状态变化时,有system event产生,硬件会发SCI(system control interrupt,并非SMI的一个中断)来通知OS,OS执行ASL中定义的method,object等来控制硬件。

二、S state介绍

  • 常见的基础知识,S state:Sleep状态。

S0:正常工作的电源状态。
S1:通过 CPU 时钟控制器将 CPU 关闭,但CPU内容不保持、其他的硬件设备仍然正常工作。从s1唤醒到s0,CPU不需要重新从reset vector处执行,唤醒时间最短。PC端可通过键鼠操作快速唤醒。
S2:系统一般很少支持(跟s1状态差不多)。
S3:挂起到内存。运行中的数据写入内存后关闭硬盘,此时除了内存需要电源来保持资料以外,其他的设备、装置全部停止供电。
S4:挂起到硬盘。把内存中的资料完整地保存在硬盘中,然后所有部件停止工作,系统主电源关闭,但是硬盘仍然带电并可以被唤醒。
其实系统设置里这个开启的话,就会是进s4,开机就比较快。关掉的话就是从s5完全关机状态来开机。
在这里插入图片描述
S5:完全关机。

windows系统的左下角电源操作显示:分别是S3(睡眠)、S4(休眠,win11现在好像没了)、S5。
在这里插入图片描述

  • 如何从睡眠的Sx到S0状态

开机键;
RTC(real-time clock),有些是设置时间自动唤醒;
Modem,电话的串口唤醒,南桥会先处理信号;
Lan,网络唤醒,例如网吧里唤醒机器;
鼠标/键盘;
Gpio;

三、ACPI table,ASL,ACPI method

1.ACPI table

  • ACPI table的作用

对硬件接口、系统信息、特定功能和method的描述。
OS boot的时候,OSPM找到ACPI table并使用其中的信息。

  • ACPI table列举

RSDP:Root System Description Pointer;
根据ACPI GUID在System table中,找到表的entry起始地址。
RSDP表包含了RSDT和XSDT表的起始地址,这2个表可以去确定其他表的位置。
在这里插入图片描述
这里看到RSDTAddress是4字节,所以寻址空间在4G以内。
而XSDTAddress是8字节,寻址空间高于4G(本来X也是extended的缩写,表示额外的意思)。
大体结构是这样:
在这里插入图片描述

在这里插入图片描述
下面这张是RSDT指出来的

在这里插入图片描述
可以看到FACS和DSDT比较特殊,不在RSDT和XSDT里放地址,这两个是OS自己产生出来的。

这些header结构都是一样的,内容各自写各自的。

RSDT:Root System Description Table;
RSDT Header是这样的结构:前4字节拿来写标识signature

在这里插入图片描述

XSDT:Extended System Description Table;
FADT:Fixed ACPI Description Table;
FACS:Firmware ACPI Control Structure;

FACS是Firmware和OS之间沟通的桥梁,主要包含3个内容:
a. HardWare signature:系统从S4 唤醒时,OS会去读取Hardware signature来验证系统硬件是否发生了改变,若被改动过,则不能LOAD之前的Image信息,而是应该重新执行一次COLD REBOOT。
b. Firmware Waking Vector中主要保存了唤醒系统之后要处理的程序entry。
c. Global Lock:主要用于OS和firmware在访问硬件时同步。

DSDT:Differentiated System Description Table;

DSDT包含了AML的CODE和DATA。它定义了OS在启动过程中如何与硬件交互。DSDT 通常包含系统硬件资源的详细描述、设备节点、方法、事件以及电源管理相关的信息。编译完成后的 DSDT 被加载到系统内存中,并由OS的 ACPI 驱动进行解析。

SSDT:Secondary System Description Table;

  • 如何在内存中找到ACPI table

1.先找到RSDP:在E000-F000内存中搜索“RSD PTR ”的signature。
通过RSDP,即可获取到RSDT或者XSDT,进而可以获取所有的ACPI Table。

2.其它locate方式:EFI环境下,根据ACPI的guid在system table中找到ACPI table(其实就是先找RSDP的guid)的entry。
(EFI GUID for ACPI 2.0 or later RSDP structure: 8868e871-e4f1-11d3-bc22-0080c73c8881)

Windows下可以用RW工具查看Acpi Table。

  • 用工具dump acpi table

DOS: ACPItbl,pl.exe
Windows:RW

2.ASL

ASL(ACPI Source Language)编译之后得到AML(ACPI machine Language),置于ACPI table中。
ASL用来定义ACPI objects,包括ACPI control methods等,可以控制hardware,读写寄存器等。
Method,类似C语言中的函数,可以被其他Method或者OS调用。详见acpi规范。

简单举列:
声明变量 : Name(Data, 0)
声明函数 : Method (_PIC, 1, NotSerialized)
声明Device: Device(COM3)
描述一段内存:Memory32Fixed(ReadWrite, 0xFED81500, 0x300)
描述一组IO:IO (Decode16, 0x3E8, 0x3E8, 0x01, 0x08)

Device声明通常存在与DSDT和SSDT中。
Device定义中正常包含_HID, _UID等描述设备信息。
_STA用于描述设备状态(status),决定该设备是否可以识别。
_CRS描述当前设备所需资源(current required resource)。

Method:
Method类似C语言的中函数。
若为局部Method,可直接调用;
若为外部Method,需要指定Method对应的路径;
若Method不在同一个Table中,需要使用External的方式进行申明。
_PTS:(比如指令Method (PTS, 1, Serialized)。)OS在做S1、S2、S3、S4 sleep操作的时候会调用_PTS method,将sleep level传入这个method。简单来说就是休眠操作回去调_PTS的相关函数。

ASL什么时候汇报给OS的:BDS,其实shell(相当于处于bds阶段,还在boot过程中)下也可以导出acpi表。这也就是为什么很多时候shell下没问题,但是OS有问题,就是asl语言控制设备的时候出了问题。

四、添加ACPI表

这是EFI_ACPI_TABLE_PROTOCOL的结构,提供了两种方法InstallAcpiTable和UninstallAcpiTable:

struct _EFI_ACPI_TABLE_PROTOCOL {EFI_ACPI_TABLE_INSTALL_ACPI_TABLE      InstallAcpiTable;EFI_ACPI_TABLE_UNINSTALL_ACPI_TABLE    UninstallAcpiTable;
};

table的结构:

typedef struct {UINT32    Signature;UINT32    Length;UINT8     Revision;UINT8     Checksum;UINT8     OemId[6];UINT64    OemTableId; //一般是放表名的,例如"RamDisk "UINT32    OemRevision;UINT32    CreatorId;UINT32    CreatorRevision;
} EFI_ACPI_DESCRIPTION_HEADER;

具体实例(edkii代码里的)

extern EFI_GUID  gEfiAcpiTableProtocolGuid;
UINTN    mRamDiskSsdtTableKey;EFI_STATUS             Status;EFI_ACPI_TABLE_PROTOCOL  *mAcpiTableProtocol = NULL;EFI_ACPI_DESCRIPTION_HEADER  *Table;UINTN                        TableSize;//数据获取Status = GetSectionFromFv (&gEfiCallerIdGuid,EFI_SECTION_RAW,SectionInstance,(VOID **)&Table,&TableSize);//先装protocolStatus = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid,NULL,(VOID **)&mAcpiTableProtocol);//再用protocol里的方法安装tableStatus = mAcpiTableProtocol->InstallAcpiTable (mAcpiTableProtocol,Table,TableSize,&mRamDiskSsdtTableKey);

edkii代码里的table例子:

// ACPI Boot Graphics Resource Table template
EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE  mBootGraphicsResourceTableTemplate = {{EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE,sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE),EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION, // Revision0x00,                                               // Checksum will be updated at runtime//// It is expected that these values will be updated at EntryPoint.//{ 0x00 },   // OEM ID is a 6 bytes long field0x00,       // OEM Table ID(8 bytes long)0x00,       // OEM Revision0x00,       // Creator ID0x00,       // Creator Revision},EFI_ACPI_5_0_BGRT_VERSION,         // VersionEFI_ACPI_5_0_BGRT_STATUS_VALID,    // StatusEFI_ACPI_5_0_BGRT_IMAGE_TYPE_BMP,  // Image Type0,                                 // Image Address0,                                 // Image Offset X0                                  // Image Offset Y
};

可以看到头部都一样,之后的部分是自己定义的结构。

http://www.xdnf.cn/news/1317151.html

相关文章:

  • 跨越南北的养老对话:为培养“银发中国”人才注入新动能
  • JavaScript 性能优化实战:从评估到落地的全链路指南
  • Spark03-RDD02-常用的Action算子
  • 在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo
  • E2B是一个开源基础设施,允许您在云中安全隔离的沙盒中运行AI生成的代码和e2b.dev网站
  • Diamond基础2:开发流程之LedDemo
  • c_str()函数的详细解析
  • 简单的 VSCode 设置
  • (nice!!!)(LeetCode 每日一题) 837. 新 21 点 (动态规划、数学)
  • bash shell 入门
  • 云智智慧停充一体云-allnew全新体验-路内停车源码+路外停车源码+充电桩源码解决方案
  • Rust:DLL 输出对象的生命周期管理
  • API生命周期10阶段
  • 原子操作及基于原子操作的shared_ptr实现
  • Baumer高防护相机如何通过YoloV8深度学习模型实现工作设备状态的检测识别(C#代码UI界面版)
  • 【C++】Windows 下 TCP接口超详介绍,如何实现一个TCP服务端和客户端
  • Windows 10共享打印机操作指南
  • 业务员手机报价软件免费领取——仙盟创梦IDE
  • 精美UI的单页网盘资源分享搜索页面 短剧搜索 自适应页面
  • 飞算JavaAI赋能高吞吐服务器模拟:从0到百万级QPS的“流量洪峰”征服之旅
  • IC验证 AHB-RAM 项目(一)——项目理解
  • AOP配置类自动注入
  • Git安装使用
  • Java增强for循环(小白友好版)
  • 整体设计 之“凝聚式中心点”原型 --整除:智能合约和DBMS的深层联合 之1
  • 【R语言】R语言矩阵运算:矩阵乘除法与逐元素乘除法计算对比
  • 7 索引的监控
  • 一文读懂[特殊字符] LlamaFactory 中 Loss 曲线图
  • JavaScript字符串详解
  • 图解希尔排序C语言实现