UEFI-ASL动态修改ACPI表

文章目录

  • UEFI-ASL动态修改ACPI表
    • 简述ACPI
      • ACPI是什么?
      • ACPI的组成及使用?
      • ACPI的优点?
    • ACPI的详细功能
    • ASL语言
      • ASL基本准则
      • 如何使用ASL?
      • 动态修改CPU频率

目前,龙芯平台早已将固件 -> 内核的2.3接口规范升级到了 3.0接口规范,这里所说的3.0接口就是UEFI到内核的桥梁-ACPI接口规范,所以不得不说现在的龙芯越来越标准化了。

简述ACPI

UEFI早已谈过,那么我们现在来谈谈ACPI。

ACPI是什么?

ACPI全称 Advanced Configuration and Power Interface ,高级配置和电源接口

首先,从固件到内核之间,无非就是提供一些设备资源(包含内存资源),一些运行时服务及一些平台差异化的讯息需要内核Attention的事项。
而如何管理这些信息,就需要定义一套套标准,ACPI即是时代的产物,一套被Intel,微软等巨头规范化的标准接口。

ACPI的组成及使用?

ACPI可以说是将众多不同种类及不同设备间的资源进行了高级抽象,然后连接在了一起,由一系列不同对象的表项所组成,简说就是ACPI表。
对于它自身的面向对象的抽象思想,有其对应的编写语言ASL(ACPI Source Language)进行译化为AML(ACPI Machine Language),然后由OS解码执行。

ACPI表 含义 作用
MADT Multiple APIC Description Table 可以管理多处理器平台上支持的处理器数量,当然也包括内核所对应的逻辑核信息
DSDT Differentiated System Description Table 差异系统描述表:下面会将其中的一部分
SRAT System Resource Affinity Table 系统资源关联表

其余的表项先就不说了,点击此处ACPI_Spec上有更详细的介绍。

ACPI的优点?

目前,多个主流操作系统都支持ACPI(Linux,NetBSD,OpenBSD,Windows Vista,Windows等),而ACPI则是一套与架构无关的资源管理接口,所以我们可以跨平台使用,理论上只要OS支持ACPI接口即可,无论Windows还是Linux。

其实ACPI的最大的进步在于Power Management(电源管理方面),这里我们就不详细说了,有关一些术语可以点击维基百科-ACPI参见。

ACPI的ASL语言里面向对象高级抽象的思想很需要我们C语言开发者学习,人家造le轮子,我们不仅要学会如何使用,关键的是学习人家的思想,如何将资源整合在一起,清晰明了,也不至于我们写的代码那么的Low。

总之,ACPI还是蛮强大的,你直接使用它控制OS都没问题。(当然,也很危险,你如果给OS传错了话,OS可就按你的话来执行了哈~).

ACPI的详细功能

关于ACPI在规范中究竟都定义了哪些功能,我就不一一介绍了,详见上述维基百科或SPEC规范。

简单列举几个功能例子:

  • 控制EC,控制风扇,电池管理,温度管理,设备电源管理,系统电源管理,中断管理,处理器核信息管理等,如何实现还请大家一起探讨学习~

ASL语言

ASL是本章节的重点,我们讲述一下使用时的基本准则和怎么描述设备信息。

ASL基本准则

  • 1)变量命名不超过4个字符,且不能以数字开头,稍后看DSDT代码即可理解。
  • 2)Spec规范中定义了大量的对象,它们的名字一般以_开头,所以自己定义时还请区别开来。
  • 3)ASL的操作符基本满足C的标准,只是关键字需要记忆,比如:逻辑与,算术运算等。
  • 4)表达式:ASL定义了好多操作符,例如:定义变量 NAME(object,Value)等,详细查看19.6章节:
  • 5)ASL中的路径有相对路径和绝对路径之分,Scope和Device都会形成自己的作用域,类似与C++中的namespace和class。
  • 6)对于使用Method定义函数:可使用Arg0-Arg7,最多8个传递参数,而对于局部变量,也最多可默认使用Local0-Local7,无需区分大小写.
  • 7)数据类型:integer(整数),String(字符串),Event(事件),Buffer(数组),Package(对象集合),这些类型都可以直接引用,是用NAME定义变量。
    太详细的就不说了,下面具体以代码为例介绍。

如何使用ASL?

