hướng dẫn patch dsdt cho máy tính để bàn

62
I. Câu chuyn mđầu My hôm gn đây, tthy bn danght post rt nhiu kinh nghim hay trong vic cài Snow Leopard trên Desktop và Laptop, trong đó điu mà tquan tâm nht là kĩ thut patch DSDT ca bn y. Vì thế tquyết định thvc mt chút vDSDT vi hi vng là Mac OS shot động tt hơn. Thc ra tđã có mt chút kiến thc vDSDT và đã tng dùng phn mm DSDT Auto Patcher (madl0n) patch DSDT con main Gigabyte G31M-S2L ca tđể fix mt sthành phn như RTC, HPET, USB, ..., tđó phi hp vi Chameleon 2.0 RC5 mà bđược mt skext ngoài như LegacyAppleRTC, NullCPUPM và EVOReboot, ... và chy n định hơn. Nhưng bn thân tsa DSDT trc tiếp thì tchưa bao gith, vli chc năng sleep không hot động được nếu không có SleepEnabler, cho nên tmi quyết định táy máy mt chút để nâng cao kinh nghim và cũng là để gii quyết trn vn bài toán DSDT cho con main ca t. Và thế là tbt đầu đọc, ngâm cu các bài viết ca bn danght và tìm kiếm mt sthông tin trên mng. Sau đó tbt tay vào công vic. Da trên cái DSDT đã được patch đợt 1 bng DSDT Auto Patcher, tbt đầu chnh sa, thêm bt cho phù hp. Quá trình chnh sa khá phc tp, nhiu lúc điên lên vì gp li. Đã có ln chnh sa sai phn SATA dn đến không boot được, thm chí còn có ln quên không đổi tên file DSDT cho phù hp, dn đến Kernel panic, và khi khi động li thì ... ôi thôi, CMOS Reset do không fix RTC. Nhưng cui cùng, sau bao khó khăn cng vi khong chc ln reset máy, cui cùng tđã patch gn như hoàn chnh DSDT ca t, và đã đạt được các thành qusau: Phn cng, chc năng Kết quPhương thc CPU Intel Pentium Dual Core E5200 Speedstep OK (dùng Chameleon 2.0 RC5, đọc patch DSDT để bt Speedstep thy khó quá nên không làm, sau này snghiên cu tiếp). Nhit độ các nhân CPU (đo bng iStats) n định 37 o C và 26 o C Chameleon 2.0 RC5, bt GeneratePStates GenerateCStates nVidia GeForce 9400 GT Full QE/CI (patch DSDT, không cn ROM nVidia hay NVEnabler.kext) patch DSDT USB OK (UCHI – USB 1.1 và EHCI – USB 2.0 nhn đầy đủ) patch DSDT Time Machine Đã fix li, không cn EthernetBuiltIn trong Chameleon patch DSDT SATA Nhn đầy đủ, không cn JMicron36xSATA.kext patch DSDT Audio Nhn tt ccác cng, không cn Voodoo HDA patch DSDT + AppleHDA patch + ALC662.kext Sleep OK, không SleepEnabler.kext patch DSDT Shutdown, Restart OK, không EVOReboot.kext patch DSDT + RestartFix trong Chameleon HPET OK, không cn NullCPUPowerManagement.kext patch DSDT

Upload: le-cao-nguyen

Post on 29-Jun-2015

1.972 views

Category:

Documents


3 download

DESCRIPTION

Hướng dẫn patch DSDT cho máy tính để bàn

TRANSCRIPT

Page 1: Hướng dẫn patch DSDT cho máy tính để bàn

I. Câu chuyện mở đầu Mấy hôm gần đây, tớ thấy bạn danght post rất nhiều kinh nghiệm hay trong việc cài Snow Leopard trên Desktop và Laptop, trong đó điều mà tớ quan tâm nhất là kĩ thuật patch DSDT của bạn ấy. Vì thế tớ quyết định thử vọc một chút về DSDT với hi vọng là Mac OS sẽ hoạt động tốt hơn. Thực ra tớ đã có một chút kiến thức về DSDT và đã từng dùng phần mềm DSDT Auto Patcher (madl0n) patch DSDT con main Gigabyte G31M-S2L của tớ để fix một số thành phần như RTC, HPET, USB, ..., từ đó phối hợp với Chameleon 2.0 RC5 mà bỏ được một số kext ngoài như LegacyAppleRTC, NullCPUPM và EVOReboot, ... và chạy ổn định hơn. Nhưng bản thân tự sửa DSDT trực tiếp thì tớ chưa bao giờ thử, vả lại chức năng sleep không hoạt động được nếu không có SleepEnabler, cho nên tớ mới quyết định táy máy một chút để nâng cao kinh nghiệm và cũng là để giải quyết trọn vẹn bài toán DSDT cho con main của tớ. Và thế là tớ bắt đầu đọc, ngâm cứu các bài viết của bạn danght và tìm kiếm một số thông tin trên mạng. Sau đó tớ bắt tay vào công việc. Dựa trên cái DSDT đã được patch đợt 1 bằng DSDT Auto Patcher, tớ bắt đầu chỉnh sửa, thêm bớt cho phù hợp. Quá trình chỉnh sửa khá phức tạp, nhiều lúc điên lên vì gặp lỗi. Đã có lần chỉnh sửa sai phần SATA dẫn đến không boot được, thậm chí còn có lần quên không đổi tên file DSDT cho phù hợp, dẫn đến Kernel panic, và khi khởi động lại thì ... ôi thôi, CMOS Reset do không fix RTC. Nhưng cuối cùng, sau bao khó khăn cộng với khoảng chục lần reset máy, cuối cùng tớ đã patch gần như hoàn chỉnh DSDT của tớ, và đã đạt được các thành quả sau:

Phần cứng, chức năng

Kết quả Phương thức

CPU Intel Pentium Dual Core E5200

Speedstep OK (dùng Chameleon 2.0 RC5, đọc patch DSDT để bật Speedstep thấy khó quá nên không làm, sau này sẽ nghiên cứu tiếp). Nhiệt độ các nhân CPU (đo bằng iStats) ổn định ở 37oC và 26oC

Chameleon 2.0 RC5, bật GeneratePStates GenerateCStates

nVidia GeForce 9400 GT

Full QE/CI (patch DSDT, không cần ROM nVidia hay NVEnabler.kext)

patch DSDT

USB OK (UCHI – USB 1.1 và EHCI – USB 2.0 nhận đầy đủ) patch DSDT Time Machine Đã fix lỗi, không cần EthernetBuiltIn trong Chameleon patch DSDT SATA Nhận đầy đủ, không cần JMicron36xSATA.kext patch DSDT Audio Nhận tất cả các cổng, không cần Voodoo HDA patch DSDT +

AppleHDA patch + ALC662.kext

Sleep OK, không SleepEnabler.kext patch DSDT Shutdown, Restart

OK, không EVOReboot.kext patch DSDT + RestartFix trong Chameleon

HPET OK, không cần NullCPUPowerManagement.kext patch DSDT

Page 2: Hướng dẫn patch DSDT cho máy tính để bàn

RTC OK, không cần LegacyRTC.kext, không CMOS Reset patch DSDT LPC, PIC, TMR OK patch DSDT Việc tự chỉnh sửa đã đem lại cho mình rất nhiều kinh nghiệm về phần cứng, hệ thống Mac OS và kĩ thuật patch DSDT. Đọc lại các hướng dẫn patch DSDT trên mạng, mình thấy chúng vẫn chưa thật sự chi tiết và thường hướng tới phần cứng cố định. Vì vậy mình tự tổng hợp lại kinh nghiệm và quyết định post bài viết này để hỗ trợ các bạn patch DSDT dễ dàng và hiệu quả. Mặc dù kinh nghiệm còn ít, song hi vọng sẽ giúp được các bạn trong việc patch DSDT, để Mac OS hoạt động ổn định và hiệu quả hơn. Nguồn bài viết tham khảo:

Hướng dẫn về cài đặt Snow Leopard retail trên laptop dòng core 2 (danght)

Hướng dẫn cài đặt Mac OSX 10.6.5 lên PC dòng Core 2 Duol (danght)

Retail Snow Leopard lên dòng Core I (Scripted w/RAID 0 2SSD Scrip) (danght)

Vanila Speedstep CPU Core Duo cho đến Core i không cần Kext (danght)

Minimal DSDT Edits for Gigabyte Socket 1366 Motherboards (macmanx86)

Advanced DSDT Fixes: nVidia Graphics (tonymacx86)

Advanced DSDT Fixes: Enable Sleep on P55 Motherboards (tonymacx86)

Advanced DSDT Fixes: Enable Native Intel SpeedStep on P55 Motherboards (tonymacx86)

và rất nhiều bài viết khác trên các diễn đàn về HACKINTOSH (InsanelyMac, ProjectOSX, ...)

Bài viết này có thể còn sai sót, hi vọng được các bạn góp ý nhiệt tình.

Page 3: Hướng dẫn patch DSDT cho máy tính để bàn

II. Giới thiệu về DSDT và hướng dẫn patch DSDT cơ bản 1. DSDT là gì? Tại sao phải patch DSDT?

DSDT (Differentiated System Description Table) là bảng dữ liệu chính trong ACPI của BIOS, có nhiệm vụ mô tả các phần cứng trên bo mạch chủ, từ đó làm liên kết trung gian giữa một hệ điều hành tương thích chuẩn ACPI và BIOS. Các hệ điều hành như Windows hoặc Linux tương thích tốt với chuẩn ACPI nên cũng hiểu và vận hành tốt với DSDT của bo mạch chủ. Còn Mac OS không tương thích hoàn toàn với ACPI và chỉ hỗ trợ một phần DSDT, vì thế không thể dùng DSDT vanilla (DSDT nguyên gốc của bo mạch chủ chưa hề bị chỉnh sửa) để liên kết với Mac OS. Việc chỉnh sửa DSDT sao cho phù hợp với khả năng hỗ trợ và cách hiểu của Mac OS sẽ giúp cho các Kext (Kernel extension) của Mac OS điều khiển được phần cứng của PC. Từ đó có thể chạy được Mac OS trên PC mà không cần các kext bên ngoài, dẫn đến độ ổn định và hiệu năng được nâng cao. Công đoạn đó gọi là patch DSDT. Với một số phần cứng mà không có kext hỗ trợ hoặc kext hoạt động không hiệu quả thì patch DSDT là giải pháp tốt nhất và có thể là duy nhất (như đồ họa Intel GMA X3100 chẳng hạn). Lưu ý một điều là ta sẽ không thay đổi DSDT của bo mạch chủ, vì như thế sẽ làm cho hệ thống không chạy được các hệ điều hành thông dụng như Linux và Windows. Mà ở đây ta sẽ sử dụng khả năng DSDT Override của Chameleon bootloader cho phép load file DSDT đã patch để giả mạo DSDT của bo mach chủ, dẫn đến Mac OS liên kết được với các phần cứng mà không ảnh hưởng đến DSDT gốc của bo mạch chủ. 2. Tổng quát về cách patch DSDT DSDT của bo mạch chủ có thể được các phần mềm đặc biệt trích xuất thành file DSDT.AML và được dịch ngược thành file DSDT.DSL để thay đổi. Sau đó file DSDT.DSL đã patch thông qua trình biên dịch iasl sẽ thành file DSDT.AML. Cuối cùng chỉ cần kết hợp file DSDT.AML đã patch với Chameleon là xong. Quá trình này có thể thực hiện thủ công hoặc bằng phần mềm tự động. Hiện nay các chương trình chỉnh sửa DSDT đều cho phép thực hiện tự động một số patch mà mình muốn. Các công đoạn patch DSDT đều có các công việc chung như sau: + Thay đổi một số giá trị (Value), địa chỉ (Address), tên (Name),... của các đối tượng trong DSDT mà không phù hợp với Mac OS thành giá trị đúng. + Thay đổi một số lệnh trong các phương thức (Method) có trong DSDT sao cho phù hợp với Mac OS. + Thêm một số phương thức để Mac OS có thể nhận diện đầy đủ phần cứng (Method _DSM, Method DTGP, ...) Các công đoạn patch DSDT này có cách thức tương tự với việc lập trình, chỉ có điều cú pháp và các câu lệnh khác so với các ngôn ngữ phổ biến như C++ và các đối tượng cần xử lí là các biến, các địa chỉ phần cứng và các giá trị (thường ở dạng dãy nhị phân binary, số nguyên trong hệ cơ số 16 hexadecimal, xâu kí tự string, ...) 3. Các patch phổ biến trong DSDT. Dưới đây là các patch phổ biến trong việc patch DSDT cho Desktop (máy tính để bàn). Với Laptop, hoặc các phần cứng khác thì mình chưa có điều kiện nghiên cứu thêm, các bạn có thể tham khảo thêm trên mạng, trong các diễn đàn về HACKINTOSH.

Tên patch Công dụng DTGP Thêm method DTGP, là thành phần của method _DSM để Mac OS nhận diện các

loại phần cứng PC. _WAK chỉnh lại method _WAK để trả lại giá trị phù hợp, tránh cảnh báo (Warning) khi

biên dịch. Shutdown chỉnh lại method _PTS và thêm OperationRegion (PMRS) để shutdown. Sau đó

bật tiếp RestartFix trong Chameleon 2.0 RC5 . HID/CID chỉnh lại Device PWRB (Power Button) cho phép sleep bằng cách nhấn nút

power. HPET chỉnh lại Device HPET để nhận diện HPET (High Precision Event Timer), tránh lỗi

Kernel Panic do AppleIntelCPUPowerManagement.kext gây ra. RTC Fix lỗi CMOS Reset khi khởi động lại do không nhận RTC. IRQs Fix device PIC và device TMR để sửa lỗi audio trên một số bo mạch chủ.

Page 4: Hướng dẫn patch DSDT cho máy tính để bàn

Time Machine sửa lỗi Time Machine bằng cách chỉnh lại Device LAN0 để nhận diện card mạng LAN là built-in (gắn liền với bo mạch chủ). Tương đương với options EthernetBuiltIn trong Chameleon 2.0 RC5

LPC Chỉnh lại device LPC (Low Pin Count) như PX40 hoặc SBRG, từ đó bật kext AppleLPC để Mac OS quản lí năng lượng của các thiết bị.

UHCI/EHCI chỉnh lại các device UHCI (USB 1.1) và EHCI (USB 2.0) để Mac OS nhận diện được các cổng và thiết bị USB, hỗ trợ USB Sleep.

Audio ALCxxx + AZAL to HDEF

chỉnh sửa Device AZAL và đổi AZAL thành HDEF để Mac OS nhận diện đúng card âm thanh HD Audio.

