Patch pin

Tìm hiểu thuật ngữ

circle-info

Trước tiên ta phải hiểu nguyên tác hoạt động:

Các bản AppleACPIPlatform mới không thể nào truy cập chính xác vào trường EC (Embedded Controller) nên nó sẽ gây ra 1 số lỗi khi sử dụng các kext hiển thị phần trăm pin, bạn phải tiến hành sửa đổi DSDT để nó nhận chính xác mặc dù bạn có thể dùng các bản AppleACPIPlatform cũ hơn (Snow Leopard) nhưng vì các CPU đời Ivy Birdge + có hỗ trợ tính năng quản lý năng lượng nên mình khuyên các bạn nên dùng bản mới nhất. Để làm điều đó, chúng ta cần thay đổi các trường trong EC thành 8 bit để có thể truy cập cùng 1 lúc.

Tiến hành

Dùng kext ECEnabler

Khi dùng cách này thì khả năng 90% là nhận pin

B1: Tải kext ECEnabler từ nguồn sauarrow-up-right và bỏ vào thư mục EFI ⇒ OC hoặc EFI ==> CLOVER ==> KEXT ==> OTHER

B2 Snapshot config nếu dùng OpenCore.

B3: Tải SMCBattery.kext bỏ vô mục kext và snapshot lại

nếu dùng OpenCore

tải ở đây nhé Releases · acidanthera/VirtualSMC · GitHubarrow-up-right

B4: Reboot và tận hưởng.

Dùng các patch sẵn của RehabMan

B2: Các bạn download patch phù hợp với máy của các bạn tại đâyarrow-up-right.

Hầu hết các máy ASUS và Lenovo đều có patch.

B3: Xem patch nào hỗ trợ máy của bạn:

Các bạn vào các patch phù hợp với model máy và tìm xuống phần works for

B4: Tải patch và MaciASL tại đâyarrow-up-right.

B5: Dump DSDT và compile theo hướng dẫn tại đây.

B6: Áp dụng các patch theo hướng dẫn tại đây.

Lưu ý : Khi làm theo cách này thì lúc các bạn update firmware sẽ phải làm lại, nếu không muốn làm lại thì các bạn có thể trích DSDT theo hướng dẫn tại đây.

Static patch

Xác định phần cần patch:

B1: Các bạn dump DSDT theo hướng dẫn tại đây.

B2: Biên dịch DSDT thành .dsl theo hướng dẫn tại đây.

B3: Mở DSDT lên và search Embedded để xác định các trường EC.

Ở đây ta có 4 trường EC

  • ECOR

  • SMBX

  • SMB2

  • NSBS

B4: Ta tiến hành search các trường EC đã xác định ở trên

Ở đây ta có:

  • Biến NSBS xuất hiện ở 1 field

  • Biến SMB2 xuất hiện ở 2 field

  • Biến SMBX xuất hiện ở 3 field

  • Và biến ECOR xuất hiện ở 1 field

B5: Các bạn tiến hành nhìn vào các biến ở các field đã xác định ở trên.

Biến nào trên 8 bit thì ghi lại.

Lưu ý:

  • Đối với những trường 16 bit và 32 bit các bạn tiết hành search các trường đó nếu chỉ trả về 1 giá trị có nghĩa là trường đó không được sử dụng và có thể bỏ qua.

  • Ở đây ta có trường B0TM có 16 bit

    • Tuy nhiên khi search lại trường này tả chỉ thấy có 1 kết quả trả về. Tức trường này không được sử dụng và có thể bỏ qua.

Làm tương tự như vậy ta có:

Patch các trường 16 bit và 32 bit

Trường 16 bit:

circle-info

Để fix các trường 16 bit bạn sẽ tiến hành chia nhỏ các trường 16 bit thành 2 trường 8 bit

B1: Đặt tên cho 2 trường vừa tách. Tên mới không được trùng với các tên đã có trong DSDT

mẹo ở đây là bạn sẽ lấy tên của trường chính bỏ đi ký tự đầu tiên và thêm sau là các sô thứ tự. Cần tránh các tên bắt đầu bằn chữ số

B2: Tiến hành viết patch để tách các trường thành các trường nhỏ 8 bit.

B3: Tiến hành apply patch vừa viết theo hướng dẫn tại đây. Sau khi apply sẽ được như hình:

hình ảnh chỉ mang tính chất minh họa

B4: Ta sẽ tiến hành fix các lỗi. Do ở bước trên bạn đã tiên hành tách các trường 16 bit nên những method call qua trường này sẽ bị lỗi. Để fix lỗi đó các bạn sẽ tiến hành add method b1b2 vào:

B5: Nhấn compiler để tiến hành check lỗi.

B6: Các bạn sẽ ân vào vùng lỗi và tìm xem nó ở method nào.

B7: Ta sẽ tiến hành phân tích lỗi và viết patch.

