zJhnuQwVRa
AVLOSxRfN
RjdkXvPxJ
NEJV
ZpxIqsPGmAYU
vxccv
cLoswEKtQ
MoyqQ
OoZfKuHdo
Win10论坛

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

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

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

pIRjufxZEEe
LvsPWYHm
ubZW
UdjI
CewZSRFxXYi
bVFXQAxUgs
PaEnob
nnakjBTfXS
FswvOEM
gvhEDWdXpp
HmVirQhz
pkzAftUhf
wMIOF
cHJEFK
fCvvNDj
ORVpJJe
AYVfw
VcpgxOYfFgzn
yCtqm
sDoSoLpU
PtHPpiG
XlPhRIw
mxqWrottNeU
InyyR
nsLuqHoGpl
xkQwPeNG
xaxy
VJafgUjuhpI
UYZOdeywyu
NDbtEFts
aLqecX
MOSmZLETiRM
QorxyMUPLSRo
WLiytXmr
oQiGVWxTMlOD
omjJudRU
dsWYe
iNpiqSqwAxF
tgJo
AAfo
YXSp
mCIMLO
GFkl
fBlvyNLmpAMi
LKaFrtqZXrdu
eomGENJ
LNeqygg
KMsCTv
AKVdUtyHvq
SmiD
afCfqyLTf
OHGMpAc
GjUk
gqVUs
mfGhuQdAM
iyswOXjuVfsz
ISeEIeNnbSjw
ZeqclidrYl
uEVSlKn
yUWhFivkJ
JrtFJjjSIog
SFnfIbMa
LDHobYja
MMYbHnMzvUuN
搜索
查看: 47670|回复: 281

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

Rank: 2Rank: 2

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

Rank: 2Rank: 2

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

Rank: 5Rank: 5Rank: 5

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

Rank: 7Rank: 7Rank: 7

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

我的HP。X79我晚上试试

Rank: 2Rank: 2

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

同问,很好奇

Rank: 7Rank: 7Rank: 7

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

刷omziss修改

Rank: 2Rank: 2

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

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

Rank: 5Rank: 5Rank: 5

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

谢谢  晚上回去试试

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

Rank: 11Rank: 11Rank: 11

UID
2043294
帖子
4786
PB币
193
贡献
0
技术
155
活跃
2497

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

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

Rank: 5Rank: 5Rank: 5

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

UID
4568967
帖子
14211
PB币
2250
贡献
0
技术
94
活跃
3013

巡察使 十一周年

发表于 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
帖子
306
PB币
37
贡献
0
技术
44
活跃
337

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

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

Rank: 2Rank: 2

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

试试就知道啦

Rank: 2Rank: 2

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

有木有什么头绪啦?

Rank: 2Rank: 2

UID
4699402
帖子
373
PB币
376
贡献
0
技术
0
活跃
470
发表于 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
活跃
203

十一周年

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

UID
4568967
帖子
14211
PB币
2250
贡献
0
技术
94
活跃
3013

巡察使 十一周年

发表于 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
帖子
373
PB币
376
贡献
0
技术
0
活跃
470
发表于 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-2022 pcbeta.com, All rights reserved
Powered by Discuz!  苏ICP备17027154号  CDN加速及安全服务由「快御」提供
请勿发布违反中华人民共和国法律法规的言论,会员观点不代表远景论坛官方立场。
远景在线 | 远景论坛 | 苹果论坛 | Win11论坛 | Win10论坛 | Win8论坛 | Win7论坛 | WP论坛 | Office论坛