SATA chỉnh lại device IDE1 thành device SATA và chỉnh lại các device PRIM (Primary) và SECD (Secondary) để nhận diện ổ SATA. Fix lỗi nhận diện nhầm ổ cứng internal thành external, dẫn đến biểu tượng màu vàng cam.

Bus0 và SBUS Nhận diện SMBUS SpeedStep Bật SpeedStep cho CPU hỗ trợ. Tương tự với 2 option GeneratePState và

GenerateCState của Chameleon 2.0 RC5 Và còn một số các patch khác nữa như patch nhận diện card đồ họa, patch cho card LAN, ... Nhiều patch trong số đó có thể tìm trên mạng hoặc trong các phần mềm patch DSDT như DSDT Simple Editor (EvOSX86 Team)

Page 5: Hướng dẫn patch DSDT cho máy tính để bàn

III. Cú pháp của ASL (ACPI Control Method Source Language) trong file DSDT.DSL Ở đây chỉ nói về các cú pháp cơ bản, không đi sâu vào ngôn ngữ ASL dùng để mô tả các bảng dữ liệu trong ACPI (DSDT, RSDT, FACP, ..), chỉ nhằm mục đích giúp các bạn hiểu một số cú pháp để việc chỉnh sửa dễ dàng hơn. Để tìm hiểu kĩ hơn, các bạn có thể tìm các tài liệu về ACPI và ngôn ngữ ASL trên mạng. 1. Các cú pháp thông dụng Từ khóa (Các tham số) { Mô tả chi tiết nếu có }

Cú pháp Chức năng Add ( Addend1, Addend2, Result )

Phép cộng 2 số Addend1, Addend2 và gán kết quả vào Result

And (Source1, Source2, Result)

Phép toán bitwise (xử lí bit) And 2 giá trị Source1, Source2, gán kết quả vào Result

Alias ( SourceObject, AliasObject )

Khai báo đối tượng AliasObject có giá trị trỏ đến SourceObject

Arg0 | Arg1 | Arg2 | Arg3 | Arg4 | Arg5 | Arg6

Nếu method có n tham số thì các tham số đó có tên gọi lần lượt là Arg0, Arg1, Arg2, ..., Arg[n-1] . Một method có tối đa 7 tham số (từ Arg0 đến Arg6)

Break Thoát giữa chừng vòng lặp while Buffer (BufferSize) { String or ByteList }

Khai báo một mảng có kích thước là BufferSize chứa các dữ liệu 1 byte

Concatenate (Source1, Source2, Result)

Ghép 2 dữ liệu trong Source1 và Source2 thành 1 dữ liệu chung trong Result Concatenate (“abc”, “def”, kq) : kq=”abcdef”

Continue Tiếp tục vòng lặp while, bỏ qua các câu lệnh tiếp theo sau Continue CopyObject (Source, Destination)

Copy dữ liệu từ Source đến Destination

Decrement (Minuend) Làm giảm giá trị của Minuend đi 1 DefinitionBlock (AMLFileName, TableSignature, ComplianceRevision, OEMID, TableID, OEMRevision) { TermList }

Khai báo mở đầu cho 1 bảng của ACPI (DSDT, FACP, RSDT, ...), cụ thể hóa nội dung của bảng trong TermList

Device (DeviceName) { ObjectList }

Khai báo thiết bị tên là DeviceName, cụ thể hóa trong ObjectList

Divide (Dividend, Divisor, Remainder, Result)

Chia Dividend cho Divisor được thương là Result, dư là Remainder

EISAID (EisaIdString)

Chuyển EisaIdString về một số nguyên mô tả EISA ID của 1 thiết bị VD: EisaID(“PNP0C08”)

Else { TermList }

Câu lệnh rẽ nhánh trong trường hợp còn lại của If và ElseIf

Page 6: Hướng dẫn patch DSDT cho máy tính để bàn

ElseIf (Predicate) { TermList }

Mô tả một nhánh khác của câu lệnh rẽ nhánh nếu điều kiện ở Predicate cho giá trị thỏa mãn (một số nguyên khác 0 hoặc True)

Field (RegionName, AccessType, LockRule, UpdateRule) { FieldUnitList }

Từ khóa Field khai báo một trường dữ liệu trong OperationRegion (cái này mình không rõ)

Function (FunctionName, ReturnType, ParameterTypes) { TermList }

Khai báo một hàm tên FunctionName, dữ liệu trả về có kiểu là ReturnType, danh sách tham số là ParameterTypes, các câu lệnh của hàm nằm trong TermList Khai báo Method có NotSeriallized cũng cho tác dụng tương tự

If (Predicate) { TermList }

Câu lệnh rẽ nhánh: Nếu điều kiện ở Predicate cho giá trị thỏa mãn (một số nguyên khác 0 hoặc True) thì thực hiện các câu lệnh trong TermList, còn không thì xét các ElseIf tiếp theo và Else.

Increment (Addend) Tăng giá trị của Addend lên 1 đơn vị. Index (Source, IndexNum, Destination)

Trỏ đến phần tử có chỉ số là IndexNum trong biến Source (biến Source có kiểu dữ liệu là Buffer, String, hoặc Package)

IRQNoFlags (DescriptorName) { InterruptList }

Khai báo một bảng ngắt IRQ (cái này mình không rõ lắm)

LAnd (Source1, Source2)

Nếu 2 giá trị Source1, Source2 khác 0 thì kết quả là True, ngược lại là False

LEqual (Source1, Source2)

Nếu 2 giá trị Source1, Source2 giống nhau thì kết quả là True, ngược lại là False

LGreater (Source1, Source2)

Nếu Source1 lớn hơn Source2 thì kết quả là True, ngược lại là False

LGreaterEqual (Source1, Source2)

Nếu Source1 lớn hơn hoặc bằng Source2 thì kết quả là True, ngược lại là False

LLess (Source1, Source2)

Nếu Source1 nhỏ hơn Source2 thì kết quả là True, ngược lại là False

LLessEqual (Source1, Source2)

Nếu Source1 nhỏ hơn hoặc bằng Source2 thì kết quả là True, ngược lại là False

LNot (Source) Nếu Source bằng 0 thì kết quả là True, ngược lại là False LNotEqual (Source1, Source2)

Nếu 2 giá trị Source1, Source2 khác nhau thì kết quả là True, ngược lại là False

LOr (Source1, Source2)

Nếu 1 trong 2 giá trị Source1, Source2 khác 0 hoặc cả hai đều khác 0 thì kết quả là True, ngược lại là False

Memory32Fixed (ReadAndWrite, AddressBase, RangeLength, DescriptorName)

Khai báo một dãy địa chỉ bộ nhớ (cái này mình không rõ)

Method (MethodName, NumArgs, SerializeRule, SyncLevel, ReturnType, ParameterTypes) { TermList }

Khai báo một phương thức (một khối lệnh) tên MethodName, số lượng tham số là NumArgs, đặc điểm là Serialized hoặc NotSerialized, các câu lệnh được mô tả trong TermList. Các tham số tùy chọn như SyncLevel, ReturnType, ParameterTypes thì mình không rõ, tương tự như khai báo trong Function.

Page 7: Hướng dẫn patch DSDT cho máy tính để bàn

Mid (Source, Index, Length, Result)

Copy Length dữ liệu từ vị trí Index ở trong Source vào Result . Source có thể là Buffer, String, hoặc Package

Mod (Dividend, Divisor, Result)

Phép gán modulo (số dư) vào Result khi chia Dividend cho Divisor

Multiply (Multiplicand, Multiplier, Result)

Phép nhân 2 số Multiplicand, Multiplier và gán kết quả vào Result

Name (ObjectName, Object)

Khai báo đối tượng tên ObjectName có giá trị khởi tạo là Object

NAnd (Source1, Source2, Result)

Phép toán bitwise (xử lí bit) NAnd 2 giá trị Source1, Source2, gán kết quả vào Result

NOr (Source1, Source2, Result)

Phép toán bitwise (xử lí bit) NOr 2 giá trị Source1, Source2, gán kết quả vào Result

Not (Source, Result) Phép toán bitwise (xử lí bit) Not giá trị Source, gán kết quả vào Result Notify (Object, NotificationValue)

Nhắc hệ điều hành rằng có sự kiện xảy ra ở Object với giá trị NotificationValue. Object thường là Device, Processor, hoặc ThermalZone

ObjectType (Object) Trả về một số nguyên cho biết kiểu dữ liệu của Object One Hẳng số nguyên mang giá trị là 1 (dãy bit mà bit cuối cùng là 1, các bit còn lại là 0)

hay 0x01 Ones Hẳng số nguyên mang giá trị là 1 dãy bit mà tất cả các bit là 1 (VD: 0xFFFFFFFF) OperationRegion (RegionName, RegionSpace, Offset, Length)

Khai báo một OperationRegion

Or (Source1, Source2, Result)

Phép toán bitwise (xử lí bit) Or 2 giá trị Source1, Source2, gán kết quả vào Result

Package (NumElements) { PackageList }

Khai báo một gói dữ liệu kích thước là NumElements, danh sách các phần tử trong gói được mô tả ở PackageList

PowerResource (ResourceName, SystemLevel, ResourceOrder) { ObjectList }

Khai báo một Power Resource

Processor (ProcessorName, ProcessorID, PBlockAddress, PblockLength) { ObjectList }

Khai báo một nhân CPU

RefOf (Object) Trả về con trỏ liên kết tới Object ResourceTemplate () { ResourceMacroList }

Khai báo một ResourceTemplate

Return (Arg) Kết thúc method và trả về giá trị Arg Scope (Location) { ObjectList }

Khai báo một Scope (phạm vi) chứa một tập hợp các đối tượng

ShiftLeft (Source, ShiftCount, Result)

Phép toán dịch ShiftCount bit của Source sang trái và gán kết quả vào Result

ShiftRight (Source, ShiftCount, Result)

Phép toán dịch ShiftCount bit của Source sang phải và gán kết quả vào Result

Page 8: Hướng dẫn patch DSDT cho máy tính để bàn

SizeOf (ObjectName) Cho biết kích thước của ObjectName (String, Buffer, Package) Sleep (MilliSeconds) Tạm dừng phương thức trong MilliSeconds ms (1/1000 giây) Store (Source, Destination)

Gán giá trị của Source vào Destination

Subtract (Minuend, Subtrahend, Result)

Phép trừ Minuend cho Subtrahend và gán kết quả vào Result

ThermalZone (ThermalZoneName) { ObjectList }

Khai báo một ThermalZone

While (Predicate) { TermList }

Vòng lặp: Nếu điều kiện ở Predicate còn cho giá trị thỏa mãn (một số nguyên khác 0 hoặc True) thì thực hiện các câu lệnh trong TermList, còn không thì thoát khỏi vòng lặp.

Zero Hẳng số nguyên mang giá trị là 0 (1 dãy bit mà tất cả các bit là 0) hay 0x00 2. Các tên chuẩn Các tên này được chuẩn hóa để hệ điều hành tương thích chuẩn ACPI có thể tìm đúng thiết bị cần giao tiếp và thực hiện đúng các phương thức. Một số tên chuẩn được viết đầy đủ như sau (nghĩa của chúng có thể tra cứu trong các tài liệu về ACPI):

Tên Viết đầy đủ _ADR Address _ATT Type-Specific Attribute _ASI Address Space Id _ASZ Access Size _BAS Base Address _BBN Bios Bus Number _BCL Brightness Control Levels _BCM Brightness Control Method _BCT Battery Charge Time _BFS Back From Sleep _BIF Battery Information _BM Bus Master _BST Battery Status _BTM Battery Time _CID Compatible ID _CRS Current Resource Settings _CST C States _DDC Display Data Current _DDN Dos Device Name _DGS Display Graphics State _DMA Direct Memory Access _DOD Display Output Devices _DOS Disable Output Switching _DSM Device Specific Method _DSS Device Set State _DSW Device Sleep Wake _Exx Edge GPE (ex: E01, E02, E0A, ...) _EC Embedded Controller _FIF Fan Information _FPS Fan Performance States _FST Fan Status _GL Global Lock _GLK Global Lock

Page 9: Hướng dẫn patch DSDT cho máy tính để bàn

_GPE General Purpose Events _GTS Going To Sleep _GTM Get Timing Mode _HID Hardware ID _INI Initialize _INT Interrupts _Lxx Level GPE (ex: L01, L1D, L1E, ...) _LCK Lock _LEN Length _LID Lid _MAF Maximum Address Fixed _MAT Multiple Apic Table Entry _MAX Maximum Base Address _MEM Memory Attributes _MIF Minimum Address Fixed _MIN Minimum Base Address _MSG Message _MSM Memory Set Monitoring _OFF Off _ON On _OS Operating System _OSC Operating System Capabilities _OSI Operating System Interfaces _OST Ospm Status Indication _PCL Power Consumer List _PCT Performance Control _PDC Processor Driver Capabilities _PDL P-state Depth Limit _PIC PIC _PIF Power Source Information _PPC Performance Present Capabilites _PR Processor _PR0 Power Resources for D0 _PR1 Power Resources for D1 _PR2 Power Resources for D2 _PR3 Power Resources for D3 _PRS Possible Resource Settings _PRT Pci Routing Table _PRW Power Resources for Wake _PS0 Power State 0 _PS1 Power State 1 _PS2 Power State 2 _PS3 Power State 3 _PSC Power State Current _PSD Processor State Dependencies _PSR Power Source _PSS Performance Supported States _PSW Power State Wake _PTS Prepare To Sleep _Qxx Query (ex: Q01, Q02, ...) _REG Region _REV Revision _ROM Read-Only Memory _S0 S0 System State _S1 S1 System State

Page 10: Hướng dẫn patch DSDT cho máy tính để bàn

