- Để biến một HDMI dummy plug giá rẻ vốn được nhận diện như màn hình 4K thành thiết bị trông giống bộ capture HDMI 1080p, tác giả đã ghi lại EDID EEPROM bên trong bằng Raspberry Pi
- Dummy plug dùng điện trở kéo lên ở chân HPD và I2C EEPROM để máy tính phát hiện có màn hình được kết nối; EDID quyết định thông tin thiết bị hiển thị như độ phân giải hỗ trợ, âm thanh và không gian màu
- Cổng HDMI của Raspberry Pi có bộ điều khiển I2C dành cho EDID được nối sẵn, nên chỉ cần chọn đúng số bus theo từng model là có thể đọc và so sánh EDID của dummy plug với thiết bị capture
- Quy trình thực tế gồm bật I2C, cài
i2c-tools, kiểm tra địa chỉ 0x50, dump bằng get-edid, rồi ghi 256 byte qua vòng lặp i2cset
- Nếu chạy lệnh ghi trên bus I2C sai hoặc trên màn hình thật, có thể làm hỏng EDID hoặc EEPROM khác, nên bắt buộc phải phân tích và xác nhận thiết bị đích trước khi ghi
Biến dummy plug 4K trông như thiết bị capture 1080p
- Đây là quá trình chỉnh sửa một HDMI dummy plug giá rẻ mua trên Amazon trước đây, vốn hoạt động như màn hình 4K, để nó trông như một thiết bị đơn giản hơn và không hỗ trợ độ phân giải 4K
- Mục tiêu là thay EDID của dummy plug bằng một bản sao EDID của một trong nhiều thiết bị capture HDMI 1080p
- Sau khi thay xong, máy tính sẽ nhận diện rằng một thiết bị capture HDMI đang được kết nối thay vì màn hình 4K
Vai trò của HDMI dummy plug và EDID
- Dummy plug cho HDMI, DVI… không thật sự xử lý tín hiệu hình ảnh, mà chỉ có mạch tối thiểu để thiết bị xuất hình như máy tính cho rằng đã có màn hình được kết nối
- Thông thường cần hai thành phần
- EDID chứa thông tin như nhà sản xuất màn hình, ngày sản xuất, độ phân giải hỗ trợ, kênh âm thanh và không gian màu
- Những dummy plug như vậy hữu ích để khiến hệ điều hành trên máy headless nghĩ rằng có màn hình đang gắn vào
Bus I2C HDMI trên Raspberry Pi
- Cổng HDMI của Raspberry Pi Zero có bộ điều khiển I2C để đọc EDID được nối vào đúng các chân
- Các bus I2C cần kiểm tra theo từng model Pi như sau
- Pi 0-3:
/dev/i2c-2
- Pi 4:
/dev/i2c-20, /dev/i2c-21
- Pi 5:
/dev/i2c-11, /dev/i2c-12
- Khi dùng Raspberry Pi Zero, đặt
edid_i2c=2
- Với các model khác, cần đổi số bus theo danh sách trên
Chuẩn bị
- Trên bản cài Raspberry Pi OS Lite mới, trước tiên chuẩn bị môi trường truy cập I2C
- Chạy
sudo raspi-config, rồi bật I2C trong Interface Options
- Cài công cụ I2C bằng
sudo apt install i2c-tools
- Với Pi Zero, truy cập mạng có thể là vấn đề, nên có thể cần adapter USB-Ethernet
- Một cách khác là cắm thẻ SD vào PC desktop chạy Debian/Ubuntu, cài
binfmt-support và qemu-user-static, rồi chroot vào rootfs của thẻ SD để chạy apt install
- Tùy môi trường làm việc, cũng có thể cần adapter HDMI-to-Mini-HDMI
Đọc và kiểm tra EDID gốc
- Trước tiên kiểm tra dummy plug có được nhận diện như EDID EEPROM hay không
edid_i2c=2
i2cdetect -y $edid_i2c
- Trong kết quả, thiết bị I2C được phát hiện tại địa chỉ
0x50, đây là địa chỉ dùng cho EDID
- Dummy plug này cũng phản hồi từ
0x51 đến 0x57, có vẻ các địa chỉ này chứa những bản sao của cùng EDID
- Không phải dummy plug nào cũng hoạt động như vậy; một dummy plug khác chỉ được phát hiện ở
0x50
- Dump EDID gốc bằng lệnh sau
get-edid -b $edid_i2c > edid-orig.bin
get-edid báo đã đọc thành công EDID 256 byte từ bus I2C 2
- Thực hiện cùng thao tác dump hai lần và so sánh xem kết quả có giống nhau không
- Sau đó xuất hex dump bằng
od, rồi dán vào edidreader.com để kiểm tra xem EDID có hợp lệ không
od -v -An -txC edid-orig.bin
Ghi EDID của thiết bị capture vào dummy plug
- Sau khi sao lưu EDID gốc của dummy plug, rút dummy plug khỏi cổng HDMI của Pi và kết nối thiết bị capture HDMI
- Dump EDID của thiết bị capture theo cùng cách
get-edid -b $edid_i2c > edid-capture-card.bin
- Cũng kiểm tra EDID của thiết bị capture có phải EDID hợp lệ không
- Sau đó rút thiết bị capture, cắm lại dummy plug, rồi ghi EDID của thiết bị capture vào EEPROM của dummy plug
edidbytes=($(od -v -An -txC edid-capture-card.bin))
for i in "${!edidbytes[@]}"; do
byte=0x${edidbytes[$i]}
echo Writing byte $i: $byte...
i2cset -f -y $edid_i2c 0x50 $i $byte
done
- Script này biến EDID trong file dump thành mảng các chuỗi hex hai chữ số, thêm
0x vào trước mỗi byte, rồi dùng i2cset ghi tuần tự vào EEPROM
- Cũng có các công cụ như edid-checked-writer, nhưng cách trên chỉ cần công cụ I2C userspace tiêu chuẩn của Linux và bash hoặc dash là chạy được
Kiểm tra kết quả ghi
- Sau khi ghi, đọc lại EDID từ dummy plug và so sánh với file EDID của thiết bị capture
get-edid -b $edid_i2c > edid-test.bin
diff edid-test.bin edid-capture-card.bin
diff không xuất gì, xác nhận dump mới giống hệt EDID gốc của thiết bị capture
- EEPROM của dummy plug đã được lập trình lại bằng EDID của thiết bị capture
- Sau đó, khi cắm vào máy tính thử nghiệm và khởi động, máy tính hoạt động như thể một thiết bị capture HDMI được kết nối thay vì màn hình 4K
Rủi ro cần kiểm tra trước khi ghi
- Nếu chạy quy trình này khi đang kết nối màn hình thật và EDID của màn hình đó không được bảo vệ, có thể làm hỏng màn hình
- Chỉ được chạy lệnh ghi khi cổng HDMI đang kết nối với thiết bị chấp nhận hỏng như dummy plug
- Phải chắc chắn đang dùng đúng bus I2C, và trước khi ghi cần đọc rồi phân tích EDID để xác nhận thật sự có EDID ở đó
- Nếu chạy các lệnh này trên PC, có khả năng vô tình flash phần cứng không phải EDID, chẳng hạn SPD EEPROM của mô-đun RAM
- Dùng Raspberry Pi thay vì thử nghiệm ghi I2C trên PC thật có thể giảm nguy cơ làm hỏng desktop PC
- Cách tương tự cũng có thể dùng theo chiều ngược lại: đưa EDID hỗ trợ 4K vào dummy plug 1080p cũ
1 bình luận
Các ý kiến trên Hacker News
Một lưu ý nhỏ cho những ai muốn thử ở nhà: các dummy plug giá rẻ kiểu này chỉ có EEPROM 256 byte, nên không đủ để lưu nhiều khối EDID mở rộng cần thiết cho các thiết lập độ phân giải cao/tần số quét cao
Nếu chỉ cần 1080p60 thì ổn, nhưng không thể dùng để giả lập màn hình 4k240
Ngoài ra, một số loại có đường bảo vệ ghi được cố định ở mức high hoặc low, nên muốn ghi thực sự thì cần chỉnh sửa phần cứng một chút
Một hạn chế của các dummy plug kiểu này là chúng không hỗ trợ HDCP
Chúng rất phù hợp để ép máy chạy headless xuất ra một độ phân giải nhất định, nhưng sẽ thất bại nếu cần chạy thứ gì đó yêu cầu HDCP
Không biết có giải pháp tốt nào hoạt động như HDMI dummy plug mà còn thực hiện được cả thương lượng HDCP không
Tôi cần kiểm thử các ứng dụng streaming video yêu cầu HDCP để phát ở độ phân giải đầy đủ, nhưng mỗi lần kiểm thử lại phải đặt một TV thì bất tiện
Giải pháp tôi tìm được đến nay là HDMI multiviewer, có vẻ như nó thương lượng HDCP riêng cho từng cổng
Nó có thể dùng EDID cài sẵn, hoặc học EDID từ thiết bị nối vào HDMI output 1, rồi miễn là bộ chia có nguồn, nó sẽ làm cho hệ thống thấy như có màn hình được kết nối ngay cả khi không cắm gì ở đầu ra
Theo tôi hiểu, nó thương lượng HDCP giữa máy tính/console và bộ chia, rồi gửi tín hiệu tới màn hình đầu ra mà không có HDCP
https://www.amazon.com/dp/B07VP37KMB
Tôi có một hệ thống nhúng xuất HDMI, và muốn thay màn hình khởi động bằng một luồng HDMI khác. Chỉ cần ảnh tĩnh là đủ
Vì nhiều lý do, tôi hoàn toàn không muốn thay đổi bản thân hệ thống nhúng, nên đang tự hỏi có cách nào làm việc này rẻ và bền không
Tuy nhiên cần người mua tự cẩn trọng
Nếu cần phiên bản mới hơn HDCP 1.4 thì có lẽ gần như bất khả thi
Liên quan đến chuyện này, tôi không biết có kho lưu trữ tốt nào tập hợp binary EDID, hoặc chương trình tạo EDID nào tốt hơn không
Tôi có một plug giả lập EDID lập trình được nên có thể clone màn hình của mình hoặc màn hình khác, nhưng đôi khi không có cách nào để thiết lập một độ phân giải hay tính năng cụ thể, chẳng hạn 8K có DSC
Tôi biết https://github.com/bsdhw/EDID, nhưng phần màn hình đời mới thì khá hạn chế
Tôi cũng từng tự tạo bằng https://www.analogway.com/products/aw-edid-editor, nhưng ít nhất với tôi thì việc chỉnh đúng các khác biệt chi tiết giữa nhiều chế độ, thứ tự ưu tiên, v.v. khá khó
Khuyến nghị của tôi là: AW EDID Editor đã được nhắc tới, CRU chỉ dành cho Windows, 010 Hex Editor có template EDID, wxEDID dạng Flatpak trên Linux, và edid-decode của v4l-utils
CRU hoạt động được, nhưng khi sửa file EDID dump từ màn hình, nó sẽ xóa các descriptor như số sê-ri để tạo chỗ cho phần độ phân giải chi tiết. Nó không chạy được trên Wine
Tôi nhớ gói wxEDID trong distro từng bị crash ở WxWidgets, và không biết nó có tạo được section mới hay không
edid-decode cũng có thể dùng làm công cụ textconv cho git diff, nhưng không giúp mã hóa file EDID
Theo tôi thấy, HDMI EDID có khối mở rộng CEA, còn DP EDID có khối mở rộng DisplayID
Tôi chưa từng làm EDID nhiều trang vượt quá 256 byte, và cũng không biết nên giả lập bằng chip EEPROM nào hay giao thức/API đọc ghi ra sao
https://www1.kramerav.com/au/product/edid%20designer
Cả hai đều miễn phí nhưng không phải phần mềm được phép tái phân phối tự do
Với Extron, có thể bạn phải làm trong một dự án hoặc tổ chức dùng phần cứng tương ứng
Tôi mua một soundbar surround 5.1 giá rẻ hỗ trợ tới Dolby TrueHD qua HDMI, nhưng cái bẫy là nó chỉ hoạt động đúng với thiết bị hỗ trợ eARC, tức TV đời mới
Nếu nối với PC thì phải dùng SPDIF hoặc AUX nên chất lượng giảm
Ngoài việc mua bộ tách âm thanh hoặc bộ chia, còn có cách đánh lừa EDID của PC để soundbar được nhận diện như eARC
Tôi vẫn đang xử lý, và tiếc là chưa có hướng dẫn rõ ràng
Gần đây tôi có tìm thử, nhưng không rõ thiết bị nào có tính năng gì, và trong số các sản phẩm rẻ hơn có cái nào ổn không
Những sản phẩm như vậy cũng có thể mua ở dạng có passthrough, và hữu ích cho các hệ thống cũ gặp vấn đề với màn hình độ phân giải cao
Tôi có một hệ thống AMD FX8350 khoảng năm 2011, trong đó northbridge + chipset video tích hợp 880G không thể xuất hình HDMI đúng cách ra màn hình 4K
Nếu nối một thiết bị như thế này ở giữa để báo rằng hãy gửi hình ảnh 1080p thì nó hoạt động tốt, và màn hình sẽ upscale số nguyên 2x lên 4K
Cái tôi có thuộc loại khá cao cấp, có thể đọc và lưu EDID từ màn hình rồi dùng làm override cho một màn hình khác
Một điểm tuyệt vời nữa là nó có thể ép để màn hình luôn được phát hiện
Một trong các màn hình của tôi khi tắt thì gần như hoạt động như thể đã bị ngắt kết nối, gây ra nhiều vấn đề, và passthrough đã giải quyết hoàn toàn
Sản phẩm tôi dùng là HD-EWB của THWT
HDMI dummy plug là một giải pháp phần cứng cho một vấn đề phần mềm vốn lẽ ra không nên tồn tại
Tôi tò mò vì sao lại cần dummy plug
Tôi không rõ có việc gì chỉ dummy plug mới làm được mà phần mềm thì không. Tôi hỏi với tư cách người từng dùng 18 màn hình ảo mà không cần dummy plug và không gặp vấn đề gì
Máy tính có hai GPU: GPU AMD dùng cho host Linux, còn GPU NVidia được passthrough cho guest Windows
Looking Glass chụp đầu ra của GPU NVidia và hiển thị trong một cửa sổ trên desktop của tôi
Cách này cho phép dùng phần mềm Windows trong VM với hiệu năng khá ổn. Từ sau Windows 7, Windows về cơ bản cần tăng tốc đồ họa mới chạy đủ dùng
Vấn đề là GPU NVidia sẽ không làm gì nếu không có màn hình được kết nối
GPU NVidia Quadro có thể dump EDID của màn hình rồi map file đó vào đầu ra, nhưng GPU consumer không hỗ trợ việc này
Vì vậy cần dummy plug
Dùng màn hình của dummy plug làm đầu ra PowerPoint, còn màn hình laptop làm ghi chú thuyết trình
Sau đó chia sẻ màn hình của dummy plug là được
Đây có thể không phải câu trả lời hay nhất với độc giả Hacker News, nhưng với giáo viên hoặc nhân viên bán hàng thì thực sự rất đơn giản
Có thể cần nó cho các thiết lập stream OBS hoặc game streaming như Steam, Parsec
Vài năm trước, trên Linux với Xorg và driver nguồn mở, cũng như trên Windows với Nvidia thì làm được ở mức nào đó, nhưng trên MacOS hoặc Windows + GPU AMD/Intel thì không hoạt động tốt như vậy
Nếu đánh lừa hệ điều hành để nó nghĩ có màn hình được kết nối, ta sẽ đưa thêm một biến mới không tồn tại trong môi trường triển khai thực tế của người dùng; dummy plug là một giải pháp phần cứng rẻ tiền
Việc mua rồi cắm vào nhiều khả năng sẽ hiệu quả về chi phí hơn so với bắt kỹ sư viết
echo on > /sys/whatevervà phần logic xung quanh nóTôi đã thêm một màn hình 4K giả vào desktop bằng phần mềm để phục vụ remote game streaming, và nó phức tạp hơn dự kiến rất nhiều
https://pfy.ch/programming/4k-sunshine.html
Mẹo thú vị: có thể dùng cùng quy trình để sửa cả EDID được lưu trong màn hình thông thường hoặc màn hình laptop
Đôi khi còn có thể ghi vào địa chỉ I2C khác để thay đổi nhiều thiết lập của TCON
Cũng không nhất thiết phải dùng Raspberry Pi, máy tính nào cũng có thể làm được
Tôi đang mod để đèn nền LED nhấp nháy kiểu strobe nhằm tạo hình ảnh không bị nhòe như CRT
Tôi phát hiện bus DDC cũng phơi bày các thanh ghi khác điều khiển đèn nền, v.v., và đã nối mạch ngoài để thực hiện strobe
Tôi cũng thấy các thanh ghi đọc/ghi flash ROM, nên đã dump ra, viết một disassembler 8051 và reverse engineering ở mức sơ bộ, rồi cuối cùng sửa ROM để thêm chế độ strobe
Tôi làm cho chế độ này chiếm dải thấp của điều chỉnh độ sáng, để có thể bật và chỉnh bằng OSD hoặc điều khiển độ sáng DDC thông thường
Khi flash thì phải mở máy ra để nối dây ghi
Tiện lợi là có ngắt vblank, và timer điều khiển đèn nền LED có chế độ bật ngay trước ngắt kế tiếp rồi tắt sau một khoảng thời gian có thể điều chỉnh
Thời điểm đó vừa đúng để bật đèn nền ngay sau khi quá trình làm mới LCD đã ổn định
Mục tiêu ban đầu chỉ là loại bỏ logo khởi động kéo dài vài giây, và việc đó đã thành công
Có lẽ chỉ các sản phẩm giá rẻ mới bỏ qua phần này
Nếu không có bảo vệ, glitch điện áp trong lúc đọc có thể bị biến thành lệnh ghi và làm hỏng flash, nên rất rủi ro
“Nếu thử lệnh này trên PC, bạn có thể vô tình flash nhầm phần cứng không phải EDID, chẳng hạn SPD EEPROM của module RAM”
Thông thường người ta sẽ mua EEPROM đã được lập trình sẵn, gắn lên board, và đi dây sao cho chân bật ghi không bao giờ lên mức high
Việc đặt EEPROM trong một sản phẩm như màn hình rồi để nó vẫn có thể ghi được là điều kỳ lạ, dù tôi cũng từng thấy những thứ còn lạ hơn trên phần cứng đã bán ra
Tôi thấy hơi khó hiểu
Tôi đã nghĩ sẽ thấy cảnh nối plug vào các chân GPIO I2C, nhưng có vẻ chỉ cần cắm vào RPi là đủ
Nếu vậy thì tôi thắc mắc liệu HDMI có trực tiếp phơi bày giao diện I2C hay không
Như bài viết đã nhắc, RPi có bộ điều khiển I2C nối với các chân của cổng HDMI đó, vì nó cần đọc EDID qua DDC
Không biết có ai biết trình giả lập EDID DisplayPort giá rẻ để giải quyết vấn đề KVM và Linux không
Lần cuối kiểm tra thì nó đắt hơn HDMI nhiều, đến mức có lẽ mua KVM mới còn hơn
Thay vào đó, nó dùng bus AUX tốc độ cao chuyên dụng cho DisplayPort, phức tạp hơn nhiều khi xử lý
Có lẽ nếu không gia nhập VESA và ký cả đống NDA thì khó mà tìm được tài liệu đầy đủ
https://foosel.net/til/how-to-override-the-edid-data-of-a-mo...
Tuy nhiên, nếu mục tiêu là thêm màn hình ảo thì không rõ https://askubuntu.com/questions/453109/add-fake-display-when... có hoạt động không
Không biết có thể dùng dummy plug để thay đổi theo dõi dấu vân tay thiết bị không