Win10论坛

Win10正式版系统下载主题平板

重定义Modern UI,打造完美Windows全新体验

Windows10下载|安装|新手宝典|必备软件

搜索
查看: 30390|回复: 267

[已解决] 【已解决!】10.13寨版华南X79安装AppleACPIPlatform问题分析   [复制链接]

Rank: 2Rank: 2

UID
4699402
帖子
315
PB币
360
贡献
0
技术
0
活跃
317
发表于 2017-8-13 22:18:35 |显示全部楼层
本帖最后由 cheneyveron 于 2017-8-31 08:21 编辑

配置:主板:华南X79 v2
CPU:E5-2670 V1 C2
显卡:GTX 1050TI
声卡:ALC662
有线网卡:RTL8168/8111/8112
目前10.12.6完美,EFI在这里:https://github.com/cheneyveron/clover-x79-e5-2670-gtx650

鲁大师配置图:


10.13 DP5:


搜了两天谷歌,按照国外大神piker alpha的分析:
https://pikeralpha.wordpress.com/2017/07/02/applesmcrtc-kext-panics
和更具体的alext jam的分析:
https://alextjam.es/debugging-appleacpiplatform
错误定位:
panic的位置在AppleACPIPlatform的_isprint函数中,函数正文反编译如下:
int _isprint(char c)
{
    return (_ctype[c] & 0x97) != 0;
}
可以看到_isprint函数用到了_ctype这个表,根据这个表的索引返回一个字符。
看起来_isprint函数重写了acpia 的_isprint函数,acpia的函数在这里:https://github.com/acpica/acpica ... clude/acclib.h#L181
AppleACPIPlatform的_isprint函数被AcpiTbPrintTableHeader调用,这个函数是acpia的函数了,所以也不需要反编译了,代码大概如下:
static void
AcpiTbFixString (
    char                    *String,
    ACPI_SIZE               Length)
{

    while (Length && *String)
    {
        if (!_isprint ((int) *String))
        {
            *String = '?';
        }

        String++;
        Length--;
    }
}

