Tải bản đầy đủ (.pdf) (62 trang)

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

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (9.22 MB, 62 trang )




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 ở 37
o
C
và 26
o
C
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
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.










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ủ.
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)







































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
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.
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
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
_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
_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)
{
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:

100110
2
= 38

10

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: 00010010
2
= 18
10
là số nguyên 8 bit. Kích thướ c của số nguyên 8 bit là 256 (từ giá trị 00000000
2
= 0
10

đến giá trị 11111111
2
= 255
10
)

* 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 = C0
16
= 192
10
= 1100 0000

2
0x08 = 8
16
= 8
10
= 1000
2
0x0A = A
16
= 10
10
= 1010
2

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.

VD:
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

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.

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)
{
"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 (1A
16
= 26 = 13x2)













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.




- 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


- 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 để ý.


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


* 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)


* 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:

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)
{
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)
}























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

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
})
}
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*/
}
}

×