2P by GN⁺ | ★ favorite | 댓글 1개
  • 4K 모니터처럼 인식되던 저가 HDMI 더미 플러그를 1080p HDMI 캡처 장치처럼 보이게 하려고, 내부 EDID EEPROM을 Raspberry Pi로 다시 기록함
  • 더미 플러그는 HPD 핀 풀업과 I2C EEPROM만으로 컴퓨터가 모니터 연결을 감지하게 하며, EDID가 지원 해상도·오디오·색공간 같은 표시 장치 정보를 결정함
  • Raspberry Pi의 HDMI 포트에는 EDID용 I2C 컨트롤러가 연결돼 있어, 모델별 버스 번호만 맞추면 더미 플러그와 캡처 장치의 EDID를 읽고 비교할 수 있음
  • 실제 작업은 I2C 활성화, i2c-tools 설치, 0x50 주소 확인, get-edid 덤프, i2cset 루프를 통한 256바이트 기록 순서로 진행됨
  • 잘못된 I2C 버스나 실제 모니터에 쓰기 명령을 실행하면 EDID나 다른 EEPROM을 망가뜨릴 수 있어, 쓰기 전 파싱과 대상 확인이 필수임

4K 더미 플러그를 1080p 캡처 장치처럼 보이게 만들기

  • Amazon에서 예전에 산 저가 HDMI 더미 플러그가 4K 모니터처럼 동작해, 더 단순하고 4K 해상도를 지원하지 않는 장치처럼 보이도록 바꾸려는 작업임
  • 목표는 더미 플러그의 EDID를 여러 1080p HDMI 캡처 장치 중 하나의 EDID 사본으로 교체하는 것임
  • 교체가 끝나면 컴퓨터는 4K 모니터 대신 HDMI 캡처 장치가 연결된 것으로 인식함

HDMI 더미 플러그와 EDID의 역할

  • HDMI, DVI 등의 더미 플러그는 영상 신호를 실제로 처리하지 않고, 컴퓨터 같은 영상 출력 장치가 모니터가 연결됐다고 판단할 최소 회로만 갖춤
  • 일반적으로 필요한 요소는 두 가지임
  • EDID에는 모니터의 제조사, 제조일, 지원 해상도, 오디오 채널, 색공간 같은 정보가 들어 있음
  • 이런 더미 플러그는 헤드리스 머신에서 운영체제가 모니터가 붙어 있다고 생각하게 만드는 데 유용함

Raspberry Pi의 HDMI I2C 버스

  • Raspberry Pi Zero의 HDMI 포트에는 EDID를 읽기 위한 I2C 컨트롤러가 올바른 핀에 연결돼 있음
  • Pi 모델별로 확인할 I2C 버스는 다음과 같음
    • Pi 0-3: /dev/i2c-2
    • Pi 4: /dev/i2c-20, /dev/i2c-21
    • Pi 5: /dev/i2c-11, /dev/i2c-12
  • Raspberry Pi Zero를 쓰는 경우 edid_i2c=2로 설정함
  • 다른 모델에서는 위 목록에 맞춰 버스 번호를 바꿔야 함

준비 작업

  • 새 Raspberry Pi OS Lite 설치에서 먼저 I2C 접근 환경을 준비함
    • sudo raspi-config 실행 후 Interface Options에서 I2C 활성화
    • sudo apt install i2c-tools로 I2C 도구 설치
  • Pi Zero에서는 네트워크 접근이 문제가 될 수 있어 USB-Ethernet 어댑터가 필요할 수 있음
  • 대안으로 SD 카드를 Debian/Ubuntu 데스크톱 PC에 꽂고, binfmt-supportqemu-user-static을 설치한 뒤 SD 카드의 rootfs에 chroot해 apt install을 실행할 수도 있음
  • 작업 환경에 따라 HDMI-to-Mini-HDMI 어댑터도 필요함

원본 EDID 읽기와 검증

  • 먼저 더미 플러그가 EDID EEPROM으로 인식되는지 확인함
edid_i2c=2
i2cdetect -y $edid_i2c
  • 결과에서 주소 0x50에 I2C 장치가 감지됐고, 이는 EDID에 사용되는 주소임
  • 해당 더미 플러그는 0x51부터 0x57까지도 응답했으며, 이 주소들에는 같은 EDID의 복사본이 들어 있는 것으로 보임
  • 모든 더미 플러그가 이렇게 동작하지는 않으며, 다른 더미 플러그 하나는 0x50만 감지됨
  • 원본 EDID는 다음 명령으로 덤프함
