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: và 26oC Chameleon 2.0 RC5, b
Trang 1I 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:
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
Time Machine Đã fix lỗi, không cần EthernetBuiltIn trong Chameleon patch DSDT
AppleHDA patch + ALC662.kext
Trang 2RTC OK, không cần LegacyRTC.kext, không CMOS Reset patch DSDT
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
Trang 3II 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
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
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
Trang 4Time 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
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)
Trang 5III 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
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
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
Trang 6Increment (Addend) Tăng giá trị của Addend lên 1 đơn vị
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
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
Trang 7Mid (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
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)
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
Trang 8SizeOf (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)
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):
_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
_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
Trang 9_GPE General Purpose Events
_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
Trang 10_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
_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, )
_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)
Trang 11{} đó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 //
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
Trang 12VD:
0x001F0002 = 0000 0000 0001 1111 0000 0000 0000 0010 2: giá trị hex thể hiện một địa chỉ 32 bit (8 kí tự
x 4 bit)
0x8086 = 1000 0000 1000 0110 2 : 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
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 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
Trang 13e 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
Trang 15IV 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
Trang 16- 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
Trang 17- 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:
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 để ý
Trang 18VD : 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
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
"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
Trang 19* 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:
Trang 20* 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:
Trang 21Tê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)
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:
[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)
Trang 22Ví 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)
Trang 23V 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ề
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
Trang 24Store (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 })
}
Trang 254 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
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
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)
} }
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
If (LEqual (\ECFL, Zero)) {
Return (0x0F) }
Else {
Store ("_SB.CMB0._BTP", 0x0F)
/*Sua lai gia tri tra ve*/ }
}
Trang 26Method (EVNT, 1, NotSerialized)
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ự
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ố)
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ố)
Trang 27VI 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
… Scope (_SB) {
}
Method (DTGP, 5, NotSerialized) {
… }
}
Trang 28Name (_HID, EisaId ("PNP0C0C"))
Method (_STA, 0, NotSerialized)
Name (_CID, EisaId ("PNP0C0C"))
Method (_STA, 0, NotSerialized) {
Return (0x0B) }
* 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ó
})
- 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)
Trang 29VD :
Device (HPET)
{
Name (_HID, EisaId ("PNP0103"))
Name (ATT3, ResourceTemplate ()
IRQNoFlags () {0}
IRQNoFlags () {8}
Memory32Fixed (ReadWrite,
0xFED00000,// Address Base 0x00000400,// Address Length )
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
Trang 300x02, // Length
) }) Name (ATT1, ResourceTemplate () {
IO (Decode16, 0x0070, // Range Minimum 0x0070, // Range Maximum 0x00, // Alignment 0x04, // Length )
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
Trang 315 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
0x00A0, // Range Minimum
0x00A0, // Range Maximum
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 )
}) Name (ATT6, ResourceTemplate () {
IO (Decode16, 0x0040, // Range Minimum 0x0040, // Range Maximum 0x00, // Alignment 0x04, // Length )
}) Method (_CRS, 0, NotSerialized) {
Return (ATT6)
} }
}