# Sửa bàn rê chuột không xài được: Cách làm thủ công

# Kiểm tra thiết bị GPI0 đã được macOS nhận chưa

Phần hướng dẫn này mặc định là bạn đã cài xong macOS và có sẵn phần mềm IORegistryExplorer (opens new window).

Việc đầu tiên là phải kiểm tra xem thiết bị GPI0 có tồn tại hay không (vì đây là điều kiện bắt buộc để kext VoodooI2C có thể hoạt động). Cách tốt nhất là sử dụng IORegistryExplorer để soi.

Nếu bạn thấy dòng chữ VoodooGPIO đang đính kèm vào thiết bị GPI0 như hình, thì chúc mừng bạn, kext đã bám được vào controller do đó hông cần chỉnh sửa gì thêm cho mục này hết nha. Bạn có thể nhảy thẳng tới phần tiếp theo.

Ngược lại, nếu VoodooGPIO vẫn "bặt vô âm tín", bạn sẽ cần phải cài đặt thêm vài giá trị để đánh thức thiết bị GPI0 dậy. Bây giờ, bạn cần đi tìm thiết bị GPI0 nằm ở đâu trong DSDT của máy bạn.

Việc tìm đường dẫn ACPI (ACPI pathing) thiệt ra khá dễ dàng. Đầu tiên, hãy mở tệp DSDT mà bạn có được từ bước Trích lục bản sao DSDTđã được biên dịch ngược bằng MaciASL (nếu bạn sử dụng macOS) hoặc bất kỳ trình soạn thảo văn bản nào nếu bạn đang có Windows hoặc Linux (VSCode có cái phần mở rộng hỗ trợ ACPI (opens new window) khá là xịn đó).

Tiếp theo, tìm kiếm từ khóa Device (GPI0). Bạn sẽ thấy kết quả dạng như vầy:

Ví dụ số 1:

Ngay bên dưới là phương thức _STA (viết tắt Status - Trạng thái hoạt động), nơi quyết định việc "bật" hay "tắt" thiết bị GPI0:

Method (_STA, 0, NotSerialized)
{
    If ((SBRG == Zero)) // Cửa kiểm tra số 1
    {
        Return (Zero) // Nếu SBRG để giá trị Zero -> trả về kết quả "vô hiệu hóa" -> GPI0 bị vô hiệu hóa
    }

    If ((GPEN == Zero)) // Cửa kiểm tra số 2
    {
        Return (Zero) // Nếu GPEN để giá trị Zero -> trả về kết quả "vô hiệu hóa" -> GPI0 bị vô hiệu hóa
    }

    Return (0x0F) // Trả về kết quả "mở khóa" nếu 1 trong 2 cửa được đặt giá trị One -> GPI0 được mở khóa
}

Đây là phương thức _STA dành cho hệ điều hành khác Windows mà nhà sản xuất cài vào để vô hiệu hóa bàn rê chuột. Mục tiêu của chúng ta là làm sao để phương thức _STA trả về một giá trị khác 0 (trong trường hợp này là 0x0F) để kích hoạt thiết bị GPI0. Trong ví dụ này ta thấy có 2 cửa kiểm tra, mỗi cửa kiểm tra có những khối lệnh vô hiệu hóa riêng nằm trong dấu ngoặc nhọn.
Nếu một trong hai "cửa kiểm tra" SBRG hoặc GPEN mà giá trị bằng 0 (vô hiệu hóa), thì kết quả trả về sẽ là Zero (vô hiệu hóa) và thiết bị GPI0 sẽ bị vô hiệu hóa.
Thông thường, chúng ta không nên đụng vào SBRG vì sửa nó dễ làm lỗi luôn thiết bị GPI0. Chúng ta chỉ nên chỉnh sửa giá trị của cửa kiểm tra GPEN nếu muốn kích hoạt GPI0 trên những hệ điều hành khác Windows mà thôi.

Đây là một ví dụ khác:

Thứ chúng ta cần soi kỹ chính là phương thức _STA:

Method (_STA, 0, NotSerialized)
{
    If ((GPHD == One)) // Cửa kiểm tra
    {
        Return (0x03) // Trả về kết quả vô hiệu hóa GPI0
    }

    Return (0x0F) // Trả về kết quả mở khóa GPI0 
}