Ở đây ta thấy nó báo lỗi trường B1SN khi nhấn vào thì sẽ hiện dòng code bị lỗi là Store (B1SN, Local0) ở method BIFA thì ta sẽ có cách dạng lỗi thường gặp:

  • Store (variableOrig, )

    • Đối với dạng này ta sẽ có cấu trúc fix chung là:

      • into method label <method> code_regex \(<variableOrig>, replaceall_matched begin (B1B2(<variable1>,<variable2>), end;

    • Ví dụ:

      • into method label BIFA code_regex \(B1SN, replaceall_matched begin (B1B2(B1SX,B1SK), end;

  • Store ( ,variableOrig)

    • Đối với dạn này ta sẽ có câu trúc fix chung là:

      • into method label <method> code_regex \<variableOrig>) replaceall_matched begin B1B2(<variable1>,<variable2>)) end;

    • Ví dụ:

      • into method label SMBW code_regex \DT2B) replaceall_matched begin B1B2(T2B1,T2B2)) end;

Ở trên là 2 dạng khá phổ biến mà bạn có thể gặp phải. Ngoài ra còn 1 dạng lỗi đặc biệt nữa như sau:

Ta có thể thấy biến bị lỗi được gắn với 1 đường dẫn. Vì vậy để fix lỗi này ta sẽ tiến hành thay toàn bộ đường dẫn bằng b1b2. Tuy nhiên bạn phải tiến hành gắn các biến trong b1b2 với đường dẫn đã thay thế

  • Cấu trúc chung:

    • into method label<method> code_regex \<path variableOrig>, replaceall_matched begin B1B2(<path variable1>, <path variable2>), end;

      • Xem các xác định path variable ở mục lưu ý

  • Ví dụ:

    • into method label _BIX code_regex \^\^LPCB.EC.B0C3, replaceall_matched begin B1B2(^\^LPCB.EC.B0CX, ^\^LPCB.EC.B0CK), end;

Chú ý:

  • Có nghĩa là method chứa dòng code lỗi như ở trên sẽ là _BIX

    • Vậy để xác định được method của dòng code lỗi ta sẽ ấn nút compiler để check lỗi và ấn vào lỗi cần fix nhìn vào gốc dưới bên trái để xác định được method cần dùng.

  • Cách xác định path variable1path variable2:

    • path variable Orig:_SB.PCI0.LPCB.EC.<variable Orig> ==>

    • path variable1:_SB.PCI0.LPCB.EC.<variable1>

    • path variable2:_SB.PCI0.LPCB.EC.<variable2>

  • Ví dụ:

    • path variable Orig: _SB.PCI0.LPCB.EC.B0C3 ==>

    • path variable1:_SB.PCI0.LPCB.EC.B0CX

    • path variable2:_SB.PCI0.LPCB.EC.B0CK

B8: Sau khi làm như trên ta sẽ được các patch:

Apply các patch theo hướng dẫn tại đây.

Trường 32 bit

circle-info

Ở đây do DSDT patch ở trên không có trường 32 bit nên ta sẽ dùng tạm DSDT khác để tiến hành patch trường 32 bit. Làm tương tự như P1 ta có các trường 32 bit sau:

B1: Ta sẽ tiến hành tách các trường 32 bit thành 4 trường 8 bit và đặt tên cho 4 trường đó:

B2: Ta tiến hành viết patch trương tự như ở trường 16 bit. Nhưng thay vì thay bằng 2 trường 8 bit ta sẽ tiến hành thay bằng 4 trường 8 bit. Sau khi làm xong ta được:

Tương tự như trường 16 bit ta vẫn sẽ gặp error.

B3: Để khắc phục điều này ta sẽ tiến hành tương tự như trường 16 bit nhưng thay vì add method B1B2 ta sẽ add method B1B4:

B4: Ta sẽ tiến hành add các patch fix lỗi tương tự như trường 16 bit nhưng thay B1B2 thành B1B4. Sau khi làm xong ta sẽ được:

B5: Tiến hành apply các patch.

P3: Patch các trường lớn hơn 32 bit

Như đã xác định ở P1 ta có các trường lớn hơn 32 bit là:

B1: Ta sẽ tiến hành đổi tên các trường này:

B2: Tiến hành viết patch

  • Cấu trúc chung:

    • into device label EC code_regex (<variableOrig>,)\s+(56) replace_matched begin <variablerenamed>,%2,//%1%2 end;

    • Giải thích cú pháp:

      • into device label EC code_regex (<variableOrig>,)\s+(56): tìm trong device EC đoạn code là BDAT, 256

      • replace_matched begin <variablerenamed>,%2,//%1%2 end;: là thay đoạn tìm thấy bằng DATX,256,//BDAT,256,

  • Ví dụ:

    • into device label EC code_regex (BDAT,)\s+(256) replace_matched begin DATX,%2,//%1%2 end;

    • into device label EC code_regex (BDA2,)\s+(256) replace_matched begin DA2X,%2,//%1%2 end;

B3: Apply patch vào DSDT.

