I have an old DTV converter sitting around gathering dust, so I thought it would be interesting to take a look inside:
As you can see, there’s not much there: a Thomson TV tuner, an IR receiver, 32MB of RAM and a 2MB flash chip (on the underside of the board). What really makes this interesting though is the LGDT1111 SoC; this is a DTV chip manufactured by LG, so it’s a little different than the Broadcom/Atheros/Ralink/etc SoCs found in a lot of other consumer devices. It is very popular with many DTV converters though, so determining its CPU architecture and reversing the underlying firmware could be interesting.
Digging around on the Internet turned up a nice block diagram of the LGDT1111 (courtesy of MVPtek):
The MVPtek web site states that the SoC uses an “AMR926EJ-STM” controller…could they mean an ARM926EJ-STM? Hmmm…
According to the block diagram the LGDT1111 does have a UART connection, and indeed there is a four pin connector on the board above the SoC with the pins nicely labeled:
The serial port settings are 115200 baud, 8 bits, no stop bits, 1 parity bit. Here’s the boot messages that are dumped over the serial connection:
V1.05.40 May 20 2008, 16:24:11 sungwee@sungwee /cygdrive/d/boot_t/src Config Baud Rate : 115200 bps System Clock Rate : 175 MHz U-Boot Mem offset : Text/Data [00e00000, 00e19e9b], BSS [00e19e9c, 00e3e7c3] RAM Configuration: Bank #0: 00000000 32 MB manufature ID : 0xc2, Device ID: 0x49 Flash: 2 MB In: serial Out: serial Err: serial Set Flash Memory Structure... Set Region for Bootrom from 00:00 0x2c000000 (131072bytes) Set Region01 for Appl from 00:05 0x2c020000 (917504bytes) cacheID : 1d0d20d2 write-back, register 7, format C cache separated D-cache 4kbytes 4-way 8 words (32bytes) I-cache 4kbytes 4-way 8 words (32bytes) Masks:: Index: c0000000, Int: 000000c0, Seg: 000003e0 Compare 00e13d8c 2c013d8c Boot from address 2c000000 Boot from flash MMU CR : 000510f8 (00004000)-> 000550fb Processing BIZ file-from Flash: 0x2c020000 Aux data is symbol table(399362 bytes), pSymTab=0x1dfa8c [Application Code] Loading[4] Image from 2c020800 to 00010000(+1512037) -- TRY 0 ==> 2298510 bytes loaded in 0.778 sec, rc=0 -- Checking CRC32[Bin ] ==> Good, in 0.158 sec Moving 7270 symbols(312102 bytes) from 0x001dfa8c to 0x0026d2c4 Load Image to 00010000... Start from 00010000... MMU CR : 000540fb (00004000)-> 000540fa cacheID : 1d0d20d2 write-back, register 7, format C cache separated D-cache 4kbytes 4-way 8 words (32bytes) I-cache 4kbytes 4-way 8 words (32bytes) Masks:: Index: c0000000, Int: 000000c0, Seg: 000003e0 MMU CR : 000550fa (00004000)-> 000550ff [37m[44mnTxtSyms = 7270[0m [37m[44mpSymTabBase = [0x26d2d8..0x2827a0)[0m [37m[44mpSymHashBase = [0x2827a4..0x274470)[0m [37m[44mpSymStrBase = [0x2b0317..0x2ceac6)[0m [37m[44mnDwarfLst = 184[0m [37m[44mpDwarfLst = [0x28607c..0x28663c)[0m [37m[44mpDwarfData = [0x28663c..0x029cdb)[0m 000.025:root ] >> InitPool ]] [0x002cf000-0x01000000] 000.026:root ] SM_MAT_POOL[ 4] = 0x002cf000(0x004000) 000.027:root ] SM_MAT_POOL[ 8] = 0x002d3000(0x00c000) 000.028:root ] SM_MAT_POOL[16] = 0x002df000(0x018000) 000.029:root ] SM_MAT_POOL[32] = 0x002f7000(0x030000) 000.030:root ] SM_MAT_POOL[64] = 0x00327000(0x0a0000) 000.031:root ] >> InitBuddy ]] Addr=0x3c7000, Size=0xc39000 000.033:root ] >> Total Free Heap Size = 0xd05000 Stack... 336860180 0023fa48 New Application booted, uart = 0xfe000000, baud = 115200 [30m[43mSystem Clock : 175MHz[0m Starting V1.6.05 , Jun 25 2008, 21:52:48, from @:/cygdrive/d/Work/Cubic2/Source/TCU/app/D2A1D Start app init task.. AppInitTask: tid 0xd, priority 0x32 App_Initialize Task.. Dmc_Init() Starting MiniShell, priority 8 ... Minishell TID 0x37 (55) running ------------------------------------------- val pad sel : 0x30001d10(0x46fc) ------------------------------------------- ------------------------------------------- val pad sel : 0x30001d10(0x46fc) ------------------------------------------- gpio 6 [GPIO_KP_POWER] reset.. Mini Shell Task Spawned.. Shell> 000.070:tInit ] [30m[43mConfiguring D2A_MODE with CVBS and S-video for LGDT1111T[0m [30m[43mConfiguring D2A_MODE [0m000.070:tInit ] creating Queue tuner0Q ... qid is 0x00240934 000.071:tInit ] creating Queue SqIR ... qid is 0x00240968 000.072:tInit ] 2 Message queues are created 000.073:tInit ] creating Sema4 VDPVSyn ... 000.073:tInit ] creating Sema4 MuteSema ... 000.073:tInit ] creating Sema4 OSDSema ... 000.073:tInit ] creating Sema4 SectFilr ... 000.074:tInit ] creating Sema4 AInfo ... 000.074:tInit ] creating Sema4 VInfo ... 000.074:tInit ] creating Sema4 NvmSem ... 000.074:tInit ] creating Sema4 IR ... 000.075:tInit ] creating Sema4 TIME ... 000.075:tInit ] 9 Semaphores are created 000.075:tInit ] 0 Partitions are created install gpio 1 (group 0, offset 1) isr 105d10 enable gpio group 0 interrupt install gpio 6 (group 0, offset 6) isr 106724 enable gpio group 0 interrupt reboot line successfully set to 'boot flash' Thomson tuner 0xc2 detected DHL_DEV_Init: manufature ID : 0xc2, Device ID: 0x49 vendor: MX, device: 29LV160B DHL_DMX_Init: 000.092:tInit ] >> InitPool ]] [0x01000000-0x01084000] 000.093:tInit ] >> InitBuddy ]] Addr=0x1000000, Size=0x084000 000.094:tInit ] >> Total Free Heap Size = 0xd78bc4 SM_SDEC_POOL inited sdec_io inited PWM inited PSI_InitSF: SDEC isr 0x10, handler changed SDEC GPB IRQ inited /////////////////////////////////////////////////////////////////// ------- Project CB2 ------- - Build date: Jun 25 2008 21:51:18 - BOARD : D2A1T (2) # Board Version : 2 # Kernel : uC/OS-II LGDT1111 1.6.05 - Core Driver version : 0.0 - DSTHAL version : 609181 - FE u-code version : 000 - HDMI driver version : 0.0 # Channel MW : 609181 - EPG MW : 707121 - Caption MW : 0 # Application Version : M5.97A_T 080625A /////////////////////////////////////////////////////////////////// DhlPrintf Sema4 created [APP tInit 13] 0001 debug trace ON DHL_DEV_Init: manufature ID : 0xc2, Device ID: 0x49 vendor: MX, device: 29LV160B [NvRam tInit 13] 0001 FlashNvmInfo: blksz 0x10000-0x20, addr[0] 0x1e0000, addr[1] 0x1f0000 [DMC 0d tIni] 0001 Config:EEPROM size 0 [APP tInit 13] 0001 [APP tInit 13] 0001 .....Loading EEPROM block from FLASH Dump 'EEPROM' 256(0x100) bytes: 00249af0: __ 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00249b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00249b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00249b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00249b30: 00 09 20 03 23 10 00 d1 00 00 00 00 00 00 00 00 .. .#..Γ........ 00249b40: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 ................ 00249b50: 00 00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 ................ 00249b60: 00 00 00 09 00 01 00 00 00 00 00 00 00 00 00 00 ................ 00249b70: 00 00 01 00 00 00 00 00 00 04 00 00 00 00 00 00 ................ 00249b80: 00 00 00 00 00 00 00 3c 00 00 00 00 00 00 00 00 .......<........ 00249b90: 00 00 01 01 01 00 02 09 00 01 00 00 00 00 37 06 ..............7. 00249ba0: 7f 01 00 00 00 00 00 00 00 30 30 30 30 00 00 00 .........0000... 00249bb0: 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00249bc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00249bd0: 00 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .6.............. 00249be0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00249bf0: 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ ................ [APP tInit 13] 0001 Wait to Write SYSDB (After 15min) [APP tInit 13] 0001 Wait to Write SYSDB (After 15min) [APP tInit 13] 0001 [APP tInit 13] 0001 [APP tInit 13] 0001 [APP tInit 13] 0001 ConfigMask is 1663 [APP tInit 13] 0001 [APP tInit 13] 0001 [APP tInit 13] 0001 set rating passwd [APP tInit 13] 0001 Rating 766 condition same [APP tInit 13] 0001 ------------------------------------------------------ [APP tInit 13] 0001 CH 0,0 RF 2 #0, uid 0, ChannelType 0, CableStd 1 [APP tInit 13] 0001 ProgramNum 0, SourceId 0, PID pva: 0x0 0x0 0x0 [APP tInit 13] 0001 Audio vol 9, mute 0x0, lang 0 [APP tInit 13] 0001 TimeZone 1, DST 0 [APP tInit 13] 0001 CC: Active 0, Style 1, Size 1, Src 2, Mode 9 [APP tInit 13] 0001 TxtCol 1, BgCol 0, TxtOp 0, BgOp 0, Edge type 0 col 1 [APP tInit 13] 0001 PenType 0, Author 55, Pos 0, mask 0x67f [APP tInit 13] 0001 ------------------------------------------------------ [APP tInit 13] 0001 Load Air UCM ..initializing crc table.. Current: 'Air' 0-0, RF 2 #0, uid 0 ---- UCM (total 0) [pid:p/v/a hex]---- [DMC 0d tIni] 0001 Notification callback 4f1f4 registerred. [DMC 0d tIni] 0001 cmdChangeDisplay: cid 0 [DHL 0d tIni] 0001 DHL_AV_ChangeVideoFormat(4, 1, 2, 4, 0) VDP_SetOutputAspectRatio: format -1, ar 2 **** vdp arc set: arc 3, zoom 1 **** security not enabled ****
It looks like it’s using a U-Boot boot loader and running uC/OS-II, an open source RTOS. After this there is a lot of debug output as it scans channels for TV stations.
There is an interactive shell available, and typing ‘?’ (no quotes) provides you with a list of supported commands.
The ‘i’ command, displays a list of running processes:
Shell> i MiniShell: [i] call function of '0x000dd3c4' Name TID(Pr) UsPr Stack_Usage State -------------------------- ------- ---- ----------- -------------------- root 0x01 1 62 1286/ 8192 Evt 0, Msg 0 IRTask 0x17 23 40 372/ 8144 Evt 240b08, Msg 0 SysTime 0x20 32 31 327/ 8144 Evt 240ba4, Msg 0 PsipRx 0x23 35 28 293/ 8144 Evt 240d10, Msg 0 AV 0x24 36 27 301/ 8144 Evt 240c40, Msg 0 MainKey 0x26 38 25 1696/32720 Evt 2413f8, Msg 0 t_AuxCC 0x2a 42 21 356/16336 Evt 241120, Msg 0 t_DccDe 0x2b 43 20 317/16336 Evt 2410ec, Msg 0 t_DccDm 0x2c 44 19 353/16336 Evt 241188, Msg 0 t_VbiDe 0x2d 45 18 325/16336 Evt 241328, Msg 0 CC_tTim 0x2e 46 17 328/ 8144 Evt 0, Msg 0 EATask 0x2f 47 16 1370/39952 Evt 0, Msg 0 tDmc 0x30 48 15 1942/32720 Evt 240de0, Msg 0 tEpgSca 0x31 49 14 445/ 8144 Evt 241050, Msg 0 tEpgEvt 0x32 50 13 333/ 8144 Evt 2410b8, Msg 0 tTimer 0x33 51 12 2570/ 8144 Evt 240fb4, Msg 0 App_Tim 0x34 52 11 137/16336 Evt 0, Msg 0 SigMon 0x35 53 10 1752/16336 Evt 2413c4, Msg 0 miniShe 0x37 55 8 9000/16336 Evt 0, Msg 0 idle 0x3a 58 5 336/ 4048 Evt 240830, Msg 0 NwtTask 0x3b 59 4 1056/ 8144 Evt 0, Msg 0 uC/OS-II Stat 0x3e 62 1 105/ 512 Evt 0, Msg 0 uC/OS-II Idle 0x3f 63 0 80/ 512 Evt 0, Msg 0 -------------------------- ------- ---- ----------- -------------------- call 0xdd3c4 result = 0x49 (73)
And the ‘key’ command displays IR codes and their associated actions:
Shell> key MiniShell: [key] call function of '0x00052014' [APP miniShe 55] 4398 -- key string help -- [APP miniShe 55] 4398 00800000 POWER_OFF [APP miniShe 55] 4398 00800001 MUTE [APP miniShe 55] 4398 00800002 CC [APP miniShe 55] 4398 00800003 ALANG [APP miniShe 55] 4398 00800004 SCREEN [APP miniShe 55] 4398 00800005 FAV [APP miniShe 55] 4398 00800006 STILL [APP miniShe 55] 4398 00800007 INFO [APP miniShe 55] 4398 00800008 EPG [APP miniShe 55] 4398 00800009 SRS_MODE [APP miniShe 55] 4398 00800010 UP [APP miniShe 55] 4398 00800011 DOWN [APP miniShe 55] 4398 00800012 LEFT [APP miniShe 55] 4398 00800013 RIGHT [APP miniShe 55] 4398 00800018 VOL_UP [APP miniShe 55] 4398 00800019 VOL_DOWN [APP miniShe 55] 4398 0080001a CH_UP [APP miniShe 55] 4398 0080001b CH_DOWN [APP miniShe 55] 4398 00800020 SELECT [APP miniShe 55] 4398 00800021 PREV_CH [APP miniShe 55] 4398 00800022 MENU [APP miniShe 55] 4398 00800023 HELP [APP miniShe 55] 4398 00800024 DRF [APP miniShe 55] 4398 00800025 EXT_INPUT [APP miniShe 55] 4398 00800026 CH_ADD [APP miniShe 55] 4398 00800027 CH_DEL [APP miniShe 55] 4398 00800028 EXIT [APP miniShe 55] 4398 0080002e ADT [APP miniShe 55] 4398 00800030 0 [APP miniShe 55] 4398 00800031 1 [APP miniShe 55] 4398 00800032 2 [APP miniShe 55] 4398 00800033 3 [APP miniShe 55] 4398 00800034 4 [APP miniShe 55] 4398 00800035 5 [APP miniShe 55] 4398 00800036 6 [APP miniShe 55] 4398 00800037 7 [APP miniShe 55] 4398 00800038 8 [APP miniShe 55] 4398 00800039 9 [APP miniShe 55] 4398 00800043 SLEEP [APP miniShe 55] 4398 00800044 SMART_PICTURE [APP miniShe 55] 4398 00800045 SMART_SOUND [APP miniShe 55] 4398 00800046 CH_BLOCK_EDIT [APP miniShe 55] 4398 00800081 DOT [APP miniShe 55] 4398 00800120 BACK [APP miniShe 55] 4398 call 0x52014 result = 0x1 (1)
There are some other interesting commands sprinkled in there, such as the video_freeze command that allows you to freeze the on screen video without interrupting the audio (an option I couldn’t find anywhere in the menu-driven user interface), or the rating_enable command which allows you to enable/disable the parental content filters without a password (bye-bye V-chip!).
This is all interesting, but if we really want to get down and dirty with this thing we’re going to need some firmware. There are of course no firmware updates for these converter boxes, so instead we’ll remove the flash chip and dump its contents using flashbin and a Gumbi board (raw flash image can be downloaded here):
$ flashbin --chip=mx29lv160 --read=flash.bin Reading all bytes starting at address 0x0β¦ [################################################] 100.00%
All of the strings in the dumped firmware image appear to be related to the bootloader, but a binwalk scan reveals a gzip compressed section of data at offset 0x20800:
DECIMAL HEX DESCRIPTION ------------------------------------------------------------------------------------------------------- 30216 0x7608 uImage header, header size: 64 bytes, header CRC: 0xE15744, created: Sat Jun 20 18:12:44 1970, image size: 14767988 bytes, Data Address: 0xE15790, Entry Point: 0xE157A4, data CRC: 0xE3520001, image name: \341\240@\002\341\240p\003\343\240` 101737 0x18D69 LZMA compressed data, properties: 0x80, dictionary size: 21364736 bytes, uncompressed size: 33554432 bytes 133120 0x20800 gzip compressed data, from Unix, DD-WRT date: Wed Dec 31 19:00:00 1969
Running a code scan with binwalk (option -A) against the extracted gzip contents confirms that it contains big endian ARM instructions:
DECIMAL HEX DESCRIPTION --------------------------------------------------------------- 896 0x380 ARMEB function prologue 1132 0x46C ARMEB function epilogue 1360 0x550 ARMEB function epilogue 1436 0x59C ARMEB function prologue 1464 0x5B8 ARMEB function epilogue 1472 0x5C0 ARMEB function prologue 1544 0x608 ARMEB function epilogue 1652 0x674 ARMEB function prologue 1844 0x734 ARMEB function epilogue 2224 0x8B0 ARMEB function prologue 2292 0x8F4 ARMEB function epilogue 2360 0x938 ARMEB function epilogue 2456 0x998 ARMEB function prologue 2596 0xA24 ARMEB function epilogue 2700 0xA8C ARMEB function prologue 2752 0xAC0 ARMEB function epilogue 2848 0xB20 ARMEB function epilogue 2856 0xB28 ARMEB function prologue ...
Based on this and a quick look at the strings, this is definitely looking like the OS code, so let’s get it loaded into IDA. Based on the boot messages obtained from the serial port, the gzipped data we found at offset 0x20800 gets loaded into memory at 0x10000, which is where execution starts (also note the pSymTab address…this will be useful later!):
... Boot from address 2c000000 Boot from flash MMU CR : 000510f8 (00004000)-> 000550fb Processing BIZ file-from Flash: 0x2c020000 Aux data is symbol table(399362 bytes), pSymTab=0x1dfa8c [Application Code] Loading[4] Image from 2c020800 to 00010000(+1512037) -- TRY 0 ==> 2298510 bytes loaded in 0.778 sec, rc=0 -- Checking CRC32[Bin ] ==> Good, in 0.158 sec Moving 7270 symbols(312102 bytes) from 0x001dfa8c to 0x0026d2c4 Load Image to 00010000... Start from 00010000...
Loading the extracted code into IDA at the offset 0x10000 results in a decent initial analysis:
String references also check out, and we have several promising candidates for common library functions, such as snprintf:
This is encouraging, but with almost 4,000 functions, manually identifying them will take too long. Looking at the strings in IDA, there appears to be a list of strings that correspond to function and symbol names, starting at address 0x222ADF:
Now we need to find out how to correlate these strings to their appropriate functions. The boot messages mentioned a symbol table at 0x1DFA8C, so we’ll start looking there. At address 0x1DFAAC, we find what appears to be a list of symbol structures:
The symbol structure appears to be:
struct symbol { uint32_t func_address; /* Function pointer to this symbol's function */ uint32_t next_func_address; /* Function pointer to the next symbol's function */ uint32_t symbol_name_offset; /* Offset of the symbol name in the symbol strings listing */ };
Applying this structure to the first entry in the above IDA screenshot, the func_address is 0x10000 which is the entry point for our code. Adding its symbol_name_offset value (0x1BAB2) to the address where we found all the symbol strings (0x222ADF), we get: 0x222ADF + 0x1BAB2 = 0x23E591. Here we find the string “start_code”:
This looks good! A quick IDAPython script takes care of renaming all of the functions to their appropriate symbol names:
start_names = 0x222ADF start_addrs = 0x1DFAAC addr = start_addrs symbol_addr = BADADDR while symbol_addr != 0: symbol_addr = Dword(addr) next_symbol = Dword(addr + 4) string_addr = start_names + Dword( addr + 8 ) symbol_name = GetString(string_addr) try: if GetSegmentAttr(symbol_addr, SEGATTR_TYPE) == 2: MakeFunction(symbol_addr) except: pass MakeName(symbol_addr, symbol_name) print '0x%X %s' % (symbol_addr, symbol_name) addr += (4*3)
After running this script, 96% of our functions have been named, including the function we previously identified as snprintf:
Coupling this with the available source code for the uC/OS-II RTOS, we could really go to town on figuring out how exactly this thing works if we were so inclined. But scrolling through the list of functions, one of the function names caught my attention:
App_CheckRemoteBackdoorKey? π
It turns out that this function is called by the MainRemoteKeyTask function, which passes App_CheckRemoteBackdoorKey the infrared key code received from the IR remote control. If one of several special IR codes is detected by App_CheckRemoteBackdoorKey, MainRemoteKeyTask will preform several actions such as providing a service menu, running a factory test, and even performing and over the air firmware upgrade:
These are actually pretty neat little boxes, and there is a surprising amount of potential for customization and modification. I can envision a wireless microcontroller that provides an enhanced user interface via the serial port and can automate commands, such as switching the channel when your favorite show comes on. Unfortunately, DTV reception is terrible here which really takes all the fun out of any cool mods like this. Oh well, I’m off to watch some Netflix.
This was really interesting, thanks.
Pingback: Digital TV converter reverse engineering - Hack a Day
This is incredibly cool! Would love to see more on this box or similar projects
Very cool to see how reverse engineering is done.
Pingback: Digital TV converter reverse engineering | How to
thanks! it’s cool and very interesting π me learning a lot π how long you took to do all these steps?
It wasn’t really high on my (exceedingly long) todo list, so I worked on it on and off. Probably a total of 6 hours or so, most of which was spent playing around on the serial port – there are a lot of commands in there that aren’t very well documented. IDA plus the boot info from the serial port made short work of the disassembly.
Pingback: Digital TV converter reverse engineering
Nice work, very kind of them to leave the serial terminal open.
Also you’ll note that there a JTAG port listed; if this is brought out to the board that’s another port of attack. The ARM9 (and possibly others) have a custom scan chain, into which you can push processor instructions.
This was used in the ‘jtag-arm9’ project (no longer maintained) to write small programs into the internal cache space of a ARM940 board I had…. and could have saved you the need to de-solder the flash to dump it.
Anyway, good job and thanks for the write up.
Yes, I didn’t see any JTAG ports on the board either. They’re probably broken out on some test points or something though.
To be honest, with a cheap hot air gun I’ve found it’s usually faster and easier to just desolder the flash chip and dump it than go through JTAG anyway. Re-soldering is harder, but I do a fair bit of soldering so it’s not that bad. Of course, if I had “proper” JTAG tools like a BDI3000 that may not be the case. π
Very nice work on disassembling and putting together such detailed documentation.
One thing though, Β΅C/OS-II isn’t open source. It is a commercial package with a trial version that comes with source so you can evaluate it. You need to fork out $$$ for a license if you actually want to use it.
Fair point, it’s not OSS. What I meant of course is that the source code is freely available, which is all I really care about since I’m not developing my own system, just hacking on someone else’s. π
This is a standard STM DTV stack. Also name StaFE.
This BSP is given to registred dev team. Please not that the BSP contain mainly an OS + include + some big blobs from ST.
More recent hardware use u-boot + linux BSP + kernel blobs .. check for example sifteam.eu for alternative firmware for new box (STM 710x SoC)..
Bye
Thanks for the info! Would love to check out some Linux based converters…
This is not a STM DTV stack, this chip is from LG and not STM.
STM 71xx SoC are also based on ST40 (SH4) and not ARM9 as in this case.
So what brand name and model number was on this tuner box?
It’s a DigitalStream DTX9950. They’re $60 from RadioShack: http://www.radioshack.com/product/index.jsp?productId=3150939 (or cheaper off ebay).
Did you find any evidence that you might be able to turn it into an SDR radio, similar to rtl-sdr? (http://sdr.osmocom.org/trac/wiki/rtl-sdr)
very cool sir, thank you for this impressive blog post!
Hi Craig,
Great work! You wrote a very good hacking how to! π
U-Boot is open-source, do you know if LG released it source code as GPL license requery?
Pingback: Digital TV converter reverse engineering « My Horizon Wireless
Pingback: KW 31 « ΞΌcpat
Hey! Great post! Great job!
I was doing a similar research several month ago when I was distracted by actual work, so… Thanks for sharing this π
Zuk
How did you work out the serial port settings, just trial and error?
8 bits, no stop bits and 1 parity bit (aka, 8N1) are pretty much the de-facto standard – I’ve never seen a serial port on an embedded device that used anything different (though I’m sure there are some out there that like to be different…).
So the only thing left to identify was the baud rate, and for that I used the baudrate utility which technically is just trial and error, but it makes trial and error a lot easier than doing it in minicom/hyperterminal/etc.
hey!
can you be more specific in the dump flash part?
how did you de-solder the flash?
what hardware did you use?
what software?
how did you re-solder it?
a full tutorial for dumping flash chips will be very appriciated!
thanks!
I desoldered the flash chip using a hot air re-work station.
The hardware used was a Gumbi board, and the software was the flashdump utility that comes with the Gumbi board.
I didn’t bother re-soldering the chip in this case since I didn’t really need the DTV converter anymore. I’ve done this to other devices before though, and found drag soldering to be a great technique for soldering surface mount IC’s.
nice!
any alternative to Gumbi board that i can buy from a shop ?
Yes, there are various commercial products out there, some more expensive than others. Look for ‘usb flash programmer’ or something similar on ebay; just make sure the programmer supports your traget flash chip(s) (the 29XXXXX series are common parallel NOR flash chips).
have you tried any to point me with a link?
also is there a way to dump the firmware on-the-fly? (without the need of desoldering the flash)
thanks for your answers!
I haven’t used them myself, but the Willem programmers are probably the most popular. They usually operate over the parallel port (which is fine as long as you have a parallel port), but there are some USB versions too for a bit more $$.
And yes, usually you can dump the firmware via JTAG or the serial port without desoldering the flash chip. This assumes of course that you can identify the JTAG/serial ports, that JTAG fuses haven’t been blown, that the serial port command line interface allows you to read arbitrary data from memory, etc.
I think this was COOL! I have one of these, a Magnavox DTV TB110MW9 that I wanted to mod, or see if I could install different or newer firmware on. You know, to like improve the UI, and things like that…if someone would be willing to walk me through this, please email me or reply to this comment. Thanks! Again, Cool tutorial/breakdown! π
How exactly do you connect to the serial port and view the console and pass commands to the box? (I actually happen to have the exact same model as you did)
Although mine does not have the socket. It has pads that a socket can be soldered on to, but no socket.
Awww… you’re just showing off. So show me how to connect a hdmi to the inside so I can send the video to all my tv’s on channel 3.
Hi,
Great post! I’m trying to do same with other firmware images but before I want replicate “same” steps you have done here.
I have the latest binwalk version and all auxiliary tools installed. I downloaded your raw image (lg_dtv.bin) and when I execute binwalk, I’m getting this output:
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
81339 0x13DBB Unix path: /cygdrive/d/boot_t/src
81488 0x13E50 CRC32 polynomial table, big endian
101168 0x18B30 Unix path: /cygdrive/d/boot_t/src
131656 0x20248 Unix path: /cygdrive/d/Work/Cubic2/Source/TCU/app/D2A1D, by mkbiz v3.12
133120 0x20800 gzip compressed data, from Unix, NULL date (1970-01-01 00:00:00)
No kernel image neither rootfs founded. Any tip what could be the problem?
Regards,
Any possibility to make this convert digital scanner frequencies to analog frqs? I have 3 analog scanners and would like to get the new digital channels, but this box has outputs for tv ch. 3 or 4! Anyway to convert any incoming signal, then to be tuned to my scanner freqs channels is what I am looking to do. I guess it would have to more broadband than ch. 3 or ch.4. If you have thouhts on another way for me to scan digital freqs I would appreciate the suggestions.