# ACPI 热补丁概述

# 什么是 ACPI 热补丁

通过引导程序对本机的 ACPI 表二进制内容进行更名,实现禁用 ACPI 表中某个设备(Device)下的方法(Method)或者变量名,同时新建 SSDT 补丁重写相关代码,达到重定义的作用

# ACPI 热补丁通常用于哪些地方

  • EmbeddedControl(嵌入式控制器):该 ACPI 设备下通常具备电池、光线传感器、加速度传感器、EC Query 方法映射等定义
  • I2C 总线:该 ACPI 设备下通常具备触摸设备及人体学输入设备相关传感器(如指纹传感器)定义
  • 睡眠唤醒相关修复:PNP0C0E(睡眠按钮)、PNP0C0D(笔记本盖子)、_PTS(睡眠前执行)、_WAK(唤醒后执行)

# ACPI 热补丁方法

TIP

热补丁的本质还是实现对 ACPI 某个设备或者方法的重定义,以便与 macOS 兼容

  • 第一步,更名

    • 更名通常是针对 Method 来使用的,它在 ACPI 中的定义与 HEX 代码对应关系如下:

      • Method(xxxx,a,N) --> xxxx 的十六进制代码 + a 的十六进制代码,最后两位范围为 00 - 07
      • Method(xxxx,b,S) --> xxxx 的十六进制代码 + (b+8) 的十六进制代码,最后两位范围为 08 - 0F
    • 根据上述关系,给出如下示例:

        Method (MHPF,1,N) --> `4D485046 01`
        Method (BTST,2,S) --> `42545354 0A`
      
    • 为了使原来的方法失效,我可以把 MHPF 更名为 XHPF,X 对应的 HEX 代码是 58,则完整的更名示例如下

      Comment change MHPF,1,N to XHPF
      Find    4D485046 01
      Rplace  58485046 01
      
  • 第二步,重定义

    • 在建立的 SSDT 补丁中,将已经更名的原始代码复制过来,并按照需求进行改动

    • 补充上操作系统判断,使整个热补丁只在 macOS 下生效,示例格式如下

      Method (MHPF, 1, NotSerialized)
      {
          If (_OSI("Darwin"))
          {
              ···
          }
          else
          {
              XHPF(Arg0)
          }
      }
      
    • 备注:若原来的 Method 定义了参数,则在回调时应该加上参数;若原来的代码存在 Return 语句,则回调时应该以 Return 的形式回调原始代码

注意事项

当 ACPI 更名涉及到 _STA_CRS 等在原始 ACPI 中反复出现的方法时,若使用的是 CLOVER 引导,则可以利用 TgtBridge 限定修改区域;若使用的是 OpenCore 引导,则需要使用 skip 和 count 计数方法来精确定位到需要修改的地方,这种方法难度较大,可以考虑采取拉长 HEX 代码的方法确保唯一性(利用 HEXFriend 在 ACPI 中找到你需要更名的那段代码然后将其上下文包含进来进行搜索确认是否是唯一的)