Ở ví dụ này, chúng ta thấy có 1 cửa kiểm tra. Ta sẽ cần chỉnh sửa cửa kiểm tra GPHD thành giá trị Zero (0) để kết quả trả về chắc chắn là 0x0F. Nếu ta để nguyên giá trị GPHD bằng One, khi hệ điều hành quét qua, macOS được hệ thống trả về giá trị 0x03 (vô hiệu hóa thiết bị này) và là nguyên nhân khiến cho bàn rê chuột không hoạt động.

# Chỉnh sửa SSDT mẫu

Bây giờ khi đã biết cần phải "nắn" cái cửa kiểm tra nào rồi, bạn lấy file SSDT tại đây và bắt đầu "tạo ra phép màu" nào:

Dựa theo ví dụ đầu tiên, chúng ta sẽ đặt GPEN thành giá trị One để cho phép nó hoạt động trong macOS:

// Cái này khả năng cao đã được đặt sẵn trong file SSDT-GPIO bạn vừa tải về
If (_OSI ("Darwin"))
{
    GPEN = One
}

Với ví dụ thứ hai, bạn sẽ bỏ cái GPEN đi và thay bằng đoạn này:

If (_OSI ("Darwin"))
{
    GPHD = Zero
}

Đến bước này, hãy kiểm tra thành quả bằng cách biên dịch SSDT của bạn và khai báo vào tệp config.plist của bạn. Giờ đây, VoodooGPIO sẽ bám chặt lấy thiết bị GPI0 như hình minh họa ở đầu mục. Nếu bàn rê chuột vẫn "lì lợm" chưa chịu chạy kể cả khi đã kích hoạt GPI0, hãy đọc tiếp phần dưới.

# Kích hoạt bàn rê chuột lì lợm

Rất nhiều thiết bị I2C (là bàn rê chuột của bạn) có thói quen "nhìn mặt" hệ điều hành, nó sẽ kiểm tra xem có đúng là đang chạy Windows không thì mới chịu thức dậy. Tương tự như thiết bị GPI0, các thiết bị này cũng có phương thức _STA (Trạng thái hoạt động) của riêng mình.

Ví dụ về _STA (Tùy chọn)

Hãy nhìn vào phương thức _STA (trạng thái):

Method (_STA, 0, NotSerialized)  // _STA: Trạng thái hoạt động
{
    Return (LSTA (SMD1))
}