get-edid -b $edid_i2c > edid-orig.bin
  • get-edid는 I2C 버스 2에서 256바이트 EDID를 성공적으로 읽었다고 출력함
  • 같은 덤프를 두 번 수행해 결과가 동일한지 비교함
  • 이후 od로 헥스 덤프를 출력하고, edidreader.com에 붙여 넣어 유효한 EDID인지 확인함
od -v -An -txC edid-orig.bin

캡처 장치 EDID를 더미 플러그에 쓰기

  • 더미 플러그의 원본 EDID를 백업한 뒤, Pi의 HDMI 포트에서 더미 플러그를 빼고 HDMI 캡처 장치를 연결함
  • 같은 방식으로 캡처 장치의 EDID를 덤프함
get-edid -b $edid_i2c > edid-capture-card.bin
  • 캡처 장치의 EDID도 유효한 EDID인지 확인함
  • 이후 캡처 장치를 빼고 더미 플러그를 다시 연결한 뒤, 캡처 장치의 EDID를 더미 플러그 EEPROM에 기록함
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
  • 이 스크립트는 덤프 파일의 EDID를 두 자리 16진수 문자열 배열로 만들고, 각 바이트 앞에 0x를 붙여 i2cset으로 EEPROM에 순서대로 씀
  • edid-checked-writer 같은 도구도 있지만, 위 방식은 표준 Linux userspace I2C 도구와 bash 또는 dash만 있으면 동작함

쓰기 결과 확인

  • 기록 후 다시 더미 플러그에서 EDID를 읽어 캡처 장치 EDID 파일과 비교함
get-edid -b $edid_i2c > edid-test.bin
diff edid-test.bin edid-capture-card.bin
  • diff가 아무 출력도 내지 않아 새 덤프가 원본 캡처 장치 EDID와 동일함을 확인함
  • 더미 플러그의 EEPROM은 캡처 장치의 EDID로 재프로그래밍
  • 이후 테스트 컴퓨터에 꽂아 부팅하자, 컴퓨터는 4K 모니터 대신 HDMI 캡처 장치가 연결된 것처럼 동작함

쓰기 전에 확인해야 할 위험

  • 실제 모니터가 연결된 상태에서 이 절차를 실행하고 해당 모니터의 EDID가 보호돼 있지 않다면, 모니터를 망가뜨릴 수 있음
  • 반드시 더미 플러그처럼 망가져도 되는 장치를 HDMI 포트에 연결한 상태에서만 쓰기 명령을 실행해야 함
  • 올바른 I2C 버스인지 확신해야 하며, 쓰기 전에 EDID를 읽고 파싱해 실제 EDID가 들어 있는지 확인해야 함
  • PC에서 이 명령을 실행하면 RAM 모듈의 SPD EEPROM 같은 EDID가 아닌 하드웨어를 실수로 플래시할 가능성이 있음
  • 실제 PC에서 I2C 쓰기를 실험하기보다 Raspberry Pi를 사용하면 데스크톱 PC를 망가뜨릴 위험을 줄일 수 있음
  • 같은 방식은 반대로 오래된 1080p 더미 플러그에 4K 지원 EDID를 넣는 용도로도 사용할 수 있음

댓글과 토론

Hacker News 의견들
  • 집에서 해보려는 사람들에게 작은 주의점: 이런 저가 더미 플러그는 EEPROM이 256바이트뿐이라, 고해상도·고주사율 설정에 필요한 여러 확장 EDID 블록을 저장하기엔 부족함
    1080p60만 필요하면 괜찮지만, 4k240 모니터를 흉내 내는 용도로는 쓸 수 없음
    또 일부는 쓰기 보호선이 high 또는 low로 고정돼 있어서 실제로 쓰려면 약간의 하드웨어 작업이 필요함

    • WP가 high인지 low인지는 사용하는 칩 종류에 따라 달라질 수 있음
  • 이런 더미 플러그의 한 가지 한계는 HDCP를 지원하지 않는다는 점임
    헤드리스 머신에서 특정 해상도 출력을 강제로 만들기에는 잘 맞지만, HDCP를 요구하는 무언가를 실행해야 하는 용도에는 실패함
    HDMI 더미 플러그처럼 동작하면서 HDCP 협상까지 해주는 좋은 해결책이 있는지 궁금함
    전체 해상도로 재생하려면 HDCP가 필요한 동영상 스트리밍 앱을 테스트해야 하는데, 테스트마다 TV를 하나씩 두기는 불편함
    지금까지 찾은 해결책은 HDMI 멀티뷰어인데, 각 포트별로 HDCP를 따로 협상하는 것처럼 보임

    • HDMI 분배기를 쓰고 있음
      사전 설정된 EDID를 쓰거나, HDMI 출력 1에 연결한 장치에서 EDID를 학습한 뒤, 분배기에 전원만 들어와 있으면 출력에 아무것도 연결하지 않아도 연결된 모니터처럼 보이게 해줌
      컴퓨터나 콘솔과 분배기 사이에서는 HDCP를 협상하고, 출력 모니터로는 HDCP 없이 신호를 보내는 것으로 알고 있음
      https://www.amazon.com/dp/B07VP37KMB
    • 다른 용도가 있음
      HDMI를 출력하는 임베디드 시스템이 있는데, 부팅 화면을 다른 HDMI 스트림으로 바꾸고 싶음. 정적 이미지면 충분함
      여러 이유로 임베디드 시스템 자체는 전혀 바꾸고 싶지 않은데, 이걸 싸고 견고하게 할 방법이 궁금함
    • Aliexpress에 HDCP를 종료하고 HDMI를 전달한다고 주장하는 물건들이 있음
      다만 구매자 주의가 필요함
    • Amazon에서 거의 노골적으로 “HDCP 스트리퍼”처럼 광고되는 HDMI 분배기 중 하나를 써보면 됨
    • HDCP 종료는 어렵고, HDCP 1.4로 다운그레이드한 뒤 1.4 “호환” 장치가 끝단에 있어야 더미 모니터처럼 동작할 수 있음
      HDCP 1.4보다 최신이 필요하다면 아마 불가능에 가까움
  • 관련해서, EDID 바이너리를 모아둔 괜찮은 아카이브나 더 나은 생성 프로그램이 있는지 궁금함
    프로그래머블 EDID 에뮬레이터 플러그가 있어서 내 모니터나 다른 모니터를 복제할 수는 있지만, 특정 해상도나 기능을 설정하고 싶을 때 방법이 없는 경우가 있음. 예를 들면 DSC가 포함된 8K 같은 것
    https://github.com/bsdhw/EDID는 알고 있지만 최신 모니터 쪽은 꽤 제한적임
    https://www.analogway.com/products/aw-edid-editor로 직접 만들어본 적도 있지만, 여러 모드의 세부 차이나 선호 순서 설정 등을 제대로 맞추기가 적어도 나에겐 꽤 어려움

    • EDID 편집 경험이 너무 많음
      추천은 이렇다: 이미 언급한 AW EDID Editor, Windows 전용인 CRU, EDID 템플릿이 있는 010 Hex Editor, Linux에서는 Flatpak의 wxEDID, v4l-utils의 edid-decode
      CRU는 모니터에서 덤프한 EDID 파일을 수정하면서 상세 해상도 공간을 만들기 위해 일련번호 같은 디스크립터를 제거하지만 동작은 함. Wine에서는 실행되지 않음
      wxEDID는 배포판 패키지가 WxWidgets에서 크래시했던 것으로 기억하고, 섹션을 새로 만들 수 있는지는 모르겠음
      edid-decode는 git diff의 textconv 도구로도 쓸 수 있지만 EDID 파일 인코딩에는 도움이 안 됨
      HDMI EDID에는 CEA 확장 블록이 있고, DP EDID에는 DisplayID 확장 블록이 있는 것으로 봄
      256바이트를 넘는 다중 페이지 EDID는 해본 적이 없고, 어떤 EEPROM 칩으로 에뮬레이션해야 하는지나 읽고 쓰는 프로토콜/API도 모름
    • https://www.extron.com/product/software/edidmanager30
      https://www1.kramerav.com/au/product/edid%20designer
      둘 다 무료지만 자유롭게 재배포할 수 있는 소프트웨어는 아님
      Extron 쪽은 해당 하드웨어를 쓰는 프로젝트나 조직에서 일해야 할 수도 있음
    • 최근 비슷한 문제가 있었음
      HDMI로 Dolby TrueHD까지 지원하는 저가 5.1 서라운드 사운드바를 샀는데, 함정은 eARC 지원 장치, 즉 신형 TV에서만 제대로 동작한다는 점임
      PC에 연결하면 SPDIF나 AUX를 써야 해서 품질이 떨어짐
      오디오 추출기나 분배기를 사는 것 말고, PC EDID를 속여 사운드바가 eARC로 인식하게 만드는 방법이 있음
      아직 작업 중이고, 아쉽게도 명확한 가이드라인은 없음
    • 어떤 프로그래머블 EDID 에뮬레이터 플러그를 쓰는지 궁금함
      최근에 찾아봤는데, 어떤 장치가 어떤 기능을 갖췄는지, 더 저렴한 제품 중 괜찮은 것이 있는지 명확하지 않았음
  • 이런 제품은 패스스루가 달린 형태로도 살 수 있고, 고해상도 모니터에서 문제를 일으키는 오래된 시스템에 유용함
    2011년쯤의 AMD FX8350 시스템이 있는데, 내장 880G 노스브리지+비디오 칩셋이 4K 디스플레이로 HDMI 영상을 제대로 출력하지 못함
    중간에 이런 장치를 연결해 1080p 이미지를 보내라고 알려주면 잘 동작하고, 모니터가 4K로 2배 정수 업스케일링해줌

    • 패스스루도 몇 개 갖고 있는데, 글에서 다른 선택지로 언급했어야 했을 것 같음
      내가 가진 것은 꽤 고급형이라 모니터에서 EDID를 읽고 저장한 뒤, 다른 모니터에 대한 오버라이드로 쓸 수 있음
      또 훌륭한 점은 모니터가 항상 감지되도록 강제할 수 있다는 것임
      내 모니터 중 하나는 끄면 사실상 연결 해제된 것처럼 동작해서 여러 문제가 생겼는데, 패스스루가 완전히 해결해줌
      내가 쓰는 제품은 THWT의 HD-EWB
  • HDMI 더미 플러그는 애초에 존재하지 말아야 할 소프트웨어 문제를 해결하는 하드웨어 해결책임

    • 현존하는 수많은 하드웨어 해결책을 설명하는 말처럼 들림
  • 더미 플러그가 왜 필요한지 궁금함
    소프트웨어로는 못 하고 더미 플러그로만 할 수 있는 게 무엇인지 모르겠음. 가상 디스플레이 18개를 더미 없이 문제없이 써본 입장에서 묻는 것임

    • 한 예로, PC에서 Windows 가상 머신과 상호작용하려고 Looking Glass라는 소프트웨어를 사용함
      컴퓨터에는 GPU가 두 개 있는데, AMD GPU는 Linux 호스트용이고 NVidia GPU는 Windows 게스트에 패스스루됨
      Looking Glass는 NVidia GPU 출력을 캡처해서 내 데스크톱의 창에 표시함
      이 방식이면 VM에서 Windows 소프트웨어를 쓸 수 있고 성능도 괜찮음. Windows는 7 이후 사실상 그래픽 가속이 있어야 쓸 만하게 돌아감
      문제는 NVidia GPU가 디스플레이가 연결되지 않으면 아무것도 하지 않는다는 점임
      NVidia Quadro GPU는 모니터 EDID를 덤프해 그 파일을 출력에 매핑할 수 있지만, 소비자용 GPU는 이를 지원하지 않음
      그래서 더미 플러그가 필요함
    • 이동 중인 사람이 화면 하나로 Zoom이나 Teams 통화를 하면서도 PowerPoint 발표자 보기를 쓰기 매우 쉬워짐
      더미 플러그 화면을 PowerPoint 출력으로 쓰고, 노트북 화면은 발표자 노트로 쓰면 됨
      그런 다음 더미 플러그 화면을 공유하면 됨
      Hacker News 독자에게는 최고의 답이 아닐 수 있지만, 교사나 영업 담당자에게는 정말 간단함
    • 많은 운영체제·GPU·드라이버 조합은 임의 설정의 가상 디스플레이를 실제로 만들 수 있게 해주지 않음
      OBS 스트리밍이나 Steam, Parsec 같은 게임 스트리밍 설정 때문에 필요할 수도 있음
      몇 년 전 Linux의 Xorg와 오픈소스 드라이버, Windows와 Nvidia 조합에서는 어느 정도 됐지만, MacOS나 Windows+AMD/Intel GPU에서는 그렇게 잘 동작하지 않았음
    • 바이너리 임베디드 Linux 배포판을 테스트할 때 사용함
      운영체제를 속여 디스플레이가 연결된 것으로 보이게 하면 사용자의 실제 배포 환경에는 없는 새 변수가 생기는데, 더미 플러그는 저렴한 하드웨어 해결책임
      엔지니어가 echo on > /sys/whatever와 그 주변 로직을 작성하게 하는 것보다, 사서 꽂는 편이 비용 효율적일 가능성이 큼
    • 대부분의 사람에게 더미 플러그가 훨씬 쉬움
      원격 게임 스트리밍을 위해 소프트웨어로 데스크톱에 가짜 4K 모니터를 추가했는데, 예상보다 훨씬 복잡했음
      https://pfy.ch/programming/4k-sunshine.html
  • 재미있는 팁: 같은 절차로 일반 모니터나 노트북 화면에 저장된 EDID도 수정할 수 있음
    때로는 다른 I2C 주소에 써서 TCON의 여러 설정까지 바꿀 수 있음
    Raspberry Pi가 꼭 필요한 것도 아니고, 아무 컴퓨터나 가능함

    • Acer 모니터에서 한 번 해본 적 있음
      CRT처럼 블러 없는 영상을 만들려고 LED 백라이트를 스트로브하도록 개조하고 있었음
      DDC 버스가 백라이트 등을 제어하는 다른 레지스터도 노출한다는 걸 발견했고, 스트로빙을 위해 외부 회로를 연결했음
      플래시 ROM을 읽고 쓰는 레지스터도 보여서 덤프한 뒤, 8051 디스어셈블러를 작성하고 대략적인 역공학을 했고, 결국 스트로브 모드를 포함하도록 ROM을 수정함
      이 모드는 밝기 조절의 낮은 구간을 차지하게 해서 OSD나 일반 DDC 밝기 제어로 켜고 조정할 수 있게 했음
      플래시할 때는 내부를 열어 쓰기선을 연결해야 했음
      편리하게도 vblank 인터럽트가 있었고, LED 백라이트를 제어하는 타이머에는 다음 인터럽트 직전에 켜고 조정 가능한 시간 뒤에 끌 수 있는 모드가 있었음
      LCD 갱신이 안정된 직후 백라이트를 켜는 데 딱 맞는 타이밍이었음
      원래 목표는 몇 초짜리 부팅 로고를 없애는 것뿐이었고, 그건 성공했음
    • 플래시 칩에는 보통 쓰기 활성/비활성 핀이 있고, 대부분의 모니터와 TV는 EDID 쓰기를 막도록 배선함
      저가 제품만 생략할 것 같음
      보호가 없으면 읽기 중 전압 글리치가 쓰기로 바뀌어 플래시를 망가뜨릴 수 있어서 위험함
    • 글쓴이는 Pi 사용을 권장하지만 필수는 아니라고 적고 있음
      “PC에서 이 명령을 시도하면 EDID가 아닌 하드웨어, 예를 들어 RAM 모듈의 SPD EEPROM을 실수로 플래시할 수 있음”
    • 일반 모니터에 저장된 EDID를 같은 방식으로 수정할 수 있다면, 하드웨어 개발자 입장에서는 이상한 실수처럼 보임
      보통은 미리 프로그래밍된 EEPROM을 사서 보드에 실장하고, 쓰기 활성 핀이 절대 high로 올라가지 않게 배선할 것임
      모니터 같은 제품에 EEPROM을 넣어두고 쓰기 가능하게 남겨두는 건 이상하지만, 출시된 하드웨어에서 더 이상한 것도 본 적은 있음
  • 혼란스러움
    플러그를 GPIO I2C 핀에 연결하는 모습을 기대했는데, 그냥 RPi에 꽂는 것만으로 충분해 보임
    그렇다면 HDMI가 I2C 인터페이스를 직접 노출하는 것인지 궁금함

    • 맞음. VGA/HDMI/DVI의 통신 부분인 DDC 링크가 기본적으로 I2C 링크이고, 운영체제가 정상 동작 중 EDID를 조회하는 방식도 그것임
      글에서 언급했듯이 RPi에는 그 HDMI 포트 핀에 연결된 I2C 컨트롤러가 있음. DDC를 통해 EDID를 읽어야 하기 때문임
  • KVM과 Linux 문제를 해결할 저렴한 DisplayPort EDID 에뮬레이터를 아는 사람이 있는지 궁금함
    마지막으로 확인했을 때 HDMI보다 훨씬 비싸서, 차라리 새 KVM을 사는 편이 나을 정도였음

  • 더미 플러그를 기기 지문 추적을 바꾸는 데도 쓸 수 있는지 궁금함