static void
AcpiTbCleanupTableHeader (
    ACPI_TABLE_HEADER       *OutHeader,
    ACPI_TABLE_HEADER       *Header)
{

    memcpy (OutHeader, Header, sizeof (ACPI_TABLE_HEADER));

    AcpiTbFixString (OutHeader->Signature, ACPI_NAME_SIZE);
    AcpiTbFixString (OutHeader->OemId, ACPI_OEM_ID_SIZE);
    AcpiTbFixString (OutHeader->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
    AcpiTbFixString (OutHeader->AslCompilerId, ACPI_NAME_SIZE);
}

void
AcpiTbPrintTableHeader (
    ACPI_PHYSICAL_ADDRESS   Address,
    ACPI_TABLE_HEADER       *Header)
{
    [...]
    else
    {
        /* Standard ACPI table with full common header */

        AcpiTbCleanupTableHeader (&LocalHeader, Header);

        ACPI_INFO ((
            "%-4.4s 0x%8.8X%8.8X"
            " %06X (v%.2d %-6.6s %-8.8s %08X %-4.4s %08X)",
            LocalHeader.Signature, ACPI_FORMAT_UINT64 (Address),
            LocalHeader.Length, LocalHeader.Revision, LocalHeader.OemId,
            LocalHeader.OemTableId, LocalHeader.OemRevision,
            LocalHeader.AslCompilerId, LocalHeader.AslCompilerRevision));
    }
}
真正引起panic的是这句AcpiTbFixString (OutHeader->AslCompilerId, ACPI_NAME_SIZE),也就是说,实际上是MATSHeader->AslCompilerId中的某个字符无法解析导致panic。
遂用iasl查看了一下MATS表如下:
[000h 0000   4]                    Signature : "MATS"
[004h 0004   4]                 Table Length : 00000034
[008h 0008   1]                     Revision : 02
[009h 0009   1]                     Checksum : 67
[00Ah 0010   6]                       Oem ID : "ALASKA"
[010h 0016   8]                 Oem Table ID : "A M I"
[018h 0024   4]                 Oem Revision : 00000002
[01Ch 0028   4]              Asl Compiler ID : "w x2"
[020h 0032   4]        Asl Compiler Revision : 00000000


**** Unknown ACPI table signature [MATS]


Raw Table Data: Length 52 (0x34)

  0000: 4D 41 54 53 34 00 00 00 02 67 41 4C 41 53 4B 41  // MATS4....gALASKA
  0010: 41 20 4D 20 49 00 00 00 02 00 00 00 77 98 78 32  // A M I.......w.x2
  0020: 00 00 00 00 B2 00 00 00 01 00 00 00 98 7D 2F CB  // .............}/.
  0030: EE FF 00 00                                      // ....
可以看到w x2之间的值是98,而0x98是不能转换成unsigned char的,因为unsigned char的取值范围只能到0x7F,把它改小一些以后就成功的启动了。


综上所述,如果任何一个ACPI表(不止是MATS)的 Signature、OemId、OemTableId 或 AslCompilerId 有字符大于0x7F就会导致AppleACPIPlatform错误。


看到这里,会编辑DSDT或者改BIOS的ACPI表的童鞋可以去解决问题了...


但是我的奇葩的华南X79找不到BIOS的ACPI表的位置...
我在ubuntu下提取了一堆acpi表,但是没办法用MaciASL修改,因为编译不通过...
如果能有景友知道上面两个方法怎么做,求告知。。
附上ROM和原始acpi表、现在用的dsdt




2017.8.31更新:
经过了和坛友们的讨论此问题终于解决啦,见第104楼
附件: 你需要登录才可以下载或查看附件。没有帐号?注册

Rank: 2Rank: 2

UID
4699402
帖子
315
PB币
360
贡献
0
技术
0
活跃
317
发表于 2017-8-13 22:24:23 |显示全部楼层
几乎没看到远景有X79安装好10.13的先例,所以先来抛砖引个玉。。

Rank: 2Rank: 2

UID
1609118
帖子
244
PB币
29
贡献
0
技术
26
活跃
474
发表于 2017-8-14 08:55:44 |显示全部楼层
厉害了,大神

Rank: 5Rank: 5Rank: 5

UID
4521991
帖子
570
PB币
560
贡献
0
技术
0
活跃
966
发表于 2017-8-14 09:10:35 |显示全部楼层
我想知道主板是怎么改成苹果Mac的?

Rank: 7Rank: 7Rank: 7

UID
1969413
帖子
2579
PB币
2598
贡献
0
技术
21
活跃
1371
发表于 2017-8-14 09:46:47 |显示全部楼层
cheneyveron 发表于 2017-8-13 22:24
几乎没看到远景有X79安装好10.13的先例,所以先来抛砖引个玉。。

我的HP。X79我晚上试试

Rank: 2Rank: 2

UID
1886210
帖子
391
PB币
202
贡献
0
技术
3
活跃
666
发表于 2017-8-14 09:54:11 |显示全部楼层
q1005291049 发表于 2017-8-14 09:10
我想知道主板是怎么改成苹果Mac的?

同问,很好奇

Rank: 7Rank: 7Rank: 7

UID
1969413
帖子
2579
PB币
2598
贡献
0
技术
21
活跃
1371
发表于 2017-8-14 10:45:29 |显示全部楼层
PhysiX 发表于 2017-8-14 09:54
同问,很好奇

刷omziss修改

Rank: 2Rank: 2

UID
4699402
帖子
315
PB币
360
贡献
0
技术
0
活跃
317
发表于 2017-8-14 13:47:33 |显示全部楼层
q1005291049 发表于 2017-8-14 09:10
我想知道主板是怎么改成苹果Mac的?

我的主板BIOS是AMI的,用AMIBCP修改信息就行啦

Rank: 5Rank: 5Rank: 5

UID
4521991
帖子
570
PB币
560
贡献
0
技术
0
活跃
966
发表于 2017-8-14 16:03:56 |显示全部楼层
cheneyveron 发表于 2017-8-14 13:47
我的主板BIOS是AMI的,用AMIBCP修改信息就行啦

谢谢  晚上回去试试

苦逼的医学生。。。考试月勿扰,扣扣一概不回!

Rank: 11Rank: 11Rank: 11

UID
2043294
帖子
4556
PB币
319
贡献
0
技术
151
活跃
2025

7周年庆典勋章 8周年庆典勋章 我是大学生!

发表于 2017-8-14 16:11:31 |显示全部楼层
修改DMI信息就行了。。。

Rank: 5Rank: 5Rank: 5

UID
4199986
帖子
725
PB币
316
贡献
0
技术
0
活跃
1050
发表于 2017-8-14 16:52:50 |显示全部楼层
佩服楼主钻研能力。

Vanilla.

UID
4568967
帖子
13702
PB币
33049
贡献
0
技术
94
活跃
2662

巡察使 十一周年

发表于 2017-8-14 17:09:09 |显示全部楼层
本帖最后由 口袋妖怪heart 于 2017-8-14 17:17 编辑

我觉得更简单的方法,是否可以直接通过对 AppleACPIPlatform 打补丁解决?我记得 10.13 DP1 刚出的时候,Alex James (aka TheRacerMaster) 就 po 了这个文,不过因为我的机器没有这样的问题以及我的 ACPI 也超差,就没再多看了。
借着楼主的问题,刚好看了一下 AppleACPIPlatform 的逆向,如下:


所以,把这个 test 的值改掉就可以了我猜,比如改成 0xFF 。
补丁如下:
  1. Kext: AppleACPIPlatform
  2. Find: F6040797
  3. Repl: F60407FF
复制代码


楼主试一下?(以上 hex 来自 10.13 DP5)

此外,如需修改 ACPI 表但 iasl 编译不通过,可尝试直接用 hex 编辑器来操作。
附件: 你需要登录才可以下载或查看附件。没有帐号?注册

Rank: 2Rank: 2

UID
1533416
帖子
297
PB币
21
贡献
0
技术
44
活跃
300

7周年庆典勋章 8周年庆典勋章

发表于 2017-8-14 19:55:47 来自手机 |显示全部楼层
我的华南x79是2.47版本的BIOS,能用这个dsdt吗

Rank: 2Rank: 2

UID
4699402
帖子
315
PB币
360
贡献
0
技术
0
活跃
317
发表于 2017-8-14 22:32:23 |显示全部楼层
口袋妖怪heart 发表于 2017-8-14 17:09
我觉得更简单的方法,是否可以直接通过对 AppleACPIPlatform 打补丁解决?我记得 10.13 DP1 刚出的时候,Al ...

哇...欢迎口袋妖怪~我今天打算再探究一下,就用手机录了一下错误信息,发现我是isspace出的问题...不是isprint...很尴尬。
刚才反编译了一下,看到__ctype数组有256项,那个isprint的问题不可能是越界访问。
这个问题产生的根本原因其实是C语言中char的一个陷阱。默认的char是signed char包含符号的,我测试了一下,0x0~0x7f时,signed char和unsigned char都是一样的,但是一旦超过了0x7f,signed char其实就是负值了:
不过,只要简单的加一句转换语句就能避免这个问题,如下:

但是因为isprint函数没有转成unsigned char,所以当传进来一个大与0x7f的char时,根据它往__ctype查索引的话就直接溢出了,故而把改test值成FF可能不能解决问题。
要想打补丁的话,可以在isprint函数中先把参数转换成unsigned char在去__ctype查找索引,就像acpia做的那样:
#define isprint(c)  (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_XS | _ACPI_PU))
要转换成unsigned char,只需要 b = b & 0xff 即可:


用汇编语言实现转换unsigned char就是
and rdi, 0xff
二进制就是
48 81 e7 ff
但是不管用Hopper还是Clover都只能修改现成的,没办法添加上面那行代码...

所以归根到底,这要么是苹果程序员的失误,对signed char理解的不够深刻,苹果的acpi表又恰好没有高于0x7f的值,所以他们的测试人员也没发现问题。要么就是故意给广大黑苹果设的坎儿:)

