The second battery controller I looked at was the Renesas R2J240-10F020. It's a
complete black box with very little information available except for
some outtakes from the datasheet on Chinese developer forums. There is
very little resemblance to the M37512, an older Mitsubishi/Renesas
microcontroller used in earlier battery packs that's fairly well
documented.
The first thing you notice is that this chip has the analog frontend integrated (unlike the M37512 or the bq8030) because there's no separate chip for measuring voltages and such. Cells are connected directly to this chip so it's a one-chip solution for building smart batteries.
SBS Report
$ smbusb_sbsreport
SMBusb Firmware Version: 1.0.1
-------------------------------------------------
Manufacturer Name: LGC
Device Name: LNV-42T4911
Device Chemistry: LION
Serial Number: 41291
Manufacture Date: 2010.01.25
Manufacturer Access: 6001
Battery Mode: e000
*snip*
Probing around
I started out by measuring voltages on all the pins. Just going by logic I was expecting some sort of differentiation on the various sides of the chip.
To summarize my findings after the first pass:
- 1-12 is the "main microcontroller side" has the SMBus pins, VCC (and probably RESET and others)
- 25-36 is connected to current sensing and exposes various built-in voltage regulators
- 37-48 appears to be mainly unused with a couple of pins at 3.3v, GPIO side?
- 13-24 has many pins connected directly to "high voltage" from the cells.
I took a 1k resistor connected to ground and started poking the pins with it to find reset. It should be possible to pull reset low through 1k resistor but unlikely on VCC and it shouldn't lead to a complete reset on an unrelated pin. It's also possible to rule out most pins through visual inspection and measurement. So long story short:
Pin #12 is Reset.
Next I wanted to see if there's something like a Boot pin that's going to get me a different mode when pulled either low or high during reset so I started up a continuous command scan and started poking at the pins again.
Pulling Pin #4 (also connected to Test Point 1 on the other side of the PCB) low during reset gave me this:
$ smbusb_scan -w 0x16
------------------------------------
smbusb_scan
------------------------------------
SMBusb Firmware Version: 1.0.1
Scanning for command writability..
Scan range: 00 - ff
Skipping: None
------------------------------------
*snip*
[f0] ACK, Byte writable
[f1] ACK
[f2] ACK
[f3] ACK
[f4] ACK
[f5] ACK
[f6] ACK
[f7] ACK
[f8] ACK
[f9] ACK
[fa] ACK, Byte writable, Word writable, Block writable
[fb] ACK, Byte writable, Word writable, Block writable
[fc] ACK, Byte writable, Word writable, Block writable, >Block writable
[fd] ACK, Byte writable, Word writable, Block writable, >Block writable
[fe] ACK
[ff] ACK
The chip was ACKing on every command. A deliberate attempt at confusing any would-be attacker perhaps? The write scan however reveals that the chip is actually exposing some real functionality on some of the commands and that a couple of them violate SMBus protocol.
Pin #4 appears to be
BOOT (active-low).
Mapping
Mapping out the protocol took a while especially because it doesn't correspond to standard SMBus protocol but I was eventually able to figure out how to read and write to RAM and erase blocks of memory-mapped flash.
Just writing to the appropriate address in ram (after the flash blocks have been erased) writes the flash memory which is convenient.
There are several partitions of flash mapped into RAM and I'm sure I haven't found all of them. The ones I did are included as address&length presets in the flasher tool.
$ smbusb_r2j240flasher -d eep2.bin -p df2
------------------------------------
smbusb_r2j240flasher
------------------------------------
SMBusb Firmware Version: 1.0.1
------------------------------------
Dumping memory 0x3400-0x37ff ...
Done!
$ xxd eep2.bin
0000000: 0000 0000 0000 0000 0000 ffff ffff ffff ................
0000010: 4c4e 562d 3432 5434 3739 3700 0000 0000 LNV-42T4797.....
*snip*
$ smbusb_r2j240flasher -d eep3.bin -p df3
------------------------------------
smbusb_r2j240flasher
------------------------------------
SMBusb Firmware Version: 1.0.1
------------------------------------
Dumping memory 0xc000-0xdfff ...
Done!
$ xxd eep3.bin
0000000: 0100 0700 b801 b801 1100 0203 0201 01e3 ................
0000010: e6fe e3ae 7000 e0e4 0cc8 0038 3150 14f0 ....p......81P..
0000020: 1530 2a4c 4743 0031 3100 0000 0000 0000 .0*LGC.11.......
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000040: 0000 004c 4e56 2d34 3254 3439 3131 0000 ...LNV-42T4911..
0000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000060: 0000 004c 494f 4e01 2d01 2d30 07fa 1031 ...LION
*snip*
In this particular battery pack the static information was stored in df3 and the dynamic in df2, df1 was empty.
Another battery stored dynamic info in df1 so this is going to differ between firmwares/packs.
Just like the bq8030 the static area is protected by a checksum on this controller/firmware as well. I took a shot at it just for kicks and it was pretty simple so I included it in the flasher tool.
$ smbusb_r2j240flasher -w eep3_f.bin -p df3 --fix-lgc-static-checksum --execute
------------------------------------
smbusb_r2j240flasher
------------------------------------
SMBusb Firmware Version: 1.0.1
------------------------------------
Erasing flash block starting at 0xc000 ...
Done!
Fixing LGC static checksum..
Done!
Writing memory 0xc000-0xdfff ...
Done!
Verifying 0xc000-0xdfff ...
Verified OK!
Exiting Boot ROM and starting firmware.
$ smbusb_sbsreport
SMBusb Firmware Version: 1.0.1
-------------------------------------------------
Manufacturer Name: LGC
Device Name: Karosium000
Device Chemistry: LION
Serial Number: 41291
Manufacture Date: 2010.01.25
*snip*
Reset
Pretty much the same procedure as with the bq8030. Map and modify the dynamic area. Eventually you'll find the error flag. As with the bq8030 the dynamic area isn't checksummed in this controller/firmware either.
Helpful tips:
- Again, multiple log entries. The number of 0x00 bytes at the beginning of the section determine the number. Patch the duplicated data in all of them.
- You can decrease the number of log entries to 1 for the time of mapping which will make the job a lot easier.
- The real cycle count is stored encoded. No idea how. With this particular firmware it was at 0x78-79. Zeroing out the bytes still decreases the cycle count to 5 but the precise algorithm/obfuscation? No clue.
- Please don't ask me to fix flash dumps :-)
- Good luck!
Notes
No disassembly/ler for this chip. I don't really know what architecture it's based on. If I had to guess I'd say an extended version of the MELPS 7700, an old Mitsubishi architecture that Renesas inherited because trying to load it up in IDA with that core seems to produce something that starts to make sense but fails on invalid instructions. I could be completely wrong though.
If anyone wants to tackle this they could probably find a nice, easy way of getting into the Boot ROM using just SMBus commands.