B4: Ta tiến hành xác định offset ở các trường này. Có 2 trường hợp có thể xảy ra:

  • Thông thường thì ở các field sẽ có ít nhất 1 offset được cho trước

  • Như vậy ta có các offset sau:

    • B1TM: 0xDE

    • B1C1: 0xE0

    • B1C2: 0xE2

    • B1C3: 0xE4

  • Tuy nhiên có những trường hợp trong field không cho sẵn offset như là:

  • Ta sẽ nhìn vào OperationRegion (SMB2, EmbeddedControl, 0x40, 0x28)OperationRegion (SMBX, EmbeddedControl, 0x18, 0x28) ta có như sau:

    • 0x28 thì đang chỉ vị trị của Region này

    • 0x400x18 chính là offset lần của SMB2SMBX

Vậy ta sẽ có các offset sau:

  • BDAT: 0x1C

  • BDA2: 0x44

B5: Vì ta đã rename ở bước 2 nên khi compiler sẽ có error. Để khắc phục ta sẽ tiến hành add method RECB (Read EC Buffer) và WECB (Write EC Buffer)

  • Khi bạn check lỗi mà nhận được lỗi có dạng Store(<variableOrig>, )

    • thì nó sẽ thuộc method RECB

    • Ví dụ:

      • Store (BDAT, )

  • Khi check lỗi mà có dạng là Store( ,<variableOrig>)

    • thì nó sẽ thuộc method WECB

    • Ví dụ:

      • Store ( ,BDAT)

B6: Ta tiến hành viết patch. Tương tự như trường 16 bit và 32 bit việc đầu tiên ta cần làm là xác định đoạn code lỗi nằm ở method nào.

Như ảnh thì ta có thể thấy đoạn code lỗi nằm ở method SMBR. Tiến hành viết patch:

  • WECB

    • Cú pháp chung:

      • into method label <method> code_regex Store\s+((.*),\s+<variableOrig>) replaceall_matched begin WECB(<offset>,<size>,%1) end;

    • Ví dụ:

      • into method label SMBR code_regex Store\s+((.*),\s+BDAT) replaceall_matched begin WECB(0x1c,256,%1) end;

      • Giải thích cú pháp:

        • into method label SMBR code_regex Store\s+((.*),\s+BDAT): tức là sẽ tìm trong method SMBR đoạn code Store (zero, BDAT) (kí hiệu .* tức là đoạn code sẽ lấy giá trị ở trước trường BDAT trong đoạn code ở DSDT)

        • replaceall_matched begin WECB(0x1c,256,%1) end;: tức là tất cả đoạn code được tìm thấy ở trên sẽ được thay thế bằng (0x1c,256,zero) (kí hiệu %1 có nghĩa là lấy phần tử T1 trong đoạn code được tìm thấy)

  • RECB

    • Cú pháp chung:

      • into method label <method> code_regex (variableOrig, replaceall_matched begin (RECB(<offset>,<size>), end;

    • Ví dụ:

      • into method label SMBR code_regex (BDAT, replaceall_matched begin (RECB(0x1c,256), end;

      • Giải thích cú pháp:

        • into method label SMBR code_regex (BDAT,: tức là sẽ tìm trong method SMBR đoạn code (BDAT,

        • replaceall_matched begin (RECB(0x1c,256), end;: tức là sẽ thay thế tất cả các đoạn code được tìm thấy trong method SMBR bằng (RECB(0x1c,256),

Chú ý:

  • <offset> là offset mà bạn đã xác định ở B4

  • <method> là method mà bạn đã xác định ở B6

Sau khi làm xong ta sẽ có:

B7: Apply patch vào DSDT.

B8: Đối với 1 số dòng Asus thì bạn cần thêm patch Logic bug with charging/discharging status

circle-info

Vì 1 số laptop ASUS có thể gặp tình trạng khi sạc đầy nhưng hệ thống vẫn báo chưa đầy hoặc khi hết pin nhưng hệ thống vẫn báo chưa hết pin dẫn đến các lỗi như sập nguồn bất chợt ( lỗi nãy vẫn có thể xảy ra ở 1 só máy model khác ) cách fix là các bạn add đoạn sau vào

Sau khi làm xong tất cả các phần trên ta sẽ có đoạn patch sau:

File cho các bạn tham khảo: DSDT-Origarrow-up-right, DSDT-patchedarrow-up-right

Lưu ý: Bạn nên trích DSDT ra SSDT theo hướng dẫn tại đâyarrow-up-right. Vì nếu dùng DSDT thì khi update bios các patch sẽ bị mất tác dụng. Hoặc bạn có thể save file patched.txt lại để apply lại vào DSDT khi update BIOS.

Lưu ý 2: Khi các bạn không thể nào tìm thấy EmbeddedControl trong DSDT tức là pin của bạn không thuộc sự quản lý của EC Controler. Để khắc phục tình trạng này các bạn sẽ tiến hành update bios để cập nhật lại DSDT

chevron-rightLinh tinhhashtag

Pass cho những ai đang tìm: Heavietnam

Source tham khảo: [Guide] How to patch DSDT for working battery status | tonymacx86.comarrow-up-right | [Guide] Laptop Battery Indicator – The DSDT Patching Horror – Page 14 – Guides and Tutorials – Olarilaarrow-up-right ( thank you )

Last updated