V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
imbushuo
V2EX  ›  分享创造

为默认不支持的设备(如 MacBook 12-inch)启用 Windows Connected Standby

  •  
  •   imbushuo ·
    imbushuo · 2018-07-09 01:51:29 +08:00 · 3423 次点击
    这是一个创建于 2355 天前的主题,其中的信息可能已经有所发展或是发生改变。

    MacBook 12-inch 使用的 CPU / SoC 整一个都是为 Windows 设计的,然后 Apple 强行拿来往 macOS 上用。于是装了 Windows 之后我在想怎么样可以让它更好用一点。因为之前写了好几个面向不同平台的 UEFI & ACPI 实现,我就想干脆启动 Connected Standby 好了。

    Note: AMD 很可能没有 Connected Standby。

    在 MacBook 12-inch 上的效果

    S0ixDemo.PNG

    你可以看视频: https://twitter.com/imbushuo/status/1016015791827836929

    • 你可以用触摸板 /键盘 /盖子的任意一种来唤醒设备
    • Windows 唤醒速度比 macOS 还快好几倍(笑死我了……)
    • Windows 睡眠时可以一直保持网络连接,可以在睡眠时收邮件 /收推送 /IRC 挂机 /BT 下载(某些客户端支持)/Windows Update (比 Power Nap 更进了一步)
    • Windows 睡眠时可以播放歌曲,只要是 UWP (本地歌曲或者网上的歌曲都可以)
    • Windows 可以在睡眠时对系统进行一些维护和优化操作

    问题


    You cannot switch between S3 and Modern Standby by changing a setting in the BIOS. Switching the power 
    model is not supported in Windows without a complete OS re-install.
    

    • 单独安装未知设备的驱动,而不是安装 Boot Camp 一个大包。Apple 的一两个服务和驱动会干扰 S0ix 的正常运行

    实现

    不同于 ACPI S3,S0ix 并不需要 ACPI DSDT 引入特殊的 ACPI 方法。自 ACPI 5.0 后,只需要在 FADT 表里标记 S0 Low Power Idle: EFI_ACPI_5_0_LOW_POWER_S0_IDLE_CAPABLE 即可。如果支持 5.0+,EDK2 的宏的 5_0 换成对应版本,不过总之都是 Flag 的 Bit 21。标记好后重新算一遍 FADT 表的 Checksum。核心实现如下:

    if (Rsdp != NULL && XsdtHeader != NULL)
    {
        UINT64* EntryAddress = (UINT64*)&XsdtHeader[1];
        UINT32 EntryArraySize = (XsdtHeader->Length - sizeof(*XsdtHeader)) / sizeof(UINT64);
    
        Print(L"XSDT: Count = %d\n", EntryArraySize);
        for (UINT32 j = 0; j < EntryArraySize; j++)
        {
            EFI_ACPI_DESCRIPTION_HEADER* Entry = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)EntryAddress[j]);
            if (Entry->Signature != EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE)
            {
                Print(L"%d: Not FADT table \n", j);
                continue;
            }
    
            if (Entry->Revision < EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION)
            {
                Print(L"%d: FADT revision is below ACPI 5.0 \n", j);
                continue;
            }
    
            Print(L"FADT table located. \n");
    
            // Iteration completed
            Fadt = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE*) Entry;
            break;
        }
    }
    
    if (Fadt != NULL)
    {
        Print(L"FADT Flags: 0x%x \n", Fadt->Flags);
    
        if ((Fadt->Flags >> 21) & 1U)
        {
            Print(L"S0 Low Power Idle State Flag is already enabled on this platform \n");
        }
        else
        {
            Print(L"Setting S0 Low Power Idle State Flag \n");
    
            // Low Power S0 Idle (V5) is bit 21, enable it
            Fadt->Flags |= 1UL << 21;
    
            // Re-calc checksum
            Print(L"Setting new checksum \n");
            SetAcpiSdtChecksum(Fadt);
    
            Print(L"FADT patch completed. \n");
        }
    }
    

    然后启动系统安装,启动系统初始化即可。目前这段代码需要每次开机跑一次,我也没做 Chainload,比较麻烦。我暂时用 rEFInd 解决。未来会加入 Chainload 来启动 Windows Boot Manager。

    代码

    Github

    Disclaimer

    由于平台设计的不同和特殊设备的不确定性,我对这个项目在其他笔记本设备上使用造成的后果概不负责。

    6 条回复    2018-07-12 09:14:35 +08:00
    hahasong
        1
    hahasong  
       2018-07-09 09:19:01 +08:00 via iPhone
    大神你的 12 寸 macbook 快被你玩坏了
    mritd
        2
    mritd  
       2018-07-09 09:49:30 +08:00 via iPhone
    大佬,请问这个语言有没有啥好的资料? 折腾黑苹果时候想学累着 后来官方文档撸不动了🙃
    mcluyu
        3
    mcluyu  
       2018-07-09 09:50:48 +08:00
    哇,第一次见有人折腾 win 下的 ACPI,腻害
    hljjhb
        4
    hljjhb  
       2018-07-09 11:12:13 +08:00 via Android
    厉害了 最好的 windows 笔记本—— macbook
    LuvLetter
        5
    LuvLetter  
       2018-07-09 12:18:18 +08:00
    不过考虑到里面还有一张 BCM 的垃圾卡
    Tink
        6
    Tink  
       2018-07-12 09:14:35 +08:00 via iPhone
    真的是大佬……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1037 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 22:30 · PVG 06:30 · LAX 14:30 · JFK 17:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.