至于isspace,在acpia的源码中isspace相当的简单,就是:
#define isspace(c)  (AcpiGbl_Ctypes[(unsigned char)(c)] & (_ACPI_SP))
其中_ACPI_SP = 0x20
而apple自己写的这个方法是这样的:

翻译成C语言就是这样:
int _isspace(int arg0) {
    rax = (int8_t) __ctype[arg0];
    rax = (rax & 0x20) >> 5;
    return rax;
}
查看一下调用栈,只有一个方法调用了它,就是AcpiUtStrtoul64,看起来就是在做单个字符的循环检测。所以问题应该又是出在_isspace本身没有把参数转换成unsigned char了。
同样的... 本来是在
mov al, byte [rdi+rax]
前面加上一句
and rdi, 0xff
就行

但是不会加...尝试数次均无果...


附件: 你需要登录才可以下载或查看附件。没有帐号?注册

Rank: 2Rank: 2

UID
4699402
帖子
315
PB币
360
贡献
0
技术
0
活跃
317
发表于 2017-8-14 22:32:58 |显示全部楼层
huangyuxuan01 发表于 2017-8-14 19:55
我的华南x79是2.47版本的BIOS,能用这个dsdt吗

试试就知道啦

Rank: 2Rank: 2

UID
4699402
帖子
315
PB币
360
贡献
0
技术
0
活跃
317
发表于 2017-8-14 23:10:49 |显示全部楼层
lwchangbing 发表于 2017-8-14 09:46
我的HP。X79我晚上试试

有木有什么头绪啦?

Rank: 2Rank: 2

UID
4699402
帖子
315
PB币
360
贡献
0
技术
0
活跃
317
发表于 2017-8-14 23:24:19 |显示全部楼层
忽然发现这里已经有Alex James的分析了。。
http://www.insanelymac.com/forum ... age-38#entry2441580