我们以DSDT表为例讲解:
UEFI下的ACPI驱动如何将信息信息传递的就不说了,DSDT表 示例代码如下

 /** Original Table Header:*   Signature  "DSDT"*   Length     OP*   Revision   0x02*   Checksum   0x0*   OEM ID     "LGSON "*   OEM Table ID   "TP_R00  "*   OEM Revision   0x00000470*   Compiler ID    "LNGSN"*   Compiler Version 0x20141107 (538185991)*/DefinitionBlock ("Dsdt.aml", "DSDT", 2, "LGSON ", "TP-R00  ", 0x00000476){include ("PcieTree.asl")include ("PciDevice.asl")//include ("Ec.asl")include ("Cpu.asl")include ("Platform.asl")//include ("Tz.asl")Scope (\_SB.PCI0){Name (PCIG, ToUUID ("e5c937d0-3553-4d7a-9117-ea4d19c3434d") /* Device Labeling                 Interface */)Method (PCID, 4, Serialized){If (LEqual (Arg0, PCIG)){If (LGreaterEqual (Arg1, 0x03)){If (LEqual (Arg2, 0x00)){Return (Buffer (0x02){0x01, 0x03})}If (LEqual (Arg2, 0x09)){Return (Package (0x06){0xC350,Ones,Ones,0xC350,Ones})}}}
//etc...

这里的DefinitionBlock是一个Operator(可以看作ASL的一个入口):它以数据和控制方法(编译成AML)的形式包含关于硬件实现和配置详细信息。
ACPI-Tables中必须至少提供一个Definition Block:Differentiated Definition Block,它描述了基本的系统。
在装载Differentiated Definition Block之后,紧接着OS会把Differentiated Deffinition Block的内容插入到ACPI Namespace。Os可以动态的从the active ACPI Namespace插入和删除其他definition blocks,可以包含指向Differentiated Definition Block的引用。

ACPI名字空间(ACPI Namespace)
一个树状层次机构,在受操作系统控制的内存里面,这段内存里面包含命名对象(named objects)等。这些对象(objects)可以是数据对象,控制方法对象,总线/设备包对象等。操作系统通过从驻留在 ACPI BIOS 中的 ACPI Tables 加载出(loading and/or unloading)定义块(definition blocks),来动态改变名字空间(namespace)的内容。在ACPI Namespace 中的所有信息都来自 Differentiated System Description Table (DSDT),DSDT 里面包含了 Differentiated Definition Block 还有一个或者多个其他的定义块(definition blocks)。

简言之:就是建立一个Block,里面包含了很多数据对象,最终放在了内存,供OS动态加载

对于我们开发者需要理解的是:

  • 首先我们看Method (PCID, 4, Serialized)这个关键字,定义了含有四个入参的函数(PCID),它干的事情就是下面一些列比较LEqual判断等,我们只需调用PCID(Arg0,Arg1,Arg2,Arg3)和C一致,但是这些关键字需要记忆。
  • 我们再看Scope (\_SB.PCI0),引用\_SB.PCI0这个路径,添加了Name (PCIG, ToUUID (“e5c937d0-3553-4d7a-9117-ea4d19c3434d”),即创建了一个PCIG的名字的UUID,关于ToUUID这个方法自己可以查看Spec了解。
  • 关于上述PCI0为什么放在作用域\_SB,那我们还需要了解规范下根作用域下定义的5个作用域:
    1: \_GPE: ACPI的事件处理
    2: \_PR: 处理器
    3: \_SB: 设备和总线
    4: \_SI: 系统指示灯
    5: \_TZ: 热区,用于读取某些温度。
    所以PCI的设备资源放在\_SB你应该就理解了。

动态修改CPU频率

我们需要修改的是Cpu.asl内的数据.
代码如下:

   Scope (\_SB){Name (IDDR,0x1fe00020)Name (FREQ,0x000009c4) //Normal Max Freq:2000OperationRegion(BASE, SystemMemory, IDDR, 0x8)Field(BASE,AnyAcc,NoLock,Preserve){PRID,64}//NAME(MEM2,0x0000303030354133)//Name(qqq,Buffer("3B5000"){})//ToString(MEM2,6,qqq)NAME(VETB,Package (){Package (0x02) {0x0000303030354133, //3A50002500},Package (0x02) {0x4C4C303030354133, //3A5000LL2300},Package (0x02) {0x004D303030354133, //3A5000M2000},Package (0x02) {0x0000303030354233, //3B50002300},Package (0x02) {0x004C303030354333, //3C5000L2200},Package (0x02) {0x0049303030354133, //3A5000I2200},Package (0x02) {0x0069303030354133, //3A5000i2200}})For (Local0 = 0,Local0 < SizeOf(VETB),Local0++){if ( LEqual ( DeRefOf ( Index ( DeRefOf ( Index ( VETB, Local0 ) ), 0 ) ), PRID ) ){Store ( DeRefOf ( Index ( DeRefOf ( Index ( VETB,Local0 ) ) , 1 ) ) , FREQ )}}Device (C000){Name (LPSS, Package (0x10){Package (0x06){FREQ,0x00003A98,20000,20000,0x00000103,0x00000003},

通过上述简摘的一部分代码,我们可以看出通过OperationRegion定义一段操作空间,然后通过读取内存或者一些IO来获取我们外部的信息,从而告知内核我们需要随时变化的信息让OS去动态获取。其中FREQ就是我们需要动态修改的值,被集合在一套频率表中,我们可以通过Linux下的lscpu来查询我们动态获取的数据。

以上,就是ASL的简单实例,更多详细操作和复杂逻辑可以查阅ACPI_Spec规范,来学习!
学无止境~

UEFI-ASL动态修改ACPI表相关推荐

  1. js 修改form表单action

    动态修改form表单action的值, 为form表单Id添加点击事件,点击form修改action值 <form action="" enctype="multi ...

  2. 【QNX Hypervisor 2.2 用户手册】3.2.3 ACPI表和FDT

    写在前面 QNX hypervisor VM为它的guest提供了高级配置和电源接口(ACPI Advanced Configuration And Power Interface)表和扁平设备树(F ...

  3. UEFI 学习3.6 - ARM QEMU上的ACPI表

    文章目录 ACPI 表结构 RSDP XSDT FADT DSDT MADT SPCR 如果对ACPI概念不熟悉,可以先参考这篇[UEFI基础]ACPI基础 解析代码github地址: TestPkg ...

  4. 如何修改动态库符号表

    如何修改动态库符号表 一.ELF 文件和有关术语 Unix 系统的可执行文件和动态库文件是以 ELF 格式存放的.为使下面的叙述 清晰而没有伎义,先简要介绍一下 ELF 文件格式,并约定一些术语.关于 ...

  5. 微信小程序引入ECharts,并自定义动态修改表内参数配置

    ECharts官方并没有给出小程序的相关参考,但是有大神做出了ECharts-小程序版,可以直接引用. 效果图 引用步骤 1.下载文件 GitHub - ecomfe/echarts-for-weix ...

  6. uefi下的开机顺序_动态修改UEFI启动顺序的方法与流程

    本发明涉及计算机领域,其主要 技术实现要素: 是动态修改UEFI启动顺序的方法. 背景技术: 固件是固化在Flash芯片中的软件程序.BIOS是计算机中最重要的固件之一,用于初始化硬件.管理硬件资源. ...

  7. 《UEFI内核导读》ACPI编程入门

    固件C字营·版权所有 敬请关注微信公众号:"固件C字营" ============================================================= ...

  8. linux设备acpi表配置,Linux acpi off简介

    Linux acpi off – the Advanced Configuration & Power Interface. ACPI是OS,BIOS和硬件之间的抽象层.它允许OS和平台独立的 ...

  9. mysql中如何设置过滤器_mysql 如何动态修改复制过滤器

    MySQL动态修改复制过滤器 说说今天遇到的问题吧,今天在处理一个业务方的需求,比较变态,我大概描述一下: 1.线上的阿里云rds上面有个游戏的日志库,里面的表都是日表的形式,数据量比较大了,每次备份 ...

最新文章

  1. [源码和文档分享]基于java 的仿QQ聊天工具
  2. go语言csv包_玩转数据处理120题R语言版本
  3. python类型转换astype-numpy数据类型dtype转换
  4. java取消按钮_Java Swing-单击取消按钮时不循环
  5. 数据结构之平衡树:红黑树的介绍与Python代码实现——17
  6. 数字信号处理——巴特沃斯滤波器设计
  7. ios系统微信浏览器、safari浏览器中h5页面上拉下滑导致悬浮层脱离窗口的解决方法
  8. 能力的变迁:能力包括哪些方面
  9. 0基础入门VTD-实操静态道路建模3
  10. 基于JAVA宠物店管理系统设计与实现计算机毕业设计源码+数据库+lw文档+系统+部署
  11. 273. 整数转换英文表示
  12. 多多情报通:拼多多推广哪个效果好?有什么推广技巧?
  13. 我陪你慢慢成长——苏子语录2015下半…
  14. Deployer php自动部署,Deployer 自动部署
  15. 使用matlab绘制世界地图并根据经纬度绘制点位(附m_map的下载与安装说明)
  16. 如何让你的内网服务器可以被外网访问到(端口映射、NAT、域名解析、IP地址)
  17. 【python学习】如何将所绘制的图(单张多张)保存到文件夹,并用绘制实时时间命名图片
  18. anconda 下的pip路径_修改conda环境和缓存默认路径/修改Python 的 pip install 默认安装依赖路径/提高conda安装速度,其实就是改了下载源。...
  19. 【总结,持续更新】java常见的线程不安全,你以为的线程安全
  20. 浅谈人机交互设计系统

热门文章

  1. wiley latex 模板 设置双栏 调整双栏间距
  2. 语音转换文字的软件怎么使用
  3. 视频无信号--H.265与H.264解码器连接录像机拼接电视显示画面处理
  4. [Daimayuan] 巨大的牛棚(C++,矩阵前缀和)
  5. python数据分析 知乎_Python数据分析揭秘知乎大V的小秘密
  6. Windows聚焦壁纸不更新的最佳解决方法
  7. 微型计算机sp作用,微机原理及应用A-中国大学mooc-题库零氪
  8. linux 根目录文件夹解释
  9. pdf转成cad,教你pdf转cad的方法
  10. CACHE数据库 存储过程