Ở đây, phương thức _STA lại đi nhờ vả một phương thức khác tên là LSTA. Nếu chúng ta tìm Method (LSTA, chúng ta sẽ thấy:

Method (LSTA, 1, Serialized)
{
    If (((Arg0 == 0x00) || (Arg0 == 0x03)))
    {
        Return (0x00)
    }

    If (CondRefOf (OSYS))
    {
        If ((OSYS < 0x07DC))
        {
            Return (0x00)
        }
    }

    Return (0x0F)
}

Giá trị OSYS là nơi lưu trữ thông tin về hệ điều hành đang chạy. Chúng ta sẽ tìm chỗ nào mà OSYS được thiết lập giá trị (ví dụ: OSYS = 0x07DC). Trong tệp DSDT này, nó nằm ở mục \_SB.PCI0._INI như hình dưới:

Có rất nhiều hàm kiểm tra cho các phiên bản Windows khác nhau, nhưng tuyệt nhiên không thấy bóng dáng hàm kiểm tra cho Darwin (cái tên mà ACPI của Apple hay sử dụng để nhận diện macOS). Thường thì chúng ta muốn đặt OSYS ở giá trị cao nhất có thể để kích hoạt hết mọi "tính năng". Trong trường hợp này, giá trị cao nhất là khi Windows là "Windows 2015", tức là Windows 10 (opens new window). Cái này có nghĩa là ta nên đặt OSYS thành giá trị 0x07DF. Lưu ý là giá trị này lớn hơn 0x07DC (mốc kiểm tra lúc nãy). Nếu chúng ta đặt OSYS thành giá trị 0x07DF, việc kiểm tra trong LSTA sẽ trả về giá trị 0x0F và bàn rê chuột sẽ sống dậy!.

Cách tốt nhất để vá các hàm kiểm tra này là bổ sung bản vá nóng đổi tên _OSI thành XOSI kết hợp sử dụng SSDT-XOSI. Bạn cũng có thể đặt OSYS ngay trong phạm vi (scope) của thiết bị I2C, mặc dù không phải lúc nào nó cũng chịu chạy (như ví dụ trên, LSTA không nằm trong phạm vi của I2C nên cách này sẽ "xịt").

# Bản vá nóng đổi tên _OSI thành XOSI

Yêu cầu tệp SSDT và bản vá sau:

Comment String Change _OSI to XOSI
Enabled Boolean YES
Count Number 0
Limit Number 0
Find Data 5f4f5349
Replace Data 584f5349
Dành riêng cho máy tính Dell

Bạn có thể cần thêm bản vá dưới đây để phím chỉnh độ sáng màn hình có thể hoạt động. Hãy đảm bảo bản vá này xuất hiện TRƯỚC bản vá đổi tên _OSI sang XOSI phía trên trong tệp config.plist nhé! Cảm ơn Rehabman về bản vá này:

Comment String Change _OSID to XSID (Đổi _OSID thành XSID để tránh trùng với bản vá _OSI)
Enabled Boolean YES
Count Number 0
Limit Number 0
Find Data 4F534944
Replace Data 58534944

# Tạo biến OSYS ngay trong thiết bị I2C

Thay vì sử dụng cách "đánh lừa" toàn bộ máy tính (vốn dễ gây lỗi màn hình xanh chết chóc khi khởi động Windows), chúng ta có thể thử một cách tế nhị hơn: Tạo ra một chiếc "mặt nạ" OSYS giả ngay bên trong phạm vi quản lý của bàn rê chuột.

Cách thực hiện: Bạn cần xác định đúng đường dẫn thiết bị chỗ lệnh kiểm tra OSYS, sau đó khai báo một biến OSYS mới ngay trong khu vực code của bàn rê chuột. Cách này chỉ thay đổi cách nhận diện hệ điều hành (mở/khóa tính năng) cho các thiết bị nằm trong khu vực đó, giúp bạn kiểm soát chi tiết hơn cái gì được mở.

Lưu ý quan trọng: Phương pháp này chỉ thành công nếu lệnh kiểm tra nằm cùng cấp hoặc thấp hơn cấp mà bạn khai báo biến. Ví dụ, nếu hàm khởi tạo tại _SB.PCI0._INI và hàm kiểm tra tại _SB.PCI0.LSTA đều đang dùng chung một biến ở tầng cao (_SB.PCI0.LSTA) thì việc bạn tạo thêm một biến riêng lẻ bên trong khu vực bàn rê chuột sẽ hoàn toàn vô tác dụng. Đơn giản là vì hàm kiểm tra ở tầng trên bị 'khuất tầm nhìn', nó chỉ dùng cái biến có sẵn ở tầng của nó mà hoàn toàn không hay biết đến sự tồn tại của cái biến riêng tư mà bạn vừa tạo thêm.

If (_OSI("Darwin")) {
    Scope (\_SB.PCI0.I2C0) { // Phạm vi (scope) I2C0 
        Name (OSYS, 0x7DF) // 0x7DF đại diện cho Windows 10 (Mở hết tính năng)
    }
}

Về các phiên bản Windows

Bạn cần biết một điều thú vị: Windows đời mới luôn trả về giá trị "đúng" (true) khi kiểm tra hàm dành cho phiên bản Windows cũ hơn. Ví dụ: Windows 7 sẽ trả về kết quả "đúng" cho các bài kiểm tra từ "Windows 2000" đến "Windows 2009", nhưng các phiên bản mới hơn thì không. Cái này quan trọng vì một số tính năng chỉ được mở ở các mốc kiểm tra Windows đời cũ. Ví dụ: bộ phận quản lý nhiệt DYTC trên các dòng ThinkPad mới chỉ được kích hoạt khi hệ điều hành chủ vượt qua bài kiểm tra "Windows 2001". Bạn cần tự soi tệp DSDT của mình để xem giá trị nào được thiết lập và tụi nó được sử dụng ở đâu. Sau khi chắc ăn xong xuôi hết rồi, bạn cần biên dịch SSDT và kiểm tra bàn rê chuột đã "ngủ dậy" chưa nha.

# Thiết lập nâng cao

Nếu bạn vẫn cần thêm sự trợ giúp để "thu phục" bàn rê chuột, nơi tốt nhất để tìm kiếm là Tài liệu hướng dẫn của VoodooI2C (opens new window)

# Gần về tới đích rồi

Khi bạn đã tạo xong SSDT của mình, bạn có thể chuyển sang trang tiếp theo để tạo nốt mấy cái SSDT còn lại hoặc truy cập vào đây nếu bạn đã hoàn tất công việc: