Skip to content

Instantly share code, notes, and snippets.

@throwaway96
Last active July 2, 2024 13:12
Show Gist options
  • Save throwaway96/827ff726981cc2cbc46a22a2ad7337a1 to your computer and use it in GitHub Desktop.
Save throwaway96/827ff726981cc2cbc46a22a2ad7337a1 to your computer and use it in GitHub Desktop.
Enabling debug and getting root on LG webOS by modifying NVM

Warnings

What you do with this information is your own responsibility. If you brick your TV trying this, it's not my fault. You should probably have some electronics experience if you want to attempt this.

This is going to involve opening your TV and attaching wires to the pins of an integrated circuit. If you're not comfortable with that, this is not for you.

This document is a work in progress.

debugstatus

LG TVs since at least the era of NetCast and "Global Platform" (webOS predecessors) have had the notion of a debug level, generally called "debugstatus". There are three modes: DEBUG, EVENT, and RELEASE. TVs normally operate in RELEASE mode. DEBUG mode enables a variety of logging and other debugging features in webOS, including access to the bootloader console and debug menus via serial. EVENT is similar to DEBUG, although it may not enable as much logging and has other relatively minor differences.

NVM

In older versions of webOS, debugstatus is stored in what LG calls "NVM" alongside a bunch of other configuration data, such as the baud rate for serial communications. You can find the relevant structures and enumerations in LG's GPL packages. Of note:

  • debugstatus on webOS: DEBUG is 3, EVENT is 4, and RELEASE is 5

    debug level value (webOS) value (NetCast/GP)
    DEBUG_LEVEL 3 0
    EVENT_LEVEL 4 1
    RELEASE_LEVEL 5 2

    From lg_modeldef.h

  • baud rate: 2400 is 0, 9600 is 2, 115200 is 7

    baud rate value
    2400 0
    4800 1
    9600 2
    14400 3
    19200 4
    38400 5
    57600 6
    115200 7
    460800 8

    SYS_BAUDRATE_T from cmnio_type.h

Although I've seen a default baud rate of 115200 in bootloader code, in practice the default seems to be 9600.

In all the cases I've encountered on webOS, debugstatus is a single byte at offset 0x1a1 in NVM. I'll use 0x1a1 throughout this document, but it may be different for your model. The best way of determining the correct offset is reverse engineering your bootloader (or programs that access NVM such as RELEASE), but the GPL package for your TV model should also provide the necessary information (except for LX SoCs, since lxboot is not open source). After dumping the contents of the EEPROM, you should verify that the structure matches your expectations.

History

Before webOS 5 (released on 2020 models), LG stored NVM in an I²C EEPROM IC. NVM is entirely unencrypted on webOS 3.5 (2017) models. In webOS 4.0 (2018), LG started encrypting debugstatus in NVM, although other config settings remained accessible. In webOS 4.5 (2019), they attempted to obfuscate debugstatus a bit by calling it "Doption". With webOS 5 (2020), NVM was removed and replaced by "bootdb", which is stored in an encrypted eMMC partition named dbboot.

ICs

The ICs I've seen being used for NVM are usually 256Kbit (32Kbyte) in SO-8 packages. Sometimes larger EEPROMs up to 1Mbit are used, but these seem to be mostly on less mainstream products. You may also find I²C EEPROM ICs (potentially smaller ones like 24C08 or 24C02) for HDMI stuff (EDID), which are not relevant here.

Rohm BR24G256F-3

A "4G25" marking (with a lot number underneath) indicates a Rohm BR24G256F-3 (datasheet). (There is also a -5 part, which supports 1MHz operation and more write cycles, but LG seems to use the -3 variant. The differences shouldn't matter here anyway.)

EEPROM IC marked "4G25"
The NVM EEPROM IC on a 43LJ5500-UA board (webOS 3.5; 2017; MStar M2R SoC) marked 4G25.

FMD FT24C256A

I've also seen ICs on LG boards marked "FT24C256A", which are from Fremont Micro Devices (FMD). The marking indicates either FT24C256A-Exx (datasheet) or FT24C256A-Txx (datasheet), although there doesn't seem to be any difference between these parts. (The T and E are supposed to indicate temperature range, but both are -40‒85°C.) I'm not sure whether they're used for NVM.

ST M24M01

The AN-WL100W main board stores NVM on a 1Mbit STMicroelectronics M24M01 (datasheet) EEPROM marked "24H01RP".

Atmel AT24C256C

The AT24C256C I²C EEPROM from Microchip (formerly Atmel) often appears in schematics as an alternative to the Rohm part, and I have seen it on non-webOS boards. Like the others, it's in an SOIC-8 package. The key markings for identifying it are a first line starting with ATML (usually ATMLH followed by three numbers forming a date code) and a second line starting with 2EC. See the datasheet for more information on the markings.

Hardware Requirements

You'll need a test clip unless you want to solder wires directly to the EEPROM IC's leads or otherwise find a way to connect to the I²C bus. Mini-grabbers (random example) may work. The I²C bus may be brought out to an unpopulated connector footprint (or, if you're really lucky, an actual connector) somewhere. There are other devices on the board that use I²C, but I don't know whether they're on the same bus.

Test Clip

A SOIC-8/SOP-8 test clip, such as the Pomona 5250, fits over the IC and provides easy access to the pins. Note that there are much cheaper generic test clips available from the usual sources (e.g., eBay, Amazon, AliExpress).

test clip on 43LJ5500-UA
A cheap test clip on the NVM EEPROM IC of a 43LJ5500-UA board.

Programmer

Any device that speaks I²C can potentially work. For example, a board based on the WCH CH341A or FTDI FT2232H (e.g., FT2232H Mini-Module) should work. An FT232H-based board can work, but note that the pre-2020 version of the Adafruit FT232H Breakout only has a 5V power output pin (see Notes below), although the I/O voltage should be fine. A Bus Pirate should theoretically work, although I had trouble with a Bus Pirate v4; I was able to detect the EEPROM and dump its contents, but the data was corrupted. I switched to using a Raspberry Pi 3 (Model B+), which gave me fewer problems, and ultimately allowed me to sucessfully change debugstatus. I used pins 3 and 5 of the 40-pin header, which are SDA and SCL, respectively. These pins correspond to /dev/i2c-1 in Linux by default.

Serial

Once you have DEBUG, you'll need a way to communicate with one of the TV's serial interfaces: RS-232 on a DE-9 connector or 3.5mm jack (if present), a 3.3V UART, or USB to serial adapter. If you are using a PC, you can accomplish this with a USB to serial adapter. If you're going to use the UART, make sure your adapter is configured to use 3.3V. If you are using something like a Raspberry Pi, you may be able to connect directly to its UART pins, although I haven't tried this. If you want to go the USB to serial route on the TV side, you may need two USB to serial adapters, at least one of which is PL2303-based.

Notes

While the EEPROM ICs themselves will tolerate 5V, you'll be backpowering parts of the board that are expecting 3.3V, so make sure your I²C adapter uses 3.3V.

I²C is pretty tolerant of less-than-ideal connections, especially at the lower speeds in use here.

Apparently at least some models can boot with an invalid or entirely missing NVM EEPROM. (As far as debugstatus goes, it'll default to RELEASE.)

Modification

The general idea is to attach a test clip to the EEPROM IC and use some I²C master device to access it. Then you should:

  1. Back up contents of EEPROM. (You may want to do this multiple times and make sure you always get the same result.)
  2. Make sure the value at offset 0x1a1 is 5. (If it's not, and you're sure you dumped the EEPROM correctly, I'd like to hear about it.)
  3. Write 3 to 0x1a1.
  4. Read the contents of EEPROM.
  5. Make sure everything is the same as before except the byte at 0x1a1 being 3 instead of 5.

After DEBUG

Confirmation

First, you should check that you have DEBUG. You should see this in the Instart menu:
Instart with DEBUG

There are several ways to launch the Instart menu. The intended method is probably via IR (e.g., with a service remote or IR blaster), but you can also use a Luna request. My super hacky SSAP client can send the necessary request. This predefined request should work on webOS 3.0+:
predefined Instart request

The password is almost certainly 0413.
password prompt

Enabling Serial Access

You can use the Instart menu to enable serial access: in System 1 set Baudrate to something sensible (like 115200), and in System 2, set RS-232C Control to On.

Serial

After enabling serial access, you'll need to connect to a serial port. The baud rate will be what you set earlier. Some models have RS-232 on a DE-9 connector, which may work, but most will have a 3.3V UART edge connector (and/or a UART on a 4-pin wafer connector). A potentially easier option is using two USB to serial adapters back-to-back, ultimately connecting from the TV's USB port to one on a PC. You can also connect from any of these options (except RS-232) to a Raspberry Pi via the appropriate pins in the P1 (GPIO) header.

You'll need to connect the GND, RX, and TX pins. (Don't connect anything to +3V3.) Connect the two GNDs first. The RX and TX pins should probably be swapped (i.e., RX on the TV to TX on your serial adapter and vice versa).

Edge Connector

The pinout of the edge connector is:

  1. +3V3
  2. RX
  3. GND
  4. TX

edge connector
UART edge connector.

On the boards I've seen, each data line has a 100Ω series resistor providing a bit of protection, but after that they probably run straight to the SoC, so be careful. The RX line is pulled up to 3.3V with a 10kΩ resistor.

The dimensions of the edge connector happen to match those of a SOIC-8 test clip. With a bit of padding (such as cardboard) underneath the board, a test clip will stay on well enough. If you can't get that to work, it's possible to solder wires to the test pads on the bottom of the board. There's usually a group of four with the same signals as the edge connector somewhere nearby. I'm not sure how they're arranged, so check what pin each one corresponds to with a multimeter.

USB to Serial

You can also use a USB to serial device in one of the TV's USB ports, although only certain types will work. Your best bet is a PL2303-based adapter. Some LG TVs have been known to specifically check for an Aten UC232A, but I haven't had any problems with generic (even possibly counterfeit) PL2303 devices.

Using a USB to serial adapter connected to the TV means you'll likely need another one to connect to your PC. Make sure you remember to swap TX and RX: TX on one goes to RX on the other. Connect the GND pins, but don't connect the VCC/+3V3 pins.

Debug Menu

NOTE: Some LX SoCs prohibit access to certain debug menu commands—including those that open a shell—without AccessUSB authentication. I've also encountered this on an MStar LM15U signage board. These restrictions may be more common on signage (and other commercial) models. There are likely workarounds, but I'm currently unable to help with this.

From the serial debug menu you can spawn a root shell. Press F9 to open the menu, and use the sh command to start the shell. (On newer models, you may just have to press s for shell access. You can usually press h for a list of available keys.)

Root Shell

Once you have the root shell, you need to use it to achieve persistent root access. First, force-enable dev mode by creating a directory named /var/luna/preferences/devmode_enabled. You may have to remove the existing file with that name. Make sure the LG Developer Mode app is uninstalled, or it will cause problems. Once you've created the devmode_enabled directory, reboot so that processes such as the app installer know that dev mode is enabled.

With dev mode enabled, you can install Homebrew Channel. Use the following commands to download and install it:

curl -L -o /home/root/hb.ipk https://github.com/webosbrew/webos-homebrew-channel/releases/download/v0.6.3/org.webosbrew.hbchannel_0.6.3_all.ipk

luna-send-pub -i 'luna://com.webos.appInstallService/dev/install' '{"id":"com.ares.defaultName","ipkUrl":"/home/root/hb.ipk","subscribe":true}'

You'll have to terminate luna-send-pub with control+C when it's done.

Once Homebrew Channel is installed, run its elevation script from the root shell:

/media/developer/apps/usr/palm/services/org.webosbrew.hbchannel.service/elevate-service

Homebrew Channel

General information about Homebrew Channel and root can be found in my crashd guide.

I recommend you block updates using the Homebrew Channel settings (although this is not totally effective). I also prefer to disable telnet, enable SSH, and set up an SSH key.

Older Platforms

Remember that on NetCast and Global Platform, DEBUG is 0 and RELEASE is 2, so you'd be changing 2 to 0.

The board in the AN-WL100W wireless transmitter box has an MStar Saturn7 SoC that runs Global Platform 2 (GP2). The general structure of NVM data is similar to more modern models, but it includes fewer fields. (However, it is on a 1 megabit EEPROM, which probably means it stores unknown other data.) There doesn't seem to be a baud rate setting in NVM. Its debugstatus byte appears to be at offset 0x185, and would be changed from 2 to 0 for DEBUG. I still haven't been able to get any further access, though.

Resources

@FLASH993
Copy link

Thank you. My test clip should be here tomorrow from Digikey, can't wait to get this done.

@Rutge-R
Copy link

Rutge-R commented Mar 1, 2024

Goodluck! Take your time. If you can, test clipping a chip on a spare board if you can. Use your left finder to keep the clip in place when you slowly release your right hand.

@Rutge-R
Copy link

Rutge-R commented Mar 10, 2024

Any update?

@Rutge-R
Copy link

Rutge-R commented Apr 2, 2024

Hi @throwaway96. I have a rooted E7 and C2 LG TV. Rooting the E7 was done to achieve ad-free Youtube and because of a crazy amount of curiosity and determination. Recently I patched my C2 to support the DTS sound format. Trying to patch the E7 I stumbled upon the problem of the RO mounted partitions. The /usr/lib/ directory is among the directories mounted RO. Do you know if and how the partitions can be remounted RW without causing any damage? The outputs of the 'mount' and 'df' command give a clear overview of the mounting schedule, so I know how to address the syntax. I'm just curious if it's something that can be done without causing severe system damage. Thanks in advance.

@kaar3l
Copy link

kaar3l commented Apr 10, 2024

Screenshot 2024-04-10 at 23 52 50
I did read FT24C256A with CH341 programmer. It seems that this has different structure. offset 0x1A1 seems clear?

@Rutge-R
Copy link

Rutge-R commented Apr 11, 2024

You didn't dump the whole ROM. I also had the same results. The small filesize is a sign that not the whole ROM has been dumped.

@Rutge-R
Copy link

Rutge-R commented Apr 11, 2024

These are my notes I have about the ROM dump, maybe it's useful:

  1. 24C256 --> https://github.com/ambujss/rpi-i2c-eeprom
  2. cc -o i2ceeprom main.c 24cXX.c -DC256
  3. ./i2ceeprom /dev/i2c-1 0x50 -a -o rom_dump.bin

@throwaway96
Copy link
Author

Yeah, something is definitely wrong with that dump. It's not even close to what it should look like.

@team-orangeBlue
Copy link

If I have a rooted W18H, can I somehow alter the debugstatus?
Instart grays out the setting (duh).

After all, webOS should know how to decrypt that value and as such I should have some way of tampering with it without too many risks.

@Rutge-R
Copy link

Rutge-R commented Apr 29, 2024

No. I believe debug status is usually done by LG maintenance engineers. The steps on this page are for the WebOS versions prior to version 4, and it's not without any risks.

@ray-duction
Copy link

Hi everyone, i also try to debug my LG tv. I tried to install the webosbrew app with root my.tv. Because the logo of the original YouTube app started to burnin into my oled screen. The firmware was patch but I gave it a try. It did not work and webos became extremely unstable because of the hack. Now I’m trying to get debug status, so i am able to flash the firmware again and install webosbrew this way.

But I am stuck and not able to dump the data from my eeprom. Maybe you guys are able to help me out a bit. Please have a look at the included images. I am also not sure what I do have to edit if and when am able the collect the data from the eeprom value offset is 5 -> write to 3 0x1a1. Also i think the eeprom is 32x (8bit) right.

Thanks upfront, kind regards
IMG_0368
IMG_0369

@ray-duction
Copy link

Hi throwaway96, you are a God among men!

Recap; after getting stuck and not able to dump the eeprom and making too many hours here in the hospital. I put the debug project on hold.
I already installed a second hands mainboard which was on a older firmware - user agreement problem ;( still not able to get root access. But then i saw a PS4 11.00 raspberry pi hack on the web. Because i had a Pi now, i could auto hack the PS4. Lets give that a go ;) After some reading i stumbled on a ps4 hack with LG TV and a new option to Root my LG TV with dejavuln-autoroot:

https://github.com/throwaway96/dejavuln-autoroot/tree/main

Kickass, everything works now. Got two mainboards with root access. The dejavuln exploid also solved all the problems with the original mainboard and i dont have too manual hack my PS4 now on 11.00, because of the raspberry pi

https://www.youtube.com/watch?v=P3v8eHEEyw4

I really appreciate the work you are doing and off cause Jacob Clayden's and PSGO's ,..................work.

Kind regards to all of you. Rayduction

@febman123
Copy link

throwaway, many thanks for this write-up. Just waiting for my bits and pieces to arrive to access the NVM on my 2016 WebOS 3.4 TV. I have a second-hand main board and upon checking it uses the same Rohm IC as above.
Apr 3 - Rutge-R said: Recently I patched my C2 to support the DTS sound format....
Is there any info available on how to do this? I have a rooted C1 that I would like to patch to support DTS but not sure how best to proceed.
Rutge-R / throwaway96 - can you advise?
Thanks

@Rutge-R
Copy link

Rutge-R commented Jun 9, 2024

Hi, Febman. Checkout this page: https://github.com/lgstreamer/dts_restore.

@febman123
Copy link

Hi, Febman. Checkout this page: https://github.com/lgstreamer/dts_restore.

Many thanks. Rutge-R. At long last, My C1 has working DTS sound.

I received my tools to connect directly to the eeprom on my old UH850V and I bought a 2nd hand mainboard from ebay to test on first (hopefully it is working!)

I see the Rohm datasheet for the eeprom mentions using pull-up resistors for the SCL and SDA lines, but the CH341 datasheet appears to state these are built-in to the chip. Has anyone here successfully accessed, dumped and modified the eeprom without using pull-up resistors? I do have an older RPi (2B, I think - it's been in storage for quite a while!). Would this suffice if my CH341 USB adapter does not work, or does it have to be a newer RPi?

Thanks in advance.

@throwaway96
Copy link
Author

throwaway96 commented Jun 23, 2024

@febman123

They're built into the TV board. You would probably be fine with the CH341's on-chip pullups anyway. If there are issues, you can lower the speed.

Any Pi should work.

Note: I recommend performing multiple reads and looking for any differences. In several cases I have encountered apparently random bit flips. I'm not sure whether this was due to poor signal integrity over long cables or other devices on the TV board being backpowered and not held in reset. If you are seeing bit flips, try slowing the clock.

Also: if possible, write only to the byte(s) you want to change rather than rewriting the entire EEPROM. That leaves fewer chances for errors. Verify after writing.

@febman123
Copy link

@throwaway96

Many thanks for your reply and for the advice.

Just fighting with my ch341a USB adapter at the moment. From what I read above I understand that the RPi provided 3.3v to the IC.

When I plug in my adapter to the USB port, it is recognised and the red LED lights up. It is set up for 3.3v output - tested with one of my multimeters.
As soon as I connect the SOIC clip to the Rohm 4G25 IC (made certain of correct connections - VCC, GND, SCL & SDA) and plug in the ch341a to the USB port, the adapter no longer shows up.

I further tested by disconnecting the clip from the IC and the adapter is recognised again by my laptop.

Not sure if I am doing something wrong, if I received a faulty adapter, if the ebay pcb is faulty or if this USB adapter is unable to provide enough power to the IC whilst it is still on the PCB.

If it is the latter, this will have to wait until the middle of next month when I can get my old RPi out of storage.

As you have much more experience than me, just wondering if you have seen this before and what your thoughts are.

Thanks again.

@Denisuu
Copy link

Denisuu commented Jun 27, 2024

I have an LG 42LB630V (2014) running WebOS 1.4.0-2536. I've successfully dumped the firmware from the ATMLH424 chip multiple times using a 3.3V modified CH341A and compared the file hashes. I know what steps to take next, but I can't access the 'In Start' menu.

I have an old Samsung Galaxy S6 with an IR blaster. If I can send the correct code to the TV, I should be able to access it, right? Previously, people used the AnyMote app for this, but it's discontinued, and the .apk no longer works.

Is there another easy way to access the menu and enable serial?

@febman123
Copy link

febman123 commented Jun 27, 2024

@Denisuu

Glad to hear you have been able to successfully access your NVM using a CH341A. Either my adapter is faulty or the chip on my ebay sourced PCB is. I went this route to practice before trying to connect to my TV's chip. I will try with my RPi once I can get to it and that should confirm things either way.

As far as accessing the In Start menu, try this: https://github.com/throwaway96/webos-ssap-web on a computer or laptop on the same network as the TV.
It works for me to access In Start on both my LG TVs but the oldest is 2016, WebOS 3.4. I do not know if it works on WebOS 1.4 but it is worth a try. Read the ReadMe first. Confirm the TVs IP address, enter it into the box in the top-left and click the connect button.

You will know if it works as you will get a pop-up message on the TV asking to grant access. After you click Yes, the TVs screen image should appear in the browser window. The option to access In Start can be found in the bottom left below the screen image, to the right of the keypad. In the drop-down list under 'request', select 'launch factorywin (In Start)' (default selection on mine) and click on the 'Send' button below the payload section. You should get a pop-up on the TV asking for the code: 0413 on my TVs but if it doesn't work for your TV, I have heard some older LG sets used different codes so you may have to search or ask on the WebOS forum.

Before discovering the above I bought a service remote from Aliexpress - cheap and works perfectly: https://www.aliexpress.com/item/1005005914076961.html?spm=a2g0o.order_list.order_list_main.5.1e1f1802td7VLy.

In addition I have a component tester that allows me to capture codes from IR remotes. If you do a search for how to send IR codes on your Galaxy S6, the codes for the In Start key are: UserCode: 04FB DataCode: FB04.
I have not used it myself, but I believe RCoid Free from Google Playstore works with Galaxy phones with built-in IR.

Hope this helps and good luck.

@Denisuu
Copy link

Denisuu commented Jun 27, 2024

@febman123

Thanks for the feedback! I had already used the CH341A on my laptop's EEPROM, so I was certain it should work. I think it's quite decent; it's actually the clip that's terrible, haha. This is the 3.3V mod I used if you're interested: Fixing high voltage bug

I already tried using SSAP-web, but I get the following for 'inStart' and 'ezAdjust':

error: 500 Application error
{"errorCode":-101,"returnValue":false,"errorText":"\"com.webos.app.factorywin\" was not found OR Unsupported Application Type"

Launch softwareupdate (expert mode), does work though:

status: response
{"returnValue":true,"processId":"1001"}

get version info, returns:

{
    "returnValue": true,
    "product_name": "webOS",
    "model_name": "HE_DTV_WT1M_AFAAABAA",
    "sw_type": "FIRMWARE",
    "major_ver": "05",
    "minor_ver": "05.90",
    "country": "omitted",
    "device_id": "omitted",
    "auth_flag": "N",
    "ignore_disable": "N",
    "eco_info": "01",
    "config_key": "00",
    "language_code": "en-GB"
}

I already tested sending a couple of codes to my TV with the irplus Android app, including 0x04FB and 0xFB04, but nothing happens. I'm wondering if my TV even has a service menu or if I need to navigate somewhere first or something like that.

@febman123
Copy link

febman123 commented Jun 28, 2024

@Denisuu

OK, thanks. I will try my CH341A on an old laptop to see if I can confirm whether it works or not. If it does then it must be the ebay PCB. I bought my CH341A recently so it has built-in selectable 3.3v or 5v, verified as working with my multimeter.

Sorry to hear none of it worked for you re accessing In Start.

Perhaps WebOS 1.4 has an alternative way to access In Start, or is pre In Start's inception.

Probably worth asking on the WebOS forum. Someone there is likely to have the knowledge and experience to advise about 1.4.

My limited knowledge is related to my 2 TVs and only goes back as far as WebOS 3.4, which is the one I trying to root via NVM.

Let's hope we both get to root our old TVs!!!

@Denisuu
Copy link

Denisuu commented Jul 2, 2024

@febman123

I posted on the WebOS forum, but there hasn't been much response. It seems either no one knows the answer or the menu doesn't exist, which makes sense since SSAP-web says it wasn't found.

People probably don't even understand why anyone would want to root a 10-year-old TV in the first place, haha.

WebOS Forum Post: Does the 'In Start' menu exist on WebOS 1.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment