Reverse Engineering of the MacroSilicon MS2130.
  • Python 62.8%
  • C 16.5%
  • Java 8%
  • Shell 7%
  • Assembly 3.7%
  • Other 2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-18 20:05:32 -04:00
docs Remove redundancy from the docs 2026-10-18 20:05:32 -04:00
nix Add flake, license and udev rule 2026-10-18 19:56:21 -04:00
tools Add HID helpers, live probing and analysis scripts 2026-10-18 19:56:22 -04:00
udev Add flake, license and udev rule 2026-10-18 19:56:21 -04:00
.gitignore Add flake, license and udev rule 2026-10-18 19:56:21 -04:00
flake.lock Add flake, license and udev rule 2026-10-18 19:56:21 -04:00
flake.nix Add flake, license and udev rule 2026-10-18 19:56:21 -04:00
LICENSE Add flake, license and udev rule 2026-10-18 19:56:21 -04:00
README.md Add README 2026-10-18 19:58:31 -04:00

MS2130 capture card reverse engineering

Notes and tools from reverse engineering the firmware of the UGREEN 15389 HDMI capture card (USB 2b89:5389, MacroSilicon MS2130), tested on one card.

What came out of it:

  • The firmware is an 8051 image in a 64 KB SPI flash. The flash format, the two checksums and the HID command set are documented, so a modified image can be written back with ms-tools.
  • The boot and no-signal screens can be replaced with your own text or a two-color image, up to fullscreen. tools/ms2130-osd builds the image and checks it in an emulator before you flash it.
  • The signal-detection logic is understood well enough to say what makes the card lock to an input: it is gated on receiver status flags, not on a list of supported resolutions. The hardware timing registers (0xE000..0xEFFF) are decoded.
  • Latency was measured: 32 to 49 ms, 40 ms on average, from the PC starting to send a frame to the frame reaching the application, the same for raw and MJPEG and for 1080p and 720p. The card's frame clock is not locked to the source, which is why it is a range and not a number.
  • About 15% of the firmware is understood. The rest, such as the USB stack, the video and audio pipeline and most HID handlers, has not been read. docs/ says what is known and how sure it is.

Read this before flashing

  • Writing flash erases the whole chip first. If power or USB drops before the write finishes, the card is left blank or half written. No recovery procedure for the MS2130 is documented. The card might fall back to a ROM USB ID (534d:2130), but that is only an inference from another tool's device table. An external SPI programmer is the safe fallback, and the flash chip on the board has not been identified.
  • Use a direct USB port with a good cable, and keep your own stock dump somewhere safe.
  • Nothing here was tried on another card or firmware revision. The tools refuse an image whose code checksum is not the one they were written against.
  • This project is not affiliated with UGREEN or MacroSilicon. Use it at your own risk.

What is not in this repository

No firmware, flash dump, disassembly or decompiled code. Anything derived from the firmware lives in workspace/, which is git-ignored, and *.bin is ignored everywhere else. You need your own dump:

nix develop                                   # or install ms-tools, Python 3, Pillow, sdcc by hand
sudo cp udev/70-ugreen-capture.rules /etc/udev/rules.d/ && sudo udevadm control --reload && sudo udevadm trigger
mkdir -p workspace/dump
tools/hid/read_flash.sh workspace/dump/flash.bin      # takes about a minute
dd if=workspace/dump/flash.bin of=workspace/dump/code.bin bs=1 skip=48 count=59436
sha256sum workspace/dump/*.bin

The stock firmware of the tested card has these hashes. If yours differs, the screen editor will not touch it.

File sha256
flash.bin abde4156563bcf271e3290e7d839c8cc0e258289e6164a5759ad3f99a58f9ed6
code.bin 7b5ac5aacb8d455618ca27c0c44ec415d5af3eabe5d5a8dae92fd83ba233f7a7

On NixOS see docs/01-device-and-flash.md for installing the udev rule.

Change the screens

cd tools/ms2130-osd
python3 ms2130_osd.py example > my.toml            # edit it, or start from examples/
python3 ms2130_osd.py build ../../workspace/dump/flash.bin my.toml \
  -o ../../workspace/new.bin --verify --preview ../../workspace/previews
ms-tools --vid=2b89 --no-patch --no-firmware write-file FLASH 0 ../../workspace/new.bin

Unplug and replug the card afterwards. Details and limits (screens are two colors and must fit in about 3.9 KB): tools/ms2130-osd/README.md.

Layout

Path Content
docs/ The findings, in six parts (below)
tools/ Everything that runs; see tools/README.md
udev/ udev rule that gives the logged-in user access to the card's HID interface
nix/ Package for ms-tools, used by the flake
workspace/ Not tracked: your dump, the decompile, the Ghidra project, captures

Docs

  1. docs/01-device-and-flash.md: the device, how to access it, the flash layout, writing and recovery
  2. docs/02-firmware-structure.md: reset, interrupts, memory use, the HID command table, how the decompile was made
  3. docs/03-osd-and-screens.md: the no-signal screens, the OSD frame buffer, custom screens
  4. docs/04-signal-detection.md: how the card detects and locks to an input, the timing registers
  5. docs/05-latency.md: the latency measurement
  6. docs/06-open-questions.md: what is not known, and ideas

The docs mark what was checked on the device or against the dump (verified) and what was only read from the disassembly (inferred).

Credits

MIT licensed, see LICENSE.