[Monitor Firmware] LG DualUp/MST9U Firmware Hacking
Posted: 23 Feb 2023, 17:51
Hi all,
I recently got myself a DualUp (LG's weird 8:9 display) and got sucked down a rabbit hole trying to get it to switch inputs via DDC/CI. My background is mostly in computer engineering, security engineering, and reverse engineering, so I'm hoping I can get some help understanding panel details.
What I've done so far:
tl;dr, this repo is the current culmination of my work: https://github.com/shinyquagsire23/lg_display_manager
I started by popping LG's OnScreen software (which is used for firmware updating) into Ghidra to figure out where it downloads firmwares. As it turns out, it's pretty basic and I didn't even need Ghidra, I could have just run strings. The firmware is stored at https://lmu.lge.com/ExternalService/ons ... 221219.zip, fetched from a constant URL at https://lmu.lge.com/ExternalService/ons ... ersion.txt . The password was 28MQ780!LGdasusodkug!@#
In the zip were 3 firmwares, NXP, PD and Scalar. NXP is the USB microcontroller that's used to update the scalar firmware (apparently it also handles fans?), and PD is for USB-C stuff apparently. The scalar firmware's name was 28MQ780_MSTAR_MST9W00V4_V3.3.0_0x12FBF031_shad4015bb_220317.bin, which gave me a few more data points to drill into, specifically the chip that's used, the MStar MST9W00V4. Eventually I found this extremely annoying post (https://web.archive.org/web/20230223071 ... /123150496) which had the compiler used for the chip and this page (http://linux-chenxing.org/cpu/aeon.html) telling me that my scalar's CPU architecture was proprietary, but based on OpenRISC. It turned out that the stars had aligned or something and there were no less than 3 people interested in this particular ISA in the last 3 weeks, because someone else had asked about it (https://github.com/linux-chenxing/linux ... ussions/81) and apparently a niche disassembler added partial support for it (https://github.com/uxmal/reko/releases).
I ended up adding support to Ghidra for the ISA (it's still WIP bc there's a handful of unknown/incorrectly guessed instructions left, repo is at https://github.com/shinyquagsire23/ghidra-aeon), and with a bit more decompiling and Github scouring I managed to pull apart and decompress the main firmware binary, so I could actually figure out how the DDC/CI commands even worked.
Long story short, LG did not program the features I wanted, and I was too chicken to modify the firmware on the SPI flash (this was partially because while attempting to sniff the USB protocol in wireshark, LG's updater bricked the monitor, so I had to return that one). So I decided to implement the features by brute force: I found a hidden/factory command that basically copied into memory anything I wanted, which meant I could write my own code that did what I wanted into the scalar CPU's memory. This also has the advantage of wiping itself clean on reboot.
Where I want to go:
I started looking into the possibility of running my panel at 120Hz. The main issue is that I don't reaaaaaaallly understand panel timings that well, but I have a full disassembly of the firmware and I can modify anything in RAM, so I can basically tweak/spoof anything, with some work. I'm curious if anyone else has experience messing with MStar panel firmwares or has an MStar driver board and is willing to also pull apart their firmware.
I recently got myself a DualUp (LG's weird 8:9 display) and got sucked down a rabbit hole trying to get it to switch inputs via DDC/CI. My background is mostly in computer engineering, security engineering, and reverse engineering, so I'm hoping I can get some help understanding panel details.
What I've done so far:
tl;dr, this repo is the current culmination of my work: https://github.com/shinyquagsire23/lg_display_manager
I started by popping LG's OnScreen software (which is used for firmware updating) into Ghidra to figure out where it downloads firmwares. As it turns out, it's pretty basic and I didn't even need Ghidra, I could have just run strings. The firmware is stored at https://lmu.lge.com/ExternalService/ons ... 221219.zip, fetched from a constant URL at https://lmu.lge.com/ExternalService/ons ... ersion.txt . The password was 28MQ780!LGdasusodkug!@#
In the zip were 3 firmwares, NXP, PD and Scalar. NXP is the USB microcontroller that's used to update the scalar firmware (apparently it also handles fans?), and PD is for USB-C stuff apparently. The scalar firmware's name was 28MQ780_MSTAR_MST9W00V4_V3.3.0_0x12FBF031_shad4015bb_220317.bin, which gave me a few more data points to drill into, specifically the chip that's used, the MStar MST9W00V4. Eventually I found this extremely annoying post (https://web.archive.org/web/20230223071 ... /123150496) which had the compiler used for the chip and this page (http://linux-chenxing.org/cpu/aeon.html) telling me that my scalar's CPU architecture was proprietary, but based on OpenRISC. It turned out that the stars had aligned or something and there were no less than 3 people interested in this particular ISA in the last 3 weeks, because someone else had asked about it (https://github.com/linux-chenxing/linux ... ussions/81) and apparently a niche disassembler added partial support for it (https://github.com/uxmal/reko/releases).
I ended up adding support to Ghidra for the ISA (it's still WIP bc there's a handful of unknown/incorrectly guessed instructions left, repo is at https://github.com/shinyquagsire23/ghidra-aeon), and with a bit more decompiling and Github scouring I managed to pull apart and decompress the main firmware binary, so I could actually figure out how the DDC/CI commands even worked.
Long story short, LG did not program the features I wanted, and I was too chicken to modify the firmware on the SPI flash (this was partially because while attempting to sniff the USB protocol in wireshark, LG's updater bricked the monitor, so I had to return that one). So I decided to implement the features by brute force: I found a hidden/factory command that basically copied into memory anything I wanted, which meant I could write my own code that did what I wanted into the scalar CPU's memory. This also has the advantage of wiping itself clean on reboot.
Where I want to go:
I started looking into the possibility of running my panel at 120Hz. The main issue is that I don't reaaaaaaallly understand panel timings that well, but I have a full disassembly of the firmware and I can modify anything in RAM, so I can basically tweak/spoof anything, with some work. I'm curious if anyone else has experience messing with MStar panel firmwares or has an MStar driver board and is willing to also pull apart their firmware.