Rank: 1

UID
4817159
帖子
27
PB币
0
贡献
0
技术
0
活跃
201

十一周年

发表于 2017-8-14 23:35:57 来自手机 |显示全部楼层
建议用clover里的 ACPI - FixHeader  试试   
当时在DP2的时候还加了一个pike的补丁,后来就不用了

Vanilla.

UID
4568967
帖子
13702
PB币
33049
贡献
0
技术
94
活跃
2662

巡察使 十一周年

发表于 2017-8-15 00:28:34 |显示全部楼层
cheneyveron 发表于 2017-8-14 22:32
哇...欢迎口袋妖怪~我今天打算再探究一下,就用手机录了一下错误信息,发现我是isspace出的问题...不是i ...

Hmm... 如果没记错的话 rdi 是个指针?(我组合语言超差了啦) 然后 rdi 在这里作为一个 arg 来传递。然后这两个 caller 都会传递字符串喔?(如果 XREF 的话)    // 我的理解对吗?
  1. __text:0000000000001178 0F BE 3B                             movsx   edi, byte ptr [rbx] ; c
  2. __text:000000000000117B 31 C0                                xor     eax, eax
  3. __text:000000000000117D E8 4D E4 01 00                       call    _isspace
  4. __text:000000000000115A 41 0F BE 3F                          movsx   edi, byte ptr [r15] ; c
  5. __text:000000000000115E 85 FF                                test    edi, edi
  6. __text:0000000000001160 0F 84 4F 01 00 00                    jz      loc_12B5
  7. __text:0000000000001166 89 75 D4                             mov     [rbp+var_2C], esi
  8. __text:0000000000001169 31 C0                                xor     eax, eax
  9. __text:000000000000116B E8 5F E4 01 00                       call    _isspace
复制代码
简单搜寻了下调用栈。
ff? no 我觉得应该是需要 & 0x7f 吧,如果问题出在 7-bit ascii 或者 8-bit ascii 上。(不确定虽然)

然后关于patch bin 我觉得是不太可能了... 稍早的时候看了下 kextstat ,发现 AppleACPIPlatform 载入太早了:
  1.    13    1 0xffffff7f83539000 0x60000    0x60000    com.apple.driver.AppleACPIPlatform (5.0) 65E05472-6AE7-3308-8CC8-FA6CB0DB2AEE <12 11 7 6 5 4 3 1>
复制代码
所以用 Lilu 来 func routing 是不大可能... Clover patch的话 bytes 不够......

然后翻了下 Clover 的 log ,发现之前已经有相关的 patch 了。(18F
所以配合 Clover r4118+ 可以试试 FixHeaders_20000000

Rank: 2Rank: 2

UID
4699402
帖子
315
PB币
360
贡献
0
技术
0
活跃
317
发表于 2017-8-15 00:32:30 |显示全部楼层
口袋妖怪heart 发表于 2017-8-15 00:28
Hmm... 如果没记错的话 rdi 是个指针?(我组合语言超差了啦) 然后 rdi 在这里作为一个 arg 来传递。然后这 ...

除了这个以外我又找到另一个方法~

汇编语言在传参数的时候用的是xdi寄存器,而写寄存器依赖三个方法:mov、movsx和movzx。他们三个的区别在这:http://www.cnblogs.com/Reyzal/p/5142302.html
我写了一个很简单的C程序,一个用了char,一个用的unsigned char,然后反编译一下,
发现传char的时候是movsx xdi, 0x98
加上unsigned char类型强转以后用的是 movzx xdi, 0x98传值。
进一步的实验表明,使用movsx即传递的原值,movzx可以起到传递unsigned值的效果。

所以,只需要找到程序中调用_isprint前面的movsx edi, ... 改成 movzx edi, ... 即可从根本上解决unsigned问题。
因为天比较晚了,涉及_isprint的地方较多,所以来不及整理clover patch了。

我用类似的方法patch了_isspace前的代码,现在错误trace里面已经没有_isspace了,而是直接AcpiUtStrtoul64错误...这就很僵硬了。
目前只能等正式版出来,然后等着其他大神有什么巧妙的解决方案啦。。。
关闭

站长推荐

已经开启实名认证了哟
这里可以进行实名操作:点我点我点我
回顶部
Copyright (C) 2005-2019 pcbeta.com, All rights reserved
Powered by Discuz!  苏ICP备17027154号
请勿发布违反中华人民共和国法律法规的言论,会员观点不代表远景论坛官方立场。
远景在线 | 远景论坛 | 苹果论坛 | Win10论坛 | Win8论坛 | Win7论坛 | WP论坛 | Office论坛 | 电脑硬件 | 安卓软件