_S2 S2 System State _S3 S3 System State _S4 S4 System State _S5 S5 System State _S1D S1 Device State _S2D S2 Device State _S3D S3 Device State _S4D S4 Device State _S0W S0 Device Wake State _S1W S1 Device Wake State _S2W S2 Device Wake State _S3W S3 Device Wake State _S4W S4 Device Wake State _SB System Bus _SBS Smart Battery Subsystem _SDD Set Device Data _SI System Indicators _SIZ Size _SLI System Locality Information _SPD Set Post Device _SRS Set Resource Settings _SST System Status _STA Status _STM Set Timing Mode _STR String _SUN Slot User Number _T_x Temporary variables (ex: _T_0, _T_1, ...) _TMP Temperature _TZ Thermal Zone _TZD Thermal Zone Devices _UID Unique ID _WAK Wake _Wxx Wake Event (ex: W01, W02, ...) 3. Cặp ngoặc nhọn mô tả một đối tượng Cặp ngoặc nhọn {} là kí hiệu dùng để đóng gói các nội dung trong một đối tượng hoặc đóng gói các câu lệnh trong một phương thức VD: Device (BUS0) { Name (_CID, "smbus") Name (_ADR, Zero) Device (DVL0) { Name (_ADR, 0x57) Name (_CID, "diagsvault") Method (_DSM, 4, NotSerialized) { Store (Package (0x03) { "address", 0x57, Buffer (One) {

Page 11: Hướng dẫn patch DSDT cho máy tính để bàn

0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } } } {} đóng gói các đối tượng con của Device (BUS0) {} đóng gói các đối tượng con của Device (DVL0) {} đóng gói các lệnh của Method (_DSM, 4, NotSerialized) {} {} đóng gói các giá trị trong Package (0x03) và Buffer (One) 4. Chú thích: Các dòng chữ có tác dụng hỗ trợ người lập trình hiểu nội dung code, bị trình biên dịch bỏ qua Chú thích 1 dòng: dùng kí hiệu // Chú thích nhiều dòng: Dùng cặp /* */ VD: //Hello /* Hello My name is DSDT */ 5. Các kiểu dữ liệu phổ biến và cách biểu diễn giá trị a. Dữ liệu số nguyên: có thể dùng làm dữ liệu số cho các biến hoặc mô phỏng địa chỉ phần cứng Dữ liệu số nguyên có thể biểu diễn dưới dạng * Số nguyên hệ thập phân (decimal, dec): 1, 10, 8, 128, ... Dạng này thường không dùng trong DSDT. * Dạng nhị phân (binary, bin): gồm 1 dãy n bit mô tả số nguyên ở hệ cơ số 2. Dạng này ít khi dùng trong DSDT vì độ dài của 1 dãy bit có thể rất lớn. VD: 1001102 = 3810 Các dãy nhị phân thường có độ dài là 1 byte (8 bit), 2 byte (16 bit), 4 byte (32 bit), 8 byte (64 bit), ... Độ dài của dãy nhị phân thể hiện kích thước dữ liệu của số nguyên đó VD: 000100102 = 1810 là số nguyên 8 bit. Kích thước của số nguyên 8 bit là 256 (từ giá trị 000000002 = 010 đến giá trị 111111112 = 25510) * Số nguyên hệ cơ số 16 (hexadecimal, hex): có dạng 0x[dãy kí tự mô tả số] . Đây là dạng số nguyên được dùng nhiều nhất trong DSDT. VD : 0xC0 = C016 = 19210 = 1100 00002 0x08 = 816 = 810 = 10002 0x0A = A16 = 1010 = 10102 Cứ 4 bit của một dãy nhị phân được đổi thành 1 kí tự trong dãy hex, 2 kí tự của dãy hex đổi thành 1 byte (8 bit) của dãy nhị phân.

Page 12: Hướng dẫn patch DSDT cho máy tính để bàn

VD: 0x001F0002 = 0000 0000 0001 1111 0000 0000 0000 00102: giá trị hex thể hiện một địa chỉ 32 bit (8 kí tự x 4 bit) 0x8086 = 1000 0000 1000 01102 : giá trị hex thể hiện một số nguyên 16 bit Các phần mềm Calculator có sẵn trong windows có thể giúp bạn chuyển đổi số nguyên giữa các hệ 16, 10, 2 b. Môt số hằng số dạng số nguyên Zero: 0x00 = 0 One: 0x01 = 1 Ones: dãy bit mà tất cả đều là bit 1. Tùy theo kích thước của dữ liệu mà Ones cho giá trị khác nhau: 0xFF = 255, 0xFFFF = 65535, 0xFFFFFFFF = 4294967295, ... c. Dữ liệu xâu: String Xâu được biểu diễn bằng 1 dãy kí tự ASCII (Bảng kí tự chuẩn Anh-Mỹ) đặt trong cặp ngoặc kép “” . Các kí tự trong xâu (Char) là các kí tự thuộc bảng mã ASCII (thường là các kí tự có trên bàn phím). VD: “device-id”, “name”, “hello”, ... Số kí tự trong xâu nằm trong đoạn từ 0 đến 255 Kích thước của xâu là (số kí tự +1) byte, vì ngoài các kí tự thực của xâu có kích thước 1 byte còn có 1 kí tự NULL (rỗng) đặt ở cuối xâu để kết thúc xâu. Vì thế kiểu dữ liệu String còn có tên đầy đủ là Null-terminated String. d. Kiểu mảng 1 byte (Buffer) Dùng để đóng gói các dữ liệu cùng kiểu có kích thước 1 byte như số nguyên hoặc kí tự. Khai báo bằng cú pháp: Buffer ([kích thước mảng]) { [các dữ liệu trong mảng] } Các dữ liệu trong mảng đều phải có cùng kích thước là 1 byte. Kích thước dữ liệu trong mảng là tổng số byte của các dữ liệu trong nó. Kích thước khai báo của mảng không được nhỏ hơn kích thước dữ liệu trong mảng (lớn hơn cũng được, nên khai báo bằng kích thước dữ liệu trong mảng) VD: Buffer (0x04) { 0x03, 0x01, 0x00, 0x00 } khai báo một mảng 4 byte gồm 4 số nguyên kiểu 1 byte. Buffer (0x08) { "display" } khai báo một mảng 8 byte chứa xâu kí tự "display" Các bạn sẽ thấy lạ là tại sao buffer có kích thước 8 byte mà xâu kí tự chỉ có 7 kí tự, thế có phải là thừa không? Thực tế là không vì như đã giải thích ở trên, kích thước dữ liệu của xâu phải là 7+1=8 byte chứ không phải là 7 byte.

Page 13: Hướng dẫn patch DSDT cho máy tính để bàn

e. Kiểu gói dữ liệu (Package) Trong các patch, gói dữ liệu thường được dùng như 1 bảng thuộc tính gồm nhiều thuộc tính và giá trị của chúng. Khai báo bằng cú pháp: Package ([n x 2]) { [Tên thuộc tính 1], [Giá trị của thuộc tính 1], [Tên thuộc tính 2], [Giá trị của thuộc tính 2], ... [Tên thuộc tính n], [Giá trị của thuộc tính n] } Tên thuộc tính có kiểu string, và giá trị của thuộc tính có thể là số nguyên, String, Buffer hoặc Package. Thường người ta sử dụng Buffer làm giá trị cho các thuộc tính. Nếu gọi n là số thuộc tính thì nx2 là số phần tử trong bảng thuộc tính. Kích thước khai báo của bảng thuộc tính không được nhỏ hơn số phần tử có trong bảng (nên khai báo đúng bằng nx2). VD: Package (0x02) { "device-id", Buffer (0x04) { 0xC8, 0x27, 0x00, 0x00 } } khai báo một bảng gồm 1 thuộc tính là “device-id” và giá trị là 1 buffer 4 byte Package (0x1A) { "@0,compatible", Buffer (0x0B) { "NVDA,NVMac" }, "@0,device_type", Buffer (0x08) { "display" }, "@0,display_cfg", Buffer (0x08) { 0x03, 0x01, 0x00, 0x00 }, "@0,name", Buffer (0x0F) { "NVDA,Display-A" }, "@1,compatible", Buffer (0x0B)

Page 14: Hướng dẫn patch DSDT cho máy tính để bàn

{ "NVDA,NVMac" }, "@1,device_type", Buffer (0x08) { "display" }, "@1,display_cfg", Buffer (0x08) { 0xFF, 0xFF, 0x00, 0x01 }, "@1,name", Buffer (0x0F) { "NVDA,Display-B" }, "NVCAP", Buffer (0x14) { /* 0000 */ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, /* 0008 */ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, /* 0010 */ 0x00, 0x00, 0x00, 0x00 }, "VRAM,totalsize", Buffer (0x04) { 0x00, 0x00, 0x00, 0x20 }, "device_type", Buffer (0x0D) { "NVDA,GeForce" }, "model", Buffer (0x17) { "nVidia GeForce 9400 GT" }, "rom-revision", Buffer (0x25) { "nVidia GeForce 9400 GT OpenGL Engine" } } khai báo một bảng thuộc tính gồm 13 thuộc tính (1A16 = 26 = 13x2)

Page 15: Hướng dẫn patch DSDT cho máy tính để bàn

IV. Các bước chuẩn bị để patch DSDT 1. Chuẩn bị - Hiển nhiên là bạn phải có Mac OS, nếu không thì patch làm chi. Cố gắng tìm các giải pháp kext ngoài hoặc dùng bootloader Chameleon để nhận diện càng nhiều phần cứng càng tốt, tất nhiên là phải hoạt động ổn định. Các kext nên dùng phiên bản mới nhất, Chameleon nên update lên RC5 vì có nhiều tính năng mới. Một giải pháp tốt cho việc này là gói MultiBeast do tonymacx86 phát triển, tích hợp rất nhiều các kext cần thiết và bootloader Chameleon 2.0 RC5. Tải MultiBeast ở trang chủ tonymacx86.com . Khi cài đặt phải chọn đúng các kext để Mac OS có thể nhận diện đúng phần cứng.

- Để thiết lập Chameleon dễ dàng hơn, bạn nên tải về Chameleon.prefpane phiên bản mới nhất, và cài đặt nó vào System Preferences.

- Bạn chỉ có thể patch DSDT khi bạn biết được thông tin về phần cứng. Vì thế bạn nên có hệ điều hành Windows đã nhận diện đủ phần cứng, từ đó bạn có thể lấy các thông tin trong Device Manager làm thông tin trong quá trình patch. Tất nhiên Mac OS có một số công cụ để tìm thông tin phần cứng nhưng dùng Windows vẫn là tốt nhất - Bạn nên update BIOS để phần cứng hoạt động tốt hơn. Ngoài ra phải tinh chỉnh BIOS phù hợp: SATA AHCI nếu có, HPET để là 64 bit. - Bạn cần có một phần mềm dùng để patch DSDT có đi kèm trình biên dịch iasl mới nhất. Có thể kiếm phần mềm DSDTSE hoặc DSDT Editor . Mình dùng DSDT Editor vì phần mềm có khả năng chỉnh sửa tốt, chạy được trên nhiều hệ điều hành. Còn mình khuyên các bạn nên dùng DSDTSE trên Mac OS do có nhiều patch hay và các fix khá cụ thể. Đương nhiên các bạn có thể đọc các patch đó và áp dụng trên DSDT Editor là được.

Page 16: Hướng dẫn patch DSDT cho máy tính để bàn

- Bạn cần có IORegistryExplorer. Phần mềm này cho phép bạn xem chi tiết các thông tin phần cứng của bạn trên Mac OS và kiểm tra xem patch đã hoạt động hiệu quả chưa. Phần mềm đi kèm theo XCode, nhưng bạn có thể tải riêng ở đây

Page 17: Hướng dẫn patch DSDT cho máy tính để bàn

- Bạn có thể kiếm một số tool khác hỗ trợ trong việc xem thông tin phần cứng, như Everest cho windows, System Info.app để đọc địa chỉ phần cứng cho Mac OS.

- Trong Chameleon 2.0 RC5, bạn nên bật sẵn các options sau EthernetBuiltIn: nhận diện card LAN là built-in, fix lỗi Time Machine RestartFix: fix restart và shutdown GeneratePStates và GenerateCStates: bật speedstep cho CPU DropSSDT: cái này mình ko rõ, nó có liên quan đến bảng SSDT chứa các thông tin P-States và C-States cho CPU. USBBusFix: Fix cho USB UHCI/EHCI 2. Một số kiến thức về địa chỉ phần cứng Các phần cứng thông thường (các Device trong Device (PCI) của DSDT) được nhận diện bằng 1 địa chỉ 32 bit. Mỗi địa chỉ 32 bit này gồm 2 phần: Device ID (ID của thiết bị) và Vendor ID (ID của hãng sản xuất). Device ID và Vendor ID là 2 số nguyên 16 bit (4 kí tự Hex). VD:

ID Device ID Vendor ID 0x064110DE 0641 (GeForce 9400 GT 512 MB) 10DE (hãng nVidia) 0x27C08086 27C0 (ICH7 SATA Controller) 8086 (hãng Intel) Lưu ý là các hệ điều hành và phần cứng ngày nay đều lên 64 bit, vì thế các thiết bị mới sẽ sử dụng địa chỉ 64 bit (cũng gồm 2 phần Device ID và Vendor ID, mỗi phần có độ dài 32 bit – 8 kí tự hex). Để các phần cứng 32 bit tương thích với các thiết bị 64 bit thì ta có thể coi như thêm 16 bit 0 (4 chữ số 0 ở hệ 16) vào đầu Device ID và 16 bit 0 vào đầu Vendor ID là được. VD: 0x064110DE chuyển thành địa chỉ 64 bit sẽ là 0x00000641000010DE, trong đó 00000641 là Device ID và 000010DE là Vendor ID. Các phần cứng trên ngoài ID chính có thể có ID SubSystem đi kèm (cũng có cấu tạo gồm Subsystem Device ID và Subsystem Vendor ID) như trên. Cái này bạn không cần để ý.

Page 18: Hướng dẫn patch DSDT cho máy tính để bàn

VD : 0x50011458 Subsystem Device ID: 5001 Subsystem Vendor ID: 1458 (Gigabyte)

Khi patch DSDT, tùy theo yêu cầu về dữ liệu, ta có thể phải đảo các thành phần trong địa chỉ phần cứng, Device ID và Vendor ID cho phù hợp. VD: 1, Khi nhập dữ liệu cho thuộc tính device-id, ta sẽ phải cắt Device ID thành các số nguyên 8 bit (2 kí tự Hex) và đọc ngược lại các số đó. Xét với Device ID 0x27C0 (trong 64 bit là 000027C0) như sau

Sai Đúng "device-id", Buffer (0x04) { 0x27, 0xC0, 0x00, 0x00 }

"device-id", Buffer (0x04) { 0xC0, 0x27, 0x00, 0x00 }

2, Khi nhập dữ liệu cho thuộc tính name, ta phải đảo Device ID và Vendor ID. Xét với địa chỉ 0x27DA8086 như sau

Sai Đúng "name", "pci27da,8086",

"name", "pci8086,27da",

Ngoài ra còn một số loại địa chỉ phần cứng khác đối với các phần cứng gắn trên mainboard như sau: * Địa chỉ thực (Address): Một số thiết bị nằm trên PCI Bus có loại địa chỉ này. Khai báo trong DSDT bằng cú pháp Name (_ADR,[địa chỉ]) VD: Name (_ADR, 0x001F0003) : Địa chỉ 0x001F0003 * Địa chỉ HID/CID (Hardware ID/Compatible ID): Khai báo trong DSDT bằng cú pháp Name (_zzz, EisaId ("xxxyyyy")) zzz là HID hoặc CID xxx và yyyy là các thành phần của xâu địa chỉ, chẳng hạn như “PNP0A03”, “APP0006” VD: Name (_HID, EisaId ("PNP0A03")) : địa chỉ HID PNP0A03 Trong các phần tiếp theo, để thống nhất mình sẽ gọi các loại địa chỉ này như sau: - ID phần cứng: 0x27C08086 (Device ID: 27C0, Vendor ID 8086) - ID Subsys: 0x50011458 (Subsys Device ID: 5001, Subsys Vendor ID: 1458) - Địa chỉ ADR: 0x001F0003 - Địa chỉ HID/CID: PNP0A03 3. Hướng dẫn xem địa chỉ trong Device Manager * Vào Control Panel -> Device Manager hoặc Start -> Run..., gõ devmgmt.msc, bấm Enter * Để xem thông tin về một thiết bị phần cứng, bấm chuột phải vào phần cứng đó, chọn Properties, vào mục Details

Page 19: Hướng dẫn patch DSDT cho máy tính để bàn

* Các mục có thể chứa ID phần cứng (ID chính và Subsys)

- Hardware ID, Compatible ID, Device Instance Path: PCI\VEN_8086&DEV_27DA&SUBSYS_50011458&REV_01 8086 : Vendor ID 27DA : Device ID 5001: Subsys Device ID 1458: Subsys Vendor ID 01: Phiên bản phần cứng (Revision)

Page 20: Hướng dẫn patch DSDT cho máy tính để bàn

* Các mục có thể chứa địa chỉ ADR - Address (nếu có) Ví dụ với LPC là 001F0003 * Các mục có thể chứa địa chỉ HID/CID - Parent (nếu Device đó không phải là Device con trong DSDT, như PCI bus chẳng hạn) - Hardware ID, Compatible ID Ví dụ với HPET, do nó là Device con của LPC nên không xem bằng Parent được, phải xem qua Hardware ID (“PNP0103”) 4. Hướng dẫn xem thông tin trong IORegistryExplorer - Trong Mac OS, mở IORegistryExplorer.app . Chọn View -> Browser để xem cho dễ.

- Toàn bộ thông tin về các Device đang hoạt động sẽ xuất hiện trong Root/[model máy]/AppleACPIPlatformExpert (1) - Các Device liên kết với PCI bus (SATA, USB, Audio, Card đồ họa, ...) xuất hiện trong mục Root/[model máy]/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI - Bấm vào mỗi Device, các thuộc tính sẽ xuất hiện trong bảng thuộc tính bên cạnh. Bảng thuộc tính gồm có các cột sau: + Property: Tên thuộc tính + Type: kiểu dữ liệu của thuộc tính. Quy đổi kiểu dữ liệu của thuộc tính sang kiểu dữ liệu tương ứng trong DSDT như sau: Data -> Buffer | Number -> số nguyên hex | String -> String + Value: Giá trị của thuộc tính Các thuộc tính này là cơ sở dữ liệu để sử dụng trong DSDT. Một số thuộc tính cơ bản nên để ý như sau:

Page 21: Hướng dẫn patch DSDT cho máy tính để bàn

Tên thuộc tính Ý nghĩa, cách hiểu device-id Device ID phần cứng, nhận được bằng cách đọc ngược các sô nguyên trong mảng

VD: C0 27 00 00 thì Device ID là 0x27C0 (trong 64 bit là 0x000027C0) Như đã nói ở trên, Mac OS là hệ điều hành 64 bit nên ID phần cứng là 64 bit, trong đó Device ID là 32 bit (4 byte, tương ứng với 4 ô nhớ ở trên)

vendor-id Vendor ID phần cứng, cách hiểu cũng như Device ID subsystem-id Subsystem Device ID subsystem-vendor-id

Subsystem Vendor ID

revision-id Revision (phiên bản phần cứng) name Tên phần cứng IOName Tên phần cứng (dùng để nhập-xuất, thường thì giống với name)

Cái này mình không rõ lắm, dịch theo cách hiểu mà thôi acpi-path Đường dẫn tới phần cứng

Xét ACPI path sau: IOACPIPlane:/_SB/PCI0@0/LPCB@1f0000 - IOACPIPlane: Gốc DSDT - _SB: Scope _SB - PCI0@0: Device (PCI0), địa chỉ ADR là 0 (0x00000000) - LPCB@1f0000: Device (LPCB), địa chỉ ADR là 0x001F0000

5. Đặc điểm của Method _DSM - Với các phần cứng thông thường, để Mac OS nhận diện được nó ta phải patch DSDT bằng cách thêm method _DSM vào Device tương ứng với phần cứng đó. Nội dung của method _DSM như sau: Method (_DSM, 4, NotSerialized) { Store (Package (nx2) { [thuộc tính 1], [giá trị thuộc tính 1], [thuộc tính 2], [giá trị thuộc tính 2], ... [thuộc tính n], [giá trị thuộc tính n] }, Local0) // Lưu trữ bảng thuộc tính vào biến Local0 DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) // Gọi method DTGP Return (Local0) //Kết thúc method _DSM và trả về gíá trị Local0 } Khi gọi method _DSM, Mac OS sẽ nhận được thông tin về phần cứng trong bảng thuộc tính, từ đó kext của Mac OS điều khiển được phần cứng. Tên phần cứng được nhận diện và các thuộc tính của nó sẽ xuất hiện trong IORegistryExplorer. Thường ta cần phải bổ sung thuộc tính device-id vào bảng. Ngoài ra còn một số thuộc tính khác tùy theo loại phần cứng và chức năng mà ta muốn bổ sung. Dữ liệu cho các thuộc tính này có thể được lấy bằng cách nhận diện phần cứng bằng kext ngoài, sau đó dùng IORegistryExplorer để lấy dữ liệu của phần cứng đó. Thành phần quan trọng của Method _DSM là method DTGP. Chính vì thế ta phải bổ sung Method DTGP vào DSDT thì Method _DSM mới hoạt động. Ví dụ về method _DSM nhận diện cổng USB bằng device-id (0x27C8) Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "device-id", Buffer (0x04)

Page 22: Hướng dẫn patch DSDT cho máy tính để bàn

{ 0xC8, 0x27, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } Ví dụ về method _DSM nhận diện âm thanh Realtek ALC662. Trong trường hợp này ta không cần Device ID mà cần các thuộc tính khác. Kích thước của bảng là 0x08 = 8 (4 thuộc tính x 2) Method (_DSM, 4, NotSerialized) { Store (Package (0x08) { "codec-id", Buffer (0x04) { 0x62, 0x06, 0xEC, 0x10 }, "layout-id", Buffer (0x04) { 0x96, 0x02, 0x00, 0x00 }, "device-type", Buffer (0x11) { "ALC662" }, "PinConfigurations", Buffer (Zero) {} }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) }

Page 23: Hướng dẫn patch DSDT cho máy tính để bàn

V. Tạo file DSDT.dsl và fix các lỗi đầu tiên Những hướng dẫn dưới đây sẽ được thực hiện trên DSDT Editor, với DSDTSE các bạn làm tương tự. Trong các fix này tớ dùng replace [Từ 1] -> [Từ 2] có nghĩa là thay thế tất cả các vị trí xuất hiện [Từ 1] thành [Từ 2] 1. Tạo file DSDT.dsl Mở DSDT Editor, vào Menu File, chọn Extract DSDT. Sau đó vào Menu File -> Save DSL, chọn vị trí lưu file, đặt tên là dsdt.dsl hay gì cũng được, nên để đuôi là .dsl

2. Lưu ý trong cách sử dụng DSDT Editor Việc patch DSDT có thể thực hiện lần lượt cho từng phần cứng một, vì vậy bạn nên tạo nhiều bản DSDT cho mỗi lần patch thêm một phần cứng nào đó. Để biên dịch file dsl thành file aml, bạn vào menu IASL -> Compile. Nếu Compile thành công, không còn bất cứ Error hay Warning nào thì bạn vào menu IASL -> Save AML As, chọn vị trí lưu file aml Để xem vị trí lỗi (error) hay cảnh báo (warning) nằm ở đâu sau khi biên dịch, bạn bấm đúp chuột vào lỗi, con trỏ văn bản sẽ ngay lập tức di chuyển đến vị trí chứa lỗi. Sau khi sửa lỗi xong thì compile luôn để kiểm tra xem lỗi đã thật sự sửa được chưa. Để DSDT hoạt động tốt, các lỗi và cảnh báo đều phải được xử lí hết. DSDT Editor có nút Fix Error để sửa lỗi, không sửa cảnh báo. Vì vậy bạn nên xem các DSDT Fixes trong DSDTSE rồi áp dụng tương tự lên DSDT của bạn. Ngoài ra bạn có thể cập nhật trình biên dịch IASL và phần mềm lên phiên bản mới nhất. Dưới đây là một số lỗi phổ biến mà tôi sẽ giới thiệu với các bạn. Các lỗi khác có thể xem hướng dẫn trong các Fix của DSDTSE. 3. Fix warning: Reserved method must return a value Lỗi này xảy ra khi method không trả về giá trị nào. Thêm các câu lệnh Return một cách phù hợp với giá trị cần trả về.

Trước Sau Method (_STA, 0, NotSerialized) { STAL (0x60) }

Method (_STA, 0, NotSerialized) { Return (STAL (0x60)) }

Method (_PSR, 0, NotSerialized) { If (\_SB.PCI0.PIB.EC.ECOK) { Return (\_SB.PCI0.PIB.EC.ADP) } }

Method (_PSR, 0, NotSerialized) { If (\_SB.PCI0.PIB.EC.ECOK) { Return (0x01) } Else { Return (0x00) } }

Lỗi này thường gặp ở method _WAK. Bạn chỉ cần thêm đoạn code sau vào cuối nội dung method _WAK

Page 24: Hướng dẫn patch DSDT cho máy tính để bàn

Return (Package (0x02) { Zero, Zero }) VD:

Trước Sau Method (\_WAK, 1, NotSerialized) { Store (0xFF, DBG1) If (LEqual (Arg0, 0x03)) { Store (0x8F, SCP) } If (LEqual (Arg0, 0x04)) { If (LEqual (OSFL, 0x00)) { If (LEqual (OSFX, 0x03)) { Store (0x59, SMIP) } Else { Store (0x58, SMIP) } } If (LEqual (OSFL, 0x01)) { Store (0x56, SMIP) } If (LEqual (OSFL, 0x02)) { Store (0x57, SMIP) } If (LEqual (OSFX, 0x03)) { Store (0x59, SMIP) } } If (LEqual (Arg0, 0x01)) {} If (OSFL) { Notify (\_SB.PWRB, 0x02) } Else { If (LEqual (RTCW, 0x00)) { Notify (\_SB.PWRB, 0x02) } } Notify (\_SB.PCI0.USB0, 0x00) Notify (\_SB.PCI0.USB1, 0x00) Notify (\_SB.PCI0.USB2, 0x00) Notify (\_SB.PCI0.USB3, 0x00) }

Method (\_WAK, 1, NotSerialized) { Store (0xFF, DBG1) If (LEqual (Arg0, 0x03)) { Store (0x8F, SCP) } If (LEqual (Arg0, 0x04)) { If (LEqual (OSFL, 0x00)) { If (LEqual (OSFX, 0x03)) { Store (0x59, SMIP) } Else { Store (0x58, SMIP) } } If (LEqual (OSFL, 0x01)) { Store (0x56, SMIP) } If (LEqual (OSFL, 0x02)) { Store (0x57, SMIP) } If (LEqual (OSFX, 0x03)) { Store (0x59, SMIP) } } If (LEqual (Arg0, 0x01)) {} If (OSFL) { Notify (\_SB.PWRB, 0x02) } Else { If (LEqual (RTCW, 0x00)) { Notify (\_SB.PWRB, 0x02) } } Notify (\_SB.PCI0.USB0, 0x00) Notify (\_SB.PCI0.USB1, 0x00) Notify (\_SB.PCI0.USB2, 0x00) Notify (\_SB.PCI0.USB3, 0x00) Return (Package (0x02) { Zero, Zero }) }

Page 25: Hướng dẫn patch DSDT cho máy tính để bàn

4. Fix Warning: Result is not used, operator has no effect Cảnh báo này là do cú pháp của toán tử chưa đúng (thiếu tham số thứ 3 chứa kết quả). Sửa lại các tham số cho phù hợp.

Trước Sau Or (0x03, PARM) Or (PARM, 0x03, PARM) And (CTRL, 0x1E) And (CTRL, 0x1E, CTRL) 5. Fix Error: Method local variable is not initialized (Local0) Lỗi này là do câu lệnh Store (Local0, Local0)trong đó biến Local0 chưa được khởi tạo. Có 3 cách sửa lại câu lệnh này như sau - Comment câu lệnh này: Thêm cặp ngoặc /* */ vào 2 đầu câu lệnh. - Đổi tham số thứ nhất thành Zero (Store (Zero, Local0))) . Cái này nên dùng. - Đóng ngoặc kép tham số thứ nhất (Store (“Local0”, Local0)) . Cái này dùng với main Gigabyte.

Trước Sau Scope (\_SI) { Method (_MSG, 1, NotSerialized) { Store (Local0, Local0) } Method (_SST, 1, NotSerialized) { Store (Local0, Local0) } }

Scope (\_SI) { Method (_MSG, 1, NotSerialized) { Store (Zero, Local0) } Method (_SST, 1, NotSerialized) { Store (Zero, Local0) } }

Scope (\_SI) { Method (_MSG, 1, NotSerialized) { Store (Local0, Local0) } Method (_SST, 1, NotSerialized) { Store (Local0, Local0) } }

Scope (\_SI) { Method (_MSG, 1, NotSerialized) { Store (“Local0”, Local0) } Method (_SST, 1, NotSerialized) { Store (“Local0”, Local0) } }

6. Fix Warning: Not all control paths return a value Cảnh báo này xảy ra khi Method có thể không trả về giá trị nào trong một số trường hợp không lường trước. Để xử lí cảnh báo này, ta chỉ cần thêm các câu lệnh Return một cách thích hợp hoặc sửa lại một số giá trị trả về để đề phòng những trường hợp không trả về giá trị nào.

Trước Sau Method (_BTP, 1, NotSerialized) { If (LEqual (\ECFL, Zero)) { Return (0x0F) } Else { Store ("_SB.CMB0._BTP", Debug) } }

Method (_BTP, 1, NotSerialized) { If (LEqual (\ECFL, Zero)) { Return (0x0F) } Else { Store ("_SB.CMB0._BTP", 0x0F) /*Sua lai gia tri tra ve*/ } }

Page 26: Hướng dẫn patch DSDT cho máy tính để bàn

Method (EVNT, 1, NotSerialized) { While (VZOK) { If (LEqual (VZOK, 0x01)) { Store (Arg0, VZOK) Notify (\_SB.VALZ, 0x80) Return (Zero) } Else { Sleep (0x05) } } }

Method (EVNT, 1, NotSerialized) { While (VZOK) { If (LEqual (VZOK, 0x01)) { Store (Arg0, VZOK) Notify (\_SB.VALZ, 0x80) Return (Zero) } Else { Sleep (0x05) } } Return (Zero) /*Them cau lenh Return*/ }

7. Fix Error: Host Operation Region requires ByteAcc access Sửa lại về ByteAcc là xong. Với các lỗi về WordAcc, DWordAcc, ... cũng làm tương tự

Trước Sau OperationRegion (ECRM, EmbeddedControl, Zero, 0xFF) Field (ECRM, DWordAcc, Lock, Preserve)

OperationRegion (ECRM, EmbeddedControl, Zero, 0xFF) Field (ECRM, ByteAcc, Lock, Preserve)

8. Fix Error: Reserved method has too few arguments Việc khai báo method không đủ tham số gây ra lỗi này. Chỉnh lại số lượng tham số về giá trị đúng (trong lỗi sẽ thông báo cụ thể cần bao nhiêu tham số)

Trước Sau Method (_EJ0, 0, NotSerialized) Method (_EJ0, 1, NotSerialized) 9. Fix Error: Reserved method has too many arguments Việc khai báo method thừa tham số gây ra lỗi này. Chỉnh lại số lượng tham số về giá trị đúng (trong lỗi sẽ thông báo cụ thể cần bao nhiêu tham số)

Trước Sau Method (_GLK, 1, NotSerialized) Method (_GLK, 0, NotSerialized) hoặc

Method (_GLK) Ngoài ra còn một số lỗi khác ít gặp hơn. Các bạn có thể tra cứu các lỗi đó trên Google hoặc sử dụng tính năng Fix Error trong DSDT Editor.

Page 27: Hướng dẫn patch DSDT cho máy tính để bàn

VI. Các patch DSDT thông dụng dành cho máy để bàn Với mỗi patch DSDT, bạn nên sao lưu lại DSDT chứa các patch trước đó để nếu patch sai còn có thể sửa lại. Khi patch DSDT, bạn nên Compile lại để xem patch có bị lỗi gì không. Patch đến đâu, bạn có thể thử file DSDT.AML đã patch đến đó để kiểm tra xem patch có hoạt động không, bởi vì các patch gần như độc lập với nhau. 1. DTGP DTGP là thành phần của Method _DSM dùng để nhận diện phần cứng của Mac OS. Thêm method này vào cuối file DSDT.dsl, nằm trong DefinitionBlock. Method (DTGP, 5, NotSerialized) { If (LEqual (Arg0, Buffer (0x10) { /* 0000 */ 0xC6, 0xB7, 0xB5, 0xA0, 0x18, 0x13, 0x1C, 0x44, /* 0008 */ 0xB0, 0xC9, 0xFE, 0x69, 0x5E, 0xAF, 0x94, 0x9B })) { If (LEqual (Arg1, One)) { If (LEqual (Arg2, Zero)) { Store (Buffer (One) { 0x03 }, Arg4) Return (One) } If (LEqual (Arg2, One)) { Return (One) } } } Store (Buffer (One) { 0x00 }, Arg4) Return (Zero) } VD:

Trước Sau DefinitionBlock ("dsdt.aml", "DSDT", 1, "GBT ", "GBTUACPI", 0x00001000) { … Scope (_SB) { } }

DefinitionBlock ("dsdt.aml", "DSDT", 1, "GBT ", "GBTUACPI", 0x00001000) { … Scope (_SB) { } Method (DTGP, 5, NotSerialized) { … } }

Page 28: Hướng dẫn patch DSDT cho máy tính để bàn

2. HID/CID Trong Device (PWRB), thay HID thành CID là được. Fix này giúp chức năng Sleep khi nhấn nút Power hoạt động.

Trước Sau Device (PWRB) { Name (_HID, EisaId ("PNP0C0C")) Method (_STA, 0, NotSerialized) { Return (0x0B) } }

Device (PWRB) { Name (_CID, EisaId ("PNP0C0C")) Method (_STA, 0, NotSerialized) { Return (0x0B) } }

Vào System Preferences -> Energy Saver, đánh dấu thiết lập Allow power button to put computer to sleep là xong. 3. HPET Có 2 bước trong fix HPET để nhận diện HPET và tránh Kernel Panic khi load AppleIntelCPUPowerManagement.kext * Sửa method _STA và method _CRS - Nếu có khai báo Name (_CRS, ResourceTemplate () {…}) thì đổi _CRS thành ATT3. Sửa ReadOnly thành ReadWrite nếu có.

Trước Sau Name (_CRS, ResourceTemplate () { Memory32Fixed (ReadOnly, 0xFED00000, // Address Base 0x00000400, // Address Length ) })

Name (ATT3, ResourceTemplate () { Memory32Fixed (ReadWrite, 0xFED00000, // Address Base 0x00000400, // Address Length ) })

- Thêm ATT4 vào HPET nếu chưa có Name (ATT4, ResourceTemplate () { }) - Sửa method _STA để luôn trả về giá trị 0x0F Method (_STA, 0, NotSerialized) { Return (0x0F) } - Sửa method _CRS để luôn trả về giá trị ATT3 Method (_CRS, 0, NotSerialized) { Return (ATT3) } * Thêm đoạn code sau trong ResourceTemplate() của ATT3 IRQNoFlags () {0} IRQNoFlags () {8}

Page 29: Hướng dẫn patch DSDT cho máy tính để bàn

VD :

Trước Sau Device (HPET) { Name (_HID, EisaId ("PNP0103")) Name (ATT3, ResourceTemplate () { Memory32Fixed (ReadWrite, 0xFED00000, // Address Base 0x00000400, // Address Length ) }) Name (ATT4, ResourceTemplate () { }) Method (_STA, 0, NotSerialized) { If (LGreaterEqual (OSFX, 0x03)) { If (HPTF) { Return (0x0F) } Else { Return (0x00) } } Else { Return (0x00) } } Method (_CRS, 0, NotSerialized) { If (LGreaterEqual (OSFX, 0x03)) { If (HPTF) { Return (ATT3) } Else { Return (ATT4) } } Else { Return (ATT4) } } }

Device (HPET) { Name (_HID, EisaId ("PNP0103")) Name (ATT3, ResourceTemplate () { IRQNoFlags () {0} IRQNoFlags () {8} Memory32Fixed (ReadWrite, 0xFED00000,// Address Base 0x00000400,// Address Length ) }) Name (ATT4, ResourceTemplate () { }) Method (_STA, 0, NotSerialized) { Return (0x0F) } Method (_CRS, 0, NotSerialized) { Return (ATT3) } }

Cuối cùng, bạn chỉ việc xóa NullCPUPowerManagement.kext là được. Trong IORegistryExplorer bạn sẽ thấy HPET và load được AppleHPET.kext

4. RTC Có 2 bước để fix CMOS Reset do lỗi RTC. * Đổi giá trị của Length thành 0x02. Để an toàn bạn có thể đổi trong cả ATT1 cũng được.

Page 30: Hướng dẫn patch DSDT cho máy tính để bàn

Trước Sau Name (ATT0, ResourceTemplate () { IO (Decode16, 0x0070, // Range Minimum 0x0070, // Range Maximum 0x00, // Alignment 0x04, // Length ) }) Name (ATT1, ResourceTemplate () { IO (Decode16, 0x0070, // Range Minimum 0x0070, // Range Maximum 0x00, // Alignment 0x04, // Length ) })

Name (ATT0, ResourceTemplate () { IO (Decode16, 0x0070, // Range Minimum 0x0070, // Range Maximum 0x00, // Alignment 0x02, // Length ) }) Name (ATT1, ResourceTemplate () { IO (Decode16, 0x0070, // Range Minimum 0x0070, // Range Maximum 0x00, // Alignment 0x04, // Length ) })

* Xóa hoặc comment đoạn code IRQNoFlags () {8} Ngoài ra có thể sửa method _CRS để luôn trả về giá trị ATT1 (giống như fix HPET). Khi đó phải chỉnh ATT0 và ATT1 đều là 0x02. VD:

Trước Sau Device (RTC) { Name (_HID, EisaId ("PNP0B00")) Name (ATT0, ResourceTemplate () { IO (Decode16, 0x0070, // Range Minimum 0x0070, // Range Maximum 0x00, // Alignment 0x04, // Length ) IRQNoFlags () {8} }) Name (ATT1, ResourceTemplate () { IO (Decode16, 0x0070, // Range Minimum 0x0070, // Range Maximum 0x00, // Alignment 0x04, // Length ) }) Method (_CRS, 0, NotSerialized) { If (LGreaterEqual (OSFX, 0x03)) { If (HPTF) { Return (ATT1) } Else { Return (ATT0) } } Else { Return (ATT0) } } }

Device (RTC) { Name (_HID, EisaId ("PNP0B00")) Name (ATT0, ResourceTemplate () { IO (Decode16, 0x0070, // Range Minimum 0x0070, // Range Maximum 0x00, // Alignment 0x02, // Length ) /*Xóa IRQNoFlag () {8}*/ }) Name (ATT1, ResourceTemplate () { IO (Decode16, 0x0070, // Range Minimum 0x0070, // Range Maximum 0x00, // Alignment 0x04, // Length ) }) Method (_CRS, 0, NotSerialized) { If (LGreaterEqual (OSFX, 0x03)) { If (HPTF) { Return (ATT1) } Else { Return (ATT0) } } Else { Return (ATT0) } } }

Như vậy bạn không cần kext LegacyRTC nữa, xóa nó đi để kiểm tra xem patch hoạt động không.

Page 31: Hướng dẫn patch DSDT cho máy tính để bàn

5. PIC, TMR, DMA Có 2 bước trong fix PIC, TMR, DMA * Replace PIC thành IPIC, TMR thành TIMR, DMA1 thành DMAC * Xóa IRQNoFlags trong IPIC và TIMR * Sửa method _CRS của TIMR để luôn trả về giá trị ATT6 (tương tự fix HPET). Do ATT6 và ATT5 giống nhau nên việc này không thật sự cần thiết. VD:

Trước Sau Device (PIC) { Name (_HID, EisaId ("PNP0000")) Name (_CRS, ResourceTemplate () { IO (Decode16, 0x0020, // Range Minimum 0x0020, // Range Maximum 0x01, // Alignment 0x02, // Length ) IO (Decode16, 0x00A0, // Range Minimum 0x00A0, // Range Maximum 0x01, // Alignment 0x02, // Length ) IRQNoFlags () {2} }) }

Device (IPIC) { Name (_HID, EisaId ("PNP0000")) Name (_CRS, ResourceTemplate () { IO (Decode16, 0x0020, // Range Minimum 0x0020, // Range Maximum 0x01, // Alignment 0x02, // Length ) IO (Decode16, 0x00A0, // Range Minimum 0x00A0, // Range Maximum 0x01, // Alignment 0x02, // Length ) }) }

Device (TMR) { Name (_HID, EisaId ("PNP0100")) Name (ATT5, ResourceTemplate () { IO (Decode16, 0x0040, // Range Minimum 0x0040, // Range Maximum 0x00, // Alignment 0x04, // Length ) IRQNoFlags () {0} }) Name (ATT6, ResourceTemplate () { IO (Decode16, 0x0040, // Range Minimum 0x0040, // Range Maximum 0x00, // Alignment 0x04, // Length ) }) Method (_CRS, 0, NotSerialized) { If (LGreaterEqual (OSFX, 0x03)) { If (HPTF) { Return (ATT6) } Else { Return (ATT5) } } Else { Return (ATT5) } } }

Device (TIMR) { Name (_HID, EisaId ("PNP0100")) Name (ATT5, ResourceTemplate () { IO (Decode16, 0x0040, // Range Minimum 0x0040, // Range Maximum 0x00, // Alignment 0x04, // Length ) }) Name (ATT6, ResourceTemplate () { IO (Decode16, 0x0040, // Range Minimum 0x0040, // Range Maximum 0x00, // Alignment 0x04, // Length ) }) Method (_CRS, 0, NotSerialized) { Return (ATT6) } }

Device (DMA1) { ... }

Device (DMAC) { ... }

Page 32: Hướng dẫn patch DSDT cho máy tính để bàn

Lưu ý: Trong DSDT của máy Mac thì các Device có tên khác với tên tương ứng trong DSDT của PC (PIC thành IPIC, TMR thành TIMR, ...). Việc đổi tên các Device về tên đúng trong DSDT của máy Mac sẽ giúp Mac OS nhận diện tốt hơn. Với laptop, để kích hoạt tính năng giảm độ sáng khi chuyển sang dùng pin, ta chuyển đoạn code IRQNoFlags từ TIMR về IPIC

TIMR IPIC Device (TIMR) { Name (_HID, EisaId ("PNP0100")) /* IRQNoFlags () {2} */

Device (IPIC) { Name (_HID, EisaId ("PNP0000")) Name (CRS, ResourceTemplate () { IO (Decode16, 0x0020, // Range Minimum 0x0020, // Range Maximum 0x01, // Alignment 0x02, // Length ) IO (Decode16, 0x04D0, // Range Minimum 0x04D0, // Range Maximum 0x01, // Alignment 0x02, // Length ) IRQNoFlags () /* Di chuyen tu TIMR */ {2}

6. Nhận diện PCI Bridge - Tìm thiết bị PCI Bridge trong Device Manager, mục System devices. Tra cứu Device ID và Address của thiết bị, thông thường Address của thiết bị là 0x001E0000

- Trong DSDTEditor, tìm 0x001E0000, ta sẽ tìm được device PCI Bridge. Tên của Device thường là PCIB. Nếu khác thì ta Replace thành PCIB Device (PCIB) { Name (_ADR, 0x001E0000) … }

Page 33: Hướng dẫn patch DSDT cho máy tính để bàn

Thêm method _DSM vào cuối Device (PCIB) có nội dung như sau Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "device-id", Buffer (0x04) { 0x4E, 0x24, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } Đổi giá trị trong Buffer của thuộc tính device-id cho phù hợp với Device ID của bạn. PCI Bridge của mình có Device ID là 0x244E thì mình đổi các giá trị trong Buffer là 0x4E, 0x24, 0x00, 0x00 VD:

Trước Sau Device (PCIB) { Name (_ADR, 0x001E0000) Method (_STA, 0, NotSerialized) { Return (0x0F) } … Method (_PRW, 0, NotSerialized) { Return (Package (0x02) { 0x0B, 0x05 }) } }

Device (PCIB) { Name (_ADR, 0x001E0000) Method (_STA, 0, NotSerialized) { Return (0x0F) } … Method (_PRW, 0, NotSerialized) { Return (Package (0x02) { 0x0B, 0x05 }) } Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "device-id", Buffer (0x04) { 0x4E, 0x24, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } }

Kiểm tra kết quả bằng cách mở IORegistryExplorer, kiểm tra ở mục sau

Page 34: Hướng dẫn patch DSDT cho máy tính để bàn

7. Nhận diện LPC - Tìm thiết bị LPC trong Device Manager, mục System devices. Tra cứu Device ID và Address của thiết bị, thông thường Address của thiết bị là 0x001F0000

- Vào /System/Library/Extensions, bấm chuột phải vào AppleLPC.kext, chọn Show Package Contents. Vào thư mục Contents, mở file Info.plist - Truy cập vào mục IOKitPersonalities -> AppleLPC -> IONameMatch, bạn sẽ thấy một danh sách các IOName. Chọn IOName có Device ID sát với Device ID của bạn nhất (giống thì càng tốt).

Page 35: Hướng dẫn patch DSDT cho máy tính để bàn

VD: Device ID của tớ là 0x27B8, nên tớ chọn cái IOName gần giống nhất là pci8086,27b9. Như vậy tớ coi Device ID của LPC sẽ là 0x27B9 thay vì 0x27B8. - Trong DSDTEditor, tìm 0x001F0000, ta sẽ tìm được device LPC. Tên đúng của device là LPCB. Một số tên khác có thể gặp là PX40 hoặc SBRG. Nếu khác thì ta Replace thành LPCB. Device (LPCB) { Name (_ADR, 0x001F0000) … } Thêm method _DSM vào cuối Device (LPCB) có nội dung như sau Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "device-id", Buffer (0x04) { 0xB9, 0x27, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } Đổi giá trị trong Buffer của thuộc tính device-id cho phù hợp với Device ID đã chỉnh lại của bạn. LPC của mình tìm được Device ID sát nhất là 0x27B9 thì mình đổi các giá trị trong Buffer là 0xB9, 0x27, 0x00, 0x00 VD:

Trước Sau Device (LPCB) { Name (_ADR, 0x001F0000) … }

Device (LPCB) { Name (_ADR, 0x001F0000) … Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "device-id", Buffer (0x04) { 0xB9, 0x27, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } }

Mình cũng đã thử thêm vào mục IONameMatch cái IOName đúng của mình (pci8086,27b8) và thêm method _DSM với device-id đúng thì vẫn load được kext AppleLPC. Nếu thích thì bạn có thể thử, còn không thì cứ làm theo cách ban đầu. Việc patch DSDT cho LPC sẽ giúp load AppleLPC.kext, từ đó bật C-State cho CPU và quản lí năng lượng của các thiết bị. Kiểm tra kết quả patch bằng cách mở IORegistryExplorer sẽ thấy load được AppleLPC ở LPCB, ngoài ra nếu có SpeedStep thì sẽ nhận được C-State Lưu ý là hình ở dưới thể hiện kết quả khi mình patch AppleLPC.kext và patch DSDT với giá trị đúng (pci8086,27b8, device-id 0xB8, 0x27, 0x00, 0x00)

Page 36: Hướng dẫn patch DSDT cho máy tính để bàn

8. Nhận diện card LAN là built-in (sửa lỗi Time Machine) Đầu tiên mở IORegistryExplorer xem card LAN thuộc vào Device nào. Đối với mình thì tên card LAN tạm thời là ethernet (ADR 0x00000000, do trong DSDT không mô tả) và thuộc vào Device PEX1 (ADR 0x001C0001)

Trong DSDTEditor, tìm đến Device (PEX1) hoặc tìm 0x001C0001 . Nếu chưa có Device con mô tả card LAN thì thêm đoạn code sau vào cuối Device (PEX1). Sau khi thêm đoạn code thì tên card LAN của bạn sẽ là LAN0 Device (LAN0) { Name (_ADR, Zero) Name (_PRW, Package (0x02) { 0x0B, 0x04 }) } Nội dung của patch này là thêm method _DSM bổ sung thuộc tính built-in là 0x01 (nhận card LAN là built-in)

Page 37: Hướng dẫn patch DSDT cho máy tính để bàn

Method (_DSM, 4, NotSerialized) { Store (Package (0x04) { "built-in", Buffer (One) { 0x01 }, "device_type", Buffer (0x09) { "ethernet" } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } VD:

Trước Sau Device (PEX1) { ... Method (_PRT, 0, NotSerialized) { ... } }

Device (PEX1) { ... Method (_PRT, 0, NotSerialized) { ... } Device (LAN0) { Name (_ADR, Zero) Name (_PRW, Package (0x02) { 0x0B, 0x04 }) Method (_DSM, 4, NotSerialized) { Store (Package (0x04) { "built-in", Buffer (One) { 0x01 }, "device_type", Buffer (0x09) { "ethernet" } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } } }

Để kiểm tra patch, ta bỏ thiết lập EthernetBuiltIn của Chameleon, dùng file DSDT.AML đã patch, restart. Vào IORegistryExplorer, kiểm tra bảng thuộc tính của device LAN0 (tùy theo tên device của bạn) xem thiết lập built-in có giá trị 01 chưa. Lưu ý: patch này có thể không hoạt động, vì vậy nên dùng thiết lập EthernetBuiltIn thì tốt hơn. 9. UHCI, EHCI Patch này giúp cho Mac OS nhận diện tất cả các cổng USB (USB 1.1 và USB 2.0), ngoài ra bật tính năng USB Sleep. - Đầu tiên mở Device Manager, tìm tất cả các thiết bị USB trong mục Universal Serial Bus controllers. Tra cứu Device ID, Address và loại của các thiết bị USB + Các thiết bị ghi là Universal Host Controller thì là UHCI (USB 1.1) + Các thiết bị ghi là Enhanced Host Controller thì là EHCI (USB 2.0)

Page 38: Hướng dẫn patch DSDT cho máy tính để bàn

- Mở IORegistryExplorer, tìm tên của các thiết bị USB trong DSDT (thông qua việc đối chiếu Address).

- Lập bảng dữ liệu để hỗ trợ việc chỉnh DSDT. Tên mới của các Device được quy định như sau + Các device thuộc loại UHCI sẽ có tên bắt đầu từ UCH1 -> UCHx (x là số device UHCI) + Các device thuộc loại EHCI sẽ có tên bắt đầu từ ECH1 -> ECHx (x là số device EHCI) Với main của mình thì mình có bảng như sau

Tên cũ Tên mới Device ID Address device-id property USB0 UHC1 0x27C8 0x001D0000 0xC8, 0x27, 0x00, 0x00 USB1 UHC2 0x27C9 0x001D0001 0xC9, 0x27, 0x00, 0x00 USB2 UHC3 0x27CA 0x001D0002 0xCA, 0x27, 0x00, 0x00

Page 39: Hướng dẫn patch DSDT cho máy tính để bàn

USB3 UHC4 0x27CB 0x001D0003 0xCB, 0x27, 0x00, 0x00 USBE EHC1 0x27CC 0x001D0007 0xCC, 0x27, 0x00, 0x00

- Trong DSDTEditor, Replace tên cũ của các thiết bị USB thành tên mới: USB0 thành UHC1, USB1 thành UHC2, USBE thành EHC1, ... - Với mỗi Device UHCx, ta thêm method _DSM vào cuối device có nội dung như sau Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "device-id", Buffer (0x04) { 0xC8, 0x27, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } - Với mỗi Device EHCx, ta thêm method _DSM vào cuối device có nội dung như sau Method (_DSM, 4, NotSerialized) { Store (Package (0x0C) { "AAPL,current-available", 0x05DC, "AAPL,current-extra", 0x04B0, "AAPL,current-in-sleep", 0x09C4, "device-id", Buffer (0x04) { 0xCC, 0x27, 0x00, 0x00 }, "AAPL,clock-id", Buffer (One) { 0x01 }, "device_type", Buffer (0x05) { "EHCI" } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } - Trong các method _DSM đã thêm, đổi thuộc tính device-id theo bảng đã lập. VD:

Trước Sau Device (USB0) { … } Device (USB1) { … } Device (USB2) {

Device (UHC1) { … Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "device-id", Buffer (0x04) {

Page 40: Hướng dẫn patch DSDT cho máy tính để bàn

… } Device (USB3) { … } Device (USBE) { … }

0xC8, 0x27, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } } Device (UHC2) { … Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "device-id", Buffer (0x04) { 0xC9, 0x27, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } } Device (UHC3) { … Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "device-id", Buffer (0x04) { 0xCA, 0x27, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } } Device (UHC4) { … Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "device-id", Buffer (0x04) { 0xCB, 0x27, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } } Device (EHC1) { … Method (_DSM, 4, NotSerialized) { Store (Package (0x0C) { "AAPL,current-available", 0x05DC, "AAPL,current-extra", 0x04B0, "AAPL,current-in-sleep", 0x09C4, "device-id", Buffer (0x04) { 0xCC, 0x27, 0x00, 0x00 }, "AAPL,clock-id", Buffer (One) { 0x01 }, "device_type", Buffer (0x05) { "EHCI" } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } }

Page 41: Hướng dẫn patch DSDT cho máy tính để bàn

Method (\_WAK, 1, NotSerialized) { Store (0xFF, DBG1) If (LEqual (Arg0, 0x03)) { Store (0x8F, SCP) } If (LEqual (Arg0, 0x04)) { If (LEqual (OSFL, 0x00)) { If (LEqual (OSFX, 0x03)) { Store (0x59, SMIP) } Else { Store (0x58, SMIP) } } If (LEqual (OSFL, 0x01)) { Store (0x56, SMIP) } If (LEqual (OSFL, 0x02)) { Store (0x57, SMIP) } If (LEqual (OSFX, 0x03)) { Store (0x59, SMIP) } } If (LEqual (Arg0, 0x01)) {} If (OSFL) { Notify (\_SB.PWRB, 0x02) } Else { If (LEqual (RTCW, 0x00)) { Notify (\_SB.PWRB, 0x02) } } Notify (\_SB.PCI0.USB0, 0x00) Notify (\_SB.PCI0.USB1, 0x00) Notify (\_SB.PCI0.USB2, 0x00) Notify (\_SB.PCI0.USB3, 0x00) Return (Package (0x02) { Zero, Zero }) } ...

Method (\_WAK, 1, NotSerialized) { Store (0xFF, DBG1) If (LEqual (Arg0, 0x03)) { Store (0x8F, SCP) } If (LEqual (Arg0, 0x04)) { If (LEqual (OSFL, 0x00)) { If (LEqual (OSFX, 0x03)) { Store (0x59, SMIP) } Else { Store (0x58, SMIP) } } If (LEqual (OSFL, 0x01)) { Store (0x56, SMIP) } If (LEqual (OSFL, 0x02)) { Store (0x57, SMIP) } If (LEqual (OSFX, 0x03)) { Store (0x59, SMIP) } } If (LEqual (Arg0, 0x01)) {} If (OSFL) { Notify (\_SB.PWRB, 0x02) } Else { If (LEqual (RTCW, 0x00)) { Notify (\_SB.PWRB, 0x02) } } Notify (\_SB.PCI0.UHC1, 0x00) Notify (\_SB.PCI0.UHC2, 0x00) Notify (\_SB.PCI0.UHC3, 0x00) Notify (\_SB.PCI0.UHC4, 0x00) Return (Package (0x02) { Zero, Zero }) } ...

Công đoạn cuối cùng chỉ còn là tắt USBBusFix trong Chameleon. Sau khi áp dụng DSDT đã patch và khởi động lại, vào IORegistryExplorer, kiểm tra lại các Device UHCx và EHCx xem các thuộc tính đã đúng chưa.

Page 42: Hướng dẫn patch DSDT cho máy tính để bàn

Như vậy sau khi patch UHCI/EHCI, các cổng USB sẽ nhận hết, không cần Rollback IOUSBFamily về phiên bản cũ hơn hay bật USBBusFix trong Chameleon nữa. Patch này bật chức năng USB Sleep, là một phần của quá trình patch sleep. 10. SATA Patch SATA gồm 2 công đoạn chính: * Nhận diện device SATA để fix lỗi biểu tượng màu vàng cam. Lỗi này là do không nhận diện được SATA nên ổ cứng bị nhận nhầm thành External (biểu tượng màu cam của ổ đĩa gắn ngoài). Chip của mình là ICH7 nên không có SATA AHCI, với các main có SATA AHCI thì mình không rõ lắm, cách fix có thể sẽ khác. - Vào Device Manager, tìm Device SATA (của mình ở trong mục IDE ATA/ATAPI Controllers). Tra cứu Device ID và Address. Với main của mình thì Device ID là 0x27C0 và Address là 0x001F0002

- Trong DSDTEditor, tìm 0x001F0002 sẽ thấy Device SATA. Nếu tên device mà khác SATA (chẳng hạn với main của mình là IDE1) thì replace thành SATA.

Page 43: Hướng dẫn patch DSDT cho máy tính để bàn

- Thêm method _DSM để nhận diện Device SATA có nội dung như sau Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "device-id", Buffer (0x04) { 0xC0, 0x27, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } Đổi giá trị trong Buffer của thuộc tính device-id cho phù hợp với Device ID của bạn. * Đổi tên các Device con cho phù hợp. - Nếu trong device SATA của bạn có các Device con như PRIM, SECD thì đổi tên chúng về tên đúng của Mac OS. + replace PRIM thành PRT0 + replace SECD thành PRT1 - Ngoài ra nếu DSDT của bạn ngoài Device IDE1 ban đầu còn có Device IDE2 thì có thể xóa Device IDE2 đi vì chúng chỉ có tác dụng khi chế độ SATA trong BIOS là IDE. VD:

Trước Sau Device (SATA) { Name (_ADR, 0x001F0002) OperationRegion (PCI, PCI_Config, 0x40, 0x20) Field (PCI, DWordAcc, NoLock, Preserve) { ITM0, 16, ITM1, 16, SIT0, 4, SIT1, 4, Offset (0x08), UDC0, 2, UDC1, 2, Offset (0x0A), UDT0, 8, UDT1, 8, Offset (0x14), ICF0, 2, ICF1, 2, , 6, WPPE, 1, , 1, FAS0, 2, FAS1, 2 } Device (PRIM) { ... } Device (SECD) { ... } }

Device (SATA) { Name (_ADR, 0x001F0002) OperationRegion (PCI, PCI_Config, 0x40, 0x20) Field (PCI, DWordAcc, NoLock, Preserve) { ITM0, 16, ITM1, 16, SIT0, 4, SIT1, 4, Offset (0x08), UDC0, 2, UDC1, 2, Offset (0x0A), UDT0, 8, UDT1, 8, Offset (0x14), ICF0, 2, ICF1, 2, , 6, WPPE, 1, , 1, FAS0, 2, FAS1, 2 } Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "device-id", Buffer (0x04) { 0xC0, 0x27, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } Device (PRT0) { ... } Device (PRT1) { ... } }

Page 44: Hướng dẫn patch DSDT cho máy tính để bàn

Như vậy sau patch này, các ổ cứng sẽ được nhận diện là gắn trong và biểu tượng trở về như cũ, không cần đến IOACHIBlockStorage.kext nữa. Ngoài ra tên của các device con được đổi lại cho phù hợp rồi nên không cần JMicron36xSATA.kext nữa.

11. Audio * Một giải pháp tổng quát cho mọi loại chip Audio là VoodooHDA, tuy vậy để VoodooHDA hoạt động tốt thì bạn phải xóa kext AppleHDA. Công đoạn đầu tiên của patch Audio sẽ giúp bạn không cần phải xóa kext AppleHDA nữa. - Dùng IORegistryExplorer tìm xem device Audio của bạn có tên là gì. Với main của mình thì tên là AZAL. - Trong DSDTEditor, replace AZAL về tên đúng là HDEF, thế là xong. * Với chip âm thanh Realtek có codec thuộc nhóm sau: ALC888, ALC887/888b, ALC889, ALC885/889a, ALC892 ta hoàn toàn có thể dùng AppleHDA.kext phối hợp với patch DSDT thay vì dùng VoodooHDA.kext (ALC662 cũng làm được nhưng phức tạp hơn một chút). Công đoạn thứ 2 (tùy chọn) của patch Audio như sau - Xóa các kext Audio như LegacyHDA.kext, VoodooHDA.kext - Tạo bản backup cho AppleHDA.kext - Mở MultiBeast, cài ALC8xxHDA (kext tổng hợp thông tin của các loại codec ALC8xx) + AppleHDA Rollback (khôi phục AppleHDA về bản 10.6.2) + HDAEnabler tương ứng với codec của bạn - Restart và kiểm tra xem có tín hiệu âm thanh chưa. Nếu chưa thì kiểm tra và điều chỉnh Output - Input trong System Preferences -> Sound cho phù hợp (Thiết lập Audio Output là Internal Speakers, Audio Input là Microphone hoặc Line In) - Vào IORegistryExplorer, tìm HDEF và lấy nội dung của các thuộc tính sau

Thuộc tính Giá trị (đối với audio của mình) codec-id 0x62, 0x06, 0xEC, 0x10 layout-id 0x96, 0x02, 0x00, 0x00 device-type "ALC662" - Trong DSDTEditor, thêm method _DSM vào cuối Device HDEF để nhận diện audio có nội dung như sau

Page 45: Hướng dẫn patch DSDT cho máy tính để bàn

Method (_DSM, 4, NotSerialized) { Store (Package (0x08) { "codec-id", Buffer (0x04) { 0x62, 0x06, 0xEC, 0x10 }, "layout-id", Buffer (0x04) { 0x96, 0x02, 0x00, 0x00 }, "device-type", Buffer (0x11) { "ALC662" }, "PinConfigurations", Buffer (Zero) {} }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } Chỉnh lại giá trị của các thuộc tính codec-id, layout-id và device-type cho phù hợp với audio của bạn. Lưu ý ở thuộc tính device-type phải thiết lập kích thước Buffer cho đúng (= độ dài xâu + 1). Mình xem các patch DSDT cho ALC662 đều để kích thước buffer của device-type là 0x11 (thừa kích thước), còn với các patch DSDT cho ALC8xx thì kích thước Buffer luôn đúng. Tốt nhất cứ để đúng là OK. - Xóa HDAEnabler.kext, vẫn giữ ALC8xxHDA.kext rồi dùng DSDT đã patch Audio. Kể từ bây giờ audio của bạn sẽ được load bằng AppleHDA.kext và chạy ngon lành. Nếu thích thì bạn có thể cài lại bản backup AppleHDA.kext lúc trước xem có hoạt động không, nếu không thì lại dùng MultiBeast để Rollback AppleHDA. Kết hợp 2 patch trên, ta có patch Audio như sau

Trước Sau Device (AZAL) { Name (_ADR, 0x001B0000) Method (_PRW, 0, NotSerialized) { Return (Package (0x02) { 0x05, 0x05 }) } }

Device (HDEF) { Name (_ADR, 0x001B0000) Method (_PRW, 0, NotSerialized) { Return (Package (0x02) { 0x05, 0x05 }) } Method (_DSM, 4, NotSerialized) { Store (Package (0x08) { "codec-id", Buffer (0x04) { 0x62, 0x06, 0xEC, 0x10 }, "layout-id", Buffer (0x04) { 0x96, 0x02, 0x00, 0x00 }, "device-type", Buffer (0x11) { "ALC662" }, "PinConfigurations", Buffer (Zero) {} }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } }

Page 46: Hướng dẫn patch DSDT cho máy tính để bàn

* Với ALC662, mình làm như sau - Lên kexts.com, tải gói ALC662.zip cho Mac OS 10.6.6 về, trong đó có 3 file là ALC662.kext (kext chứa thông tin về codec ALC662), HDAEnabler (Enabler cho AppleHDA) và AppleHDA (cái này đã patch binary để hỗ trợ codec ALC662) - Cài cả 3 kext (ALC662.kext và HDAEnabler mình để ở /Extra/Extensions, AppleHDA.kext thì chép đè vào /System/Library/Extensions). Restart, tinh chỉnh thiết lập trong System Preferences -> Sound - Patch DSDT như ở trên - Xóa HDAEnabler.kext, vẫn giữ ALC662.kext. Thế là xong, audio chạy ngon lành, tất cả các cổng đều nhận, âm thanh to hơn (trước kia dùng VoodooHDA thì âm thanh hơi nhỏ).

Page 47: Hướng dẫn patch DSDT cho máy tính để bàn

12. Nhận diện SMBUS Patch SMBUS gồm 2 phần * Thêm Device BUS0 - Trong DSDTEditor, thêm đoạn code của Device (BUS0) vào trước Device (HDEF) như sau Device (BUS0) { Name (_CID, "smbus") Name (_ADR, 0x00) Device (DVL0) { Name (_ADR, 0x57) Name (_CID, "diagsvault") Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "address", 0x57 }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } } } * Patch SBUS - Tìm thiết bị SMBus Controller trong Device Manager, mục System devices. Tra cứu Device ID, Vendor ID và Address của thiết bị, với main của mình thì Address của thiết bị là 0x001F0003, Device ID là 0x27DA và Vendor ID là 0x8086 (Intel)

Page 48: Hướng dẫn patch DSDT cho máy tính để bàn

- Trong DSDTEditor, tìm 0x001F0003, ta sẽ tìm được device SMBUS. Tên đúng của device là SBUS. Nếu khác (chẳng hạn như PX43) thì ta Replace thành SBUS Thêm method _DSM vào cuối Device (SBUS) có nội dung như sau Method (_DSM, 4, NotSerialized) { Store (Package (0x04) { "name", "pci8086,27da", "device-id", Buffer (0x04) { 0xDA, 0x27, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } Đổi giá trị trong Buffer của thuộc tính device-id và giá trị của thuộc tính name cho phù hợp với Device ID và Vendor ID của bạn. Kết hợp 2 công đoạn ta có patch nhận diện SMBUS như sau:

Trước Sau Device (PX43) { Name (_ADR, 0x001F0003) ... }

Device (BUS0) { Name (_CID, "smbus") Name (_ADR, 0x00) Device (DVL0) { Name (_ADR, 0x57) Name (_CID, "diagsvault") Method (_DSM, 4, NotSerialized) { Store (Package (0x02) { "address", 0x57 }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } } } Device (HDEF) { ... } ... Device (SBUS) { Name (_ADR, 0x001F0003) ... Method (_DSM, 4, NotSerialized) { Store (Package (0x04) { "name", "pci8086,27da", "device-id", Buffer (0x04) { 0xDA, 0x27, 0x00, 0x00 } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } }

Kiểm tra kết quả sau khi patch bằng cách mở IORegistryExplorer, tìm 2 mục BUS0 và SBUS và kiểm tra là xong.

Page 49: Hướng dẫn patch DSDT cho máy tính để bàn

13. Shutdown Fix shutdown này áp dụng với main Gigabyte, các dòng main khác thì tớ không rõ lắm. Lưu ý rằng fix này chỉ fix được shutdown, không fix được restart, vì thế phải cần RestartFix trong Chameleon 2.0 RC5. - Thêm đoạn code sau vào cuối DSDT, trong DefinitionBlock OperationRegion (PMRS, SystemIO, 0x0430, One) Field (PMRS, ByteAcc, NoLock, Preserve) { , 4, SLPE, 1 } - Sửa lại method _PTS bằng cách thêm vào 2 dòng tô đậm ở dưới If (LEqual (Arg0, 0x05)) { Store (One, \_SB.PCI0.LPCB.AG3E) Store (Zero, SLPE) Sleep (0x10) } VD:

Trước Sau DefinitionBlock ("dsdt.aml", "DSDT", 1, "GBT ", "GBTUACPI", 0x00001000) { … Method (\_PTS, 1, NotSerialized) { Or (Arg0, 0xF0, Local0) Store (Local0, DBG1) OSTP () If (LEqual (Arg0, 0x01)) {} If (LEqual (Arg0, 0x03)) {} If (LEqual (Arg0, 0x05)) { Store (One, \_SB.PCI0.LPCB.AG3E) } Else { Store (Zero, \_SB.PCI0.LPCB.AG3E) } If (LEqual (Arg0, 0x04)) { If (LNot (PICF)) { Sleep (0x64) } } } ... }

DefinitionBlock ("dsdt.aml", "DSDT", 1, "GBT ", "GBTUACPI", 0x00001000) { … Method (\_PTS, 1, NotSerialized) { Or (Arg0, 0xF0, Local0) Store (Local0, DBG1) OSTP () If (LEqual (Arg0, 0x01)) {} If (LEqual (Arg0, 0x03)) {} If (LEqual (Arg0, 0x05)) { Store (One, \_SB.PCI0.LPCB.AG3E) Store (Zero, SLPE) Sleep (0x10) } Else { Store (Zero, \_SB.PCI0.LPCB.AG3E) } If (LEqual (Arg0, 0x04)) { If (LNot (PICF)) { Sleep (0x64) } } } ... OperationRegion (PMRS, SystemIO, 0x0430, One) Field (PMRS, ByteAcc, NoLock, Preserve) { , 4, SLPE, 1 } }

Như vậy sau patch này bạn có thể bỏ kext EVOReboot được rồi đó.

Page 50: Hướng dẫn patch DSDT cho máy tính để bàn

14. Speedstep Patch này khá phức tạp nên mình không nói ở đây. Ta có thể làm cách đơn giản hơn là bật các option sau trong Chameleon 2.0 RC5 (phải là RC5 mới có) - GeneratePStates - GenerateCStates - DropSSDT Cuối cùng chỉ việc patch nhận diện LPC, cộng thêm một số patch quan trong như HPET (để load AppleIntelCPUPowerManagement) là xong. Để kiểm tra patch ta kiểm tra 2 mục sau * Kiểm tra các thông số trong ACPI_SMC_PlatformPlugin + CPUPLimit + CSTInfo + PerformanceStateArray

Để SpeedStep hiệu quả hơn, bạn cần có một file SMBIOS.plist chứa tên máy Mac có cấu hình gần giống với cấu hình của bạn. Xét với cấu hình của mình thì gần giống với 1 con Macmini3,1 nên mình cần có file SMBIOS.plist chứa thông tin của một con Macmini3,1. Nhờ có SMBIOS mà Mac điều khiển CPU hiệu quả hơn, dẫn đến nhiệt độ CPU giảm đi. 15. Sleep Nói là patch nhưng thực ra chỉ là việc thực hiện các patch trên, trong đó các patch quan trọng là UHCI/EHCI, HID/CID, PCIB, LPCB, WAK, HPET và SpeedStep. Giờ bạn có thể thử chức năng Sleep được rồi đó. Nếu Sleep vẫn không hoạt động thì kiểm tra lại các patch xem. Có lần mình không sleep được là do patch LPC (patch thì đúng nhưng sleep thì không được). Bỏ patch đi thì sleep ngon lành. Sau này phải cầu viện đến DSDT Auto Patcher phiên bản mới nhất thì mới xong. Theo mình thì lỗi không phải là do patch LPC mà do method _PTS có lỗi nào đó nên mới vậy. Các bạn cũng nên để ý đến method này (PTS là viết tắt của Prepare to Sleep). 16. Patch đồ họa nVidia Cái này bạn nào thích thì nghịch, chứ thực tế chỉ cần dùng ROM nVidia là ngon rồi.

Page 51: Hướng dẫn patch DSDT cho máy tính để bàn

Việc patch đồ họa nVidia thực chất là hard-code DSDT, tức là bổ sung thông tin về các phần cứng không gắn trên Mainboard vào DSDT, từ đó nhận diện được các phần cứng đó. Cái này thích hợp khi muốn nhận diện một số card rời gắn vào các khe PCI hoặc ExpressCard. Nội dung của các patch hard-code chủ yếu tập trung vào method _DSM để nhận diện phần cứng, nhưng tùy theo loại card rời mà các thuộc tính trong _DSM sẽ khác nhau, vì thế trước khi patch phải tìm hiểu kĩ càng và lấy thông tin cụ thể trong IORegistryExplorer. Nói thế là đủ, giờ thì đi vào việc chính. Mình sẽ lấy con card GeForce 9400 GT 512 MB của mình làm ví dụ. * Bước 1: Nhận diện card Không thiếu gì cách để nhận diện card, từ kext ngoài cho đến EFI String, nhưng theo mình cách tốt nhất là dùng chức năng UseNVidiaROM + GraphicsEnabler của Chameleon 2.0 RC5 cho phép nạp ROM card đồ họa nVidia. - Dùng GPUZ lấy thông tin về Device ID và Vendor ID rồi trích xuất ROM. Lưu file ROM với tên là <Vendor ID>_<Device ID>.ROM . Với card của mình có Vendor ID là 0x10DE, Device ID là 0x0641 thì tên file sẽ là 10DE_0641.ROM

- Copy file ROM vào thư mục /Extra

- Bật thiết lập UseNvidiaROM và GraphicsEnabler trong Chameleon. - Xóa các kext đồ họa như NVEnabler, Natit, … - Restart, vào System Profiler để kiểm tra.

Page 52: Hướng dẫn patch DSDT cho máy tính để bàn

Có thể tình trạng sau sẽ xảy ra: khi bạn boot vào Mac OS thì cuối cùng sẽ chỉ thấy màn hình xanh lè mặc dù âm thanh và mọi thứ của Mac OS vẫn hoạt động. Đó là do lỗi nhận nhầm PCI Root UID (mặc định là 0, nhưng thực tế phải là 1). Fix lỗi này bằng cách bật option PCIRoot = 1 trong Chameleon hoặc mở file com.apple.boot.plist, thêm các dòng sau <key>PciRoot</key> <string>1</string> Lưu ý là các kext như NVEnabler có thể tự nhận diện đúng PCI Root, khi đó không cần fix lỗi này. * Bước 2: Patch DSDT - Vào IORegistryExplorer, tìm thiết bị tương ứng với card nVidia, lấy các thông số sau

Thông số Ý nghĩa Giá trị (đối với card của mình) VRAM,totalsize Dung lượng RAM của card đồ họa

Bạn hoàn toàn có thể tự tính giá trị cho thuộc tính này bằng cách lấy dung lượng RAM chia cho 16 rồi đổi ra hệ hex VD: Dung lượng RAM card của mình là 512 MB 512 / 16 = 32 = 0x20, như vậy VRAM,totalsize là 0x00, 0x00, 0x00, 0x20

0x00, 0x00, 0x00, 0x20

Page 53: Hướng dẫn patch DSDT cho máy tính để bàn

NVCAP Thông số hoạt động của card nVidia (gồm một mảng 20 số nguyên 1 byte). Nên nhóm lại thành 3 hàng 8 - 8 - 4

0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00

- Trong DSDT Editor, thêm device PEGP chứa device GFX0 vào đầu device PCI0. Device GFX0 chứa method _DSM nhận diện card đồ họa như sau Device (PEGP) { Name (_ADR, 0x00010000) Device (GFX0) { Name (_ADR, Zero) Name (_SUN, One) Method (_DSM, 4, NotSerialized) { Store (Package (0x1A) { "@0,compatible", Buffer (0x0B) { "NVDA,NVMac" }, "@0,device_type", Buffer (0x08) { "display" }, "@0,display_cfg", Buffer (0x08) { 0x03, 0x01, 0x00, 0x00 }, "@0,name", Buffer (0x0F) { "NVDA,Display-A" }, "@1,compatible", Buffer (0x0B) { "NVDA,NVMac" }, "@1,device_type", Buffer (0x08) { "display" }, "@1,display_cfg", Buffer (0x08) { 0xFF, 0xFF, 0x00, 0x01 }, "@1,name", Buffer (0x0F) { "NVDA,Display-B" }, "NVCAP", Buffer (0x14) { /* 0000 */ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, /* 0008 */ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, /* 0010 */ 0x00, 0x00, 0x00, 0x00 }, "VRAM,totalsize", Buffer (0x04) { 0x00, 0x00, 0x00, 0x20 }, "device_type", Buffer (0x0D) { "NVDA,GeForce" }, "model", Buffer (0x17)

Page 54: Hướng dẫn patch DSDT cho máy tính để bàn

{ "nVidia GeForce 9400 GT" }, "rom-revision", Buffer (0x25) { "nVidia GeForce 9400 GT OpenGL Engine" } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } } } Sửa giá trị của NVCAP và VRAM,totalsize cho phù hợp với card của bạn. Với 2 thuộc tính model và rom-revision thì bạn có thể để tùy ý, nhưng nên để đúng với tên card của bạn. Chẳng hạn như card của mình thì có thể để name là "nVidia GeForce 9400 GT" hoặc "GeForce 9400 GT", còn rom-revision có thể để là "62.94.54.00.00" (xem trong GPU-Z) hoặc "nVidia GeForce 9400 GT OpenGL Engine". Nhớ chỉnh lại kích thước của Buffer chứa 2 thuộc tính name và rom-revision cho phù hợp với dữ liệu của bạn. - Nếu bạn bị lỗi PCI Root UID thì bạn có thể fix bằng thiết lập Chameleon ở trên, hoặc thêm đoạn code sau vào đầu Device (PCI0) nếu chưa có. Device (PCI0) { Name (_HID, EisaId ("PNP0A03")) Name (_ADR, Zero) Name (_UID, One) Name (_BBN, Zero) Method (_S3D, 0, NotSerialized) { If (LEqual (OSFL, 0x02)) { Return (0x02) } Else { Return (0x03) } } Như vậy toàn bộ đoạn code cần chỉnh sẽ là: Device (PCI0) { Name (_HID, EisaId ("PNP0A03")) Name (_ADR, 0x00) Name (_UID, 0x01) Name (_BBN, 0x00) Method (_S3D, 0, NotSerialized) { If (LEqual (OSFL, 0x02)) { Return (0x02) } Else { Return (0x03) } } Device (PEGP) { Name (_ADR, 0x00010000) Device (GFX0) { Name (_ADR, Zero)

Page 55: Hướng dẫn patch DSDT cho máy tính để bàn

Name (_SUN, One) Method (_DSM, 4, NotSerialized) { Store (Package (0x1A) { "@0,compatible", Buffer (0x0B) { "NVDA,NVMac" }, "@0,device_type", Buffer (0x08) { "display" }, "@0,display_cfg", Buffer (0x08) { 0x03, 0x01, 0x00, 0x00 }, "@0,name", Buffer (0x0F) { "NVDA,Display-A" }, "@1,compatible", Buffer (0x0B) { "NVDA,NVMac" }, "@1,device_type", Buffer (0x08) { "display" }, "@1,display_cfg", Buffer (0x08) { 0xFF, 0xFF, 0x00, 0x01 }, "@1,name", Buffer (0x0F) { "NVDA,Display-B" }, "NVCAP", Buffer (0x14) { /* 0000 */ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, /* 0008 */ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, /* 0010 */ 0x00, 0x00, 0x00, 0x00 }, "VRAM,totalsize", Buffer (0x04) { 0x00, 0x00, 0x00, 0x20 }, "device_type", Buffer (0x0D) { "NVDA,GeForce" }, "model", Buffer (0x17) { "nVidia GeForce 9400 GT" }, "rom-revision", Buffer (0x25) { "nVidia GeForce 9400 GT OpenGL Engine" } }, Local0) DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0)) Return (Local0) } } } ... }

Page 56: Hướng dẫn patch DSDT cho máy tính để bàn

- Cuối cùng bạn chỉ việc tắt UseNVidiaROM, giữ GraphicsEnabler và dùng file DSDT đã patch. Restart và kiểm tra lại System Profiler. Mở IORegistryExplorer, tìm Device GFX0 để kiểm tra các thuộc tính.

Page 57: Hướng dẫn patch DSDT cho máy tính để bàn

VII. Hướng dẫn thiết lập Chameleon và sử dụng DSDT đã patch Đầu tiên bạn phải có Chameleon 2.0 RC5 đã cài. Tiếp theo đó để dễ thiết lập, bạn nên tải Chameleon.prefpane và cài vào System Preferences Mở System Preferences -> Chameleon, bấm vào ổ kháo và nhập password để unlock. Một số mục mà bạn cần lưu ý 1. Boot flags: Chứa các boot flag (tham số boot)

+ Verbose (-v): Hiện log trong khi boot + Safe boot (-x): Boot ở chế độ an toàn, chỉ load các thành phần cần thiết + Ignore Boot Config (-f): Bỏ qua boot config (cái này có cả việc load lại tất cả các kext) + Single User (-s): Boot vào chế độ dòng lệnh + Time Out: Thời gian chờ boot + Quiet Boot: Tự động boot không cần chờ + Instant menu: Bắt Chameleon hiện menu boot để chọn thiết bị boot + Boot Theme: Theme của Chameleon + UseGUI: Tắt bật giao diện đồ họa của Chameleon + Wait: Chờ một phím bất kì trước khi load kernel 2. Pheripherals: Các thiết bị ngoại vi

Page 58: Hướng dẫn patch DSDT cho máy tính để bàn

+ Graphics mode: Thiết lập chế độ đồ họa. Chế độ đồ họa có định dạng là <CHIỀU RỘNG>x<CHIỀU CAO>x<ĐỘ SÂU MÀU>@<TẦN SỐ LÀM TƯƠI> VD: 1366x768x32 hoặc 1280x800x32@60 + Graphics Enabler: Bật Enabler cho card đồ họa nVidia của Chameleon + Use ATI ROM: nạp ROM của card ATI, địa chỉ của file ROM phải là /Extra/<Vendor ID>_<Device ID>.ROM + Use nVidia ROM: nạp ROM của card nVidia, địa chỉ của file ROM phải là /Extra/<Vendor ID>_<Device ID>.ROM + VBIOS: Nạp Video BIOS của card nVidia trong file ROM, địa chỉ của file ROM chứa VBIOS cần nạp phải là /Extra/<Vendor ID><Device ID>.ROM + Legacy Logo: Dùng Logo boot chuẩn của Apple (cái này mình không thích vì nó xấu) + Boot banner: Hiện boot banner (cái này mình không rõ) + USBBusFix: Fix UHCI/EHCI + EHCI Acquire: Fix EHCI + UCHI Reset: Fix UHCI + EthernetBuiltIn: nhận card LAN là built-in + PCIRoot: Thiết lập PCI Root UID (0 hoặc 1) + Force HPET: ép bật HPET trong BIOS kể cả khi BIOS không cung cấp thiết lập cho HPET. Cái này chỉ dùng khi đã patch DSDT cho HPET 3. EFI Inject: Nạp các EFI String cho các thiết bị. Cái này chủ yếu dùng để nhận card đồ họa

4. BIOS: Dùng DSDT đã patch và SMBIOS.plist . Cái này quan trọng đây :)

Page 59: Hướng dẫn patch DSDT cho máy tính để bàn

+ DSDT: nạp file DSDT.AML khi boot. Nên để file DSDT.AML trong /Extra và thiết lập cho option DSDT là /Extra/dsdt.aml + SMBIOS: nạp file SMBIOS.plist khi boot. Nên để file SMBIOS.plist trong /Extra và thiết lập cho option DSDT là /Extra/SMBIOS.plist + Drop (SSDT): Bỏ qua bảng SSDT khi relocate ACPI (cái này mình không rõ, cần thiết khi bật P-State và C-State thì phải) 5. Advanced: Các thiết lập nâng cao

Kernel: Chọn kernel khi boot arch: Thiết lập boot 32 bit (i386) hay 64 bit (x86_64) cpus: Giới hạn số nhân CPU busratio: Thiết lập bus ratio cho CPU system-type: Thiết lập loại máy tính: 1 (Máy để bàn), 2 (Laptop) RestartFix: Sửa lỗi Restart GeneratePStates và GenerateCStates: nhận dạng PState và CState cho CPU Intel VIII. Hướng dẫn sử dụng DSDT Editor cơ bản 1. Giao diện chính Giao diện chính của phần mềm khá đơn giản, gồm các menu và nút sau Menu Menu con Chức năng

File

New Tạo file DSL mới Open Mở file DSL hoặc AML có trong máy Save DSL Lưu file DSL Save DSL As Lưu file DSL ở một vị trí khác Extract DSDT Trích xuất DSDT của bo mạch chủ thành file DSL

Patch New Tạo một patch tự động Open Mở patch có sẵn. Chức năng này ít khi hoạt động tốt nên mình không giới thiệu.

IASL Compile Biên dịch file DSL thành file AML Save AML As Chọn vị trí lưu file AML

Options Background color Thiết lập phông nền cho trình soạn thảo

Page 60: Hướng dẫn patch DSDT cho máy tính để bàn

Nút (nhóm nút) Chức năng Cut / Copy / Paste Cắt / Sao chép / Dán văn bản Select All Chọn toàn bộ văn bản Undo / Redo Hủy / Thực hiện lại các thao tác trên văn bản Find / Find next Tìm từ / Tiếp tục quá trình tìm kiếm Goto Line Đi đến một dòng nào đó trong văn bản Jump to Pair Khi chọn một ngoặc nhọn và bấm nút, nó sẽ giúp bạn đi tới ngoặc nhọn tương ứng Complete word Hoàn thành một cú pháp đang nhập (VD: Scop -> Scope) Toggle comment Chú thích đoạn văn bản đang chọn Update tree Sau khi thay đổi file DSL, cần bấm nút này để quét lại cấu trúc cây DSDT 2. Hộp thoại Find / Replace

- Nhập từ cần tìm vào hộp Find, bấm Next để tìm. Khi muốn thay thế bấm Replace. Cứ như vậy cho đến khi replace hết (từ cần tìm không còn xuất hiện nữa) thì quá trình tìm kiếm / thay thế sẽ tự dừng lại. - Bạn có thể thay thế tất cả bằng Replace All, lưu ý là việc này phải cẩn thận vì bạn không biết những vị trí nào sẽ bị thay thế. 3. Hộp thoại Compile

Page 61: Hướng dẫn patch DSDT cho máy tính để bàn

Cột Ý nghĩa Line Dòng gặp lỗi / cảnh báo Type Lỗi / cảnh báo Message Thông báo của Lỗi / cảnh báo Một số lỗi có thể fix tự động bằng cách bấm nút Fix Error. Lưu ý là các cảnh báo sẽ không được fix, vì vậy bạn nên fix thủ công để đảm bảo an toàn.

Page 62: Hướng dẫn patch DSDT cho máy tính để bàn

IX. Kết luận Trên đây là một số patch DSDT dành cho máy tính để bàn. Với Laptop thì mình sẽ phải nghiên cứu thêm vì mình chưa có điều kiện nghịch và DSDT của Laptop có một số device khác khó xử lí hơn. Một hệ thống HACKINTOSH dùng kext ngoài đã là đủ để chạy ngon. Nhưng nếu bạn muốn giảm sự phụ thuộc vào kext ngoài, làm cho Mac OS chạy ngon hơn nữa thì patch DSDT là việc cần thiết. Mặc dù patch DSDT cũng như việc lập trình đều là những vấn đề khó đối với những người sử dụng nghiệp dư, nhưng nếu bạn đam mê tìm tòi và có khả năng suy luận tốt thì patch DSDT sẽ không khó như bạn tưởng. Bản hướng dẫn này đã cụ thể hóa các patch DSDT thường gặp và có thể áp dụng cho mọi loại phần cứng thông thường. Các công đoạn được viết chi tiết, đảm bảo cho những bạn có trình độ tin học, tiếng Anh ở mức trung bình và có một chút kiến thức về phần cứng có thể hiểu được. Chỉ cần có đủ can đảm và thực hiện đúng theo hướng dẫn này thì việc patch DSDT sẽ dễ dàng hơn bao giờ hết. Tất nhiên không phải DSDT nào cũng giống nhau và có thể bạn cần chút khả năng suy luận để ứng biến cho phù hợp với DSDT của mình. Mặc dù bản hướng dẫn có thể còn sai sót, song theo mình đánh giá thì nó là một công cụ đắc lực trong việc patch DSDT . Hi vọng rằng sau khi đọc bản hướng dẫn này, các bạn sẽ bắt tay vào việc patch DSDT và đạt được nhiều thành công, làm cho Mac OS hoạt động ổn định mượt mà hơn. Mong các bạn góp ý để cho bản hướng dẫn này được hoàn thiện.

Hạ Long, ngày 7 tháng 2 năm 2011

Nguyên (aka CHILINHHACKER)