Sunday, August 28, 2016

Hacking the bq8030 with SANYO firmware

As mentioned in the previous article the bq8030 is the blank version of the bq20z90. If you bought some from Aliexpress they'd come up with the TI Boot ROM and you could use the flashing tool included in SMBusb to upload firmware and eeprom(data flash) to it.
Theoretically you could turn it into a bq20z90 by downloading the firmware from one and uploading that. (The procedure for accessing the Boot ROM on those chips is documented in datasheets and application notes.)



So how would you even start with a BQ8030 running proprietary firmware?

Google. Lots of Google.
Apparently they sell this tool for them::




Now with a SPECIAL! price of ONLY 3 THOUSAND US DOLLARS!! WHAT AN AMAZING DEAL!!!

I gathered everything I could find about this device and while it wasn't much it did provide clues that came in handy later on in the process. Especially this screenshot of the software that comes with it:




There was no way I could figure everything out based on just that but I did take notice of the function bar on the bottom.

Those could very well be SMBus commands right there.. would they have done that? Surely not.
Not really expecting much I tried a word write of 0x0214 to command 0x71 aand.. nothing obvious happened. So I moved on to poking at other things but eventually came back for a second look and that's when I realized:

Command scan starting at 0x70 before sending command

$ /smbusb_scan -w 0x16 -b 0x70
------------------------------------
             smbusb_scan
------------------------------------
SMBusb Firmware Version: 1.0.0
Scanning for command writability..
Scan range: 70 - ff
Skipping: None
------------------------------------
[71] ACK, Byte writable, Word writable
[72] ACK



And after


$ smbusb_comm -a 16 -c 71 -w 0x0214 
$ smbusb_scan -w 0x16 -b 0x70
------------------------------------
             smbusb_scan
------------------------------------
SMBusb Firmware Version: 1.0.0
Scanning for command writability..
Scan range: 70 - ff
Skipping: None
------------------------------------
[71] ACK, Byte writable, Word writable
[72] ACK
[73] ACK


So this actually unlocks an extra command which disappears again when an SBS command is issued (or when doing a full command scan starting from 0.)
The command however is not writable. Reading it returns:

$ smbusb_comm -a 16 -c 73 -r 2
023d

Interesting but insufficient.

Brick wall meet impatience

I couldn't really get any further with just that information so I started looking at the hardware instead. Having found slides from a TI presentation revealing the connection between the BQ8030 and bq20z90 I opened up the datasheet for the latter (since there's no public datasheet for the former).


Ok, nothing straightforward. No obvious BOOT pin as one would expect with a device that's not meant to be tampered with. But maybe pulling some pin high or low during reset will get me somewhere.

After the first pass no, not really. So maybe we have to set multiple pins into multiple states for it to work. Or maybe there's no such combination at all.
How about I try to abuse N/C pins instead. I have no logical explanation as to why I came to this decision. Maybe I saw a presentation somewhere about blackbox chips and N/C pins years and years and years ago but I could just be imagining things. Either way, about 5 minutes of poking at PIN #28 with a resistor connected to 3.3v in hand and triggering RESET at random intervals while running a continuous command scan:

$ smbusb_scan -w 0x16
------------------------------------
             smbusb_scan
------------------------------------
SMBusb Firmware Version: 1.0.1
Scanning for command writability..
Scan range: 00 - ff
Skipping: None
------------------------------------
[0] ACK, Byte writable, Word writable, Block writable
[1] ACK
[2] ACK
[3] ACK
[4] ACK, Byte writable, Word writable, Block writable
[5] ACK, Byte writable, Word writable, Block writable
[6] ACK, Byte writable, Word writable
[7] ACK, Byte writable, Word writable
[8] ACK
[9] ACK, Byte writable, Word writable
[a] ACK, Byte writable, Word writable


Wow, that worked?
Umm.. ok.. let's just reset for now..

$ smbusb_sbsreport
SMBusb Firmware Version: 1.0.1
-------------------------------------------------
Manufacturer Name:          ERROR
Device Name:                ERROR
Device Chemistry:           ERROR
Serial Number:              4294967287
Manufacture Date:           1980.00.00


Uh-oh.. Well that's not good!
It seems we're stuck in the Boot ROM. Is the chip fried? It's at this point that I coded up the flash tool to try and read the flash contents. (I wasn't really bothered by the chip dying as this was one of 2 sacrificial controller boards I kept just for messing around with.)
And the results? Apparently we can corrupt (ideally just) the first couple of blocks of flash if we bully PIN #28 while the chip is trying to start up. The good news though? (If we're lucky) We get 99% of the firmware, and thanks to Charlie Miller we have a disassembler(zip) for it.

Did messing with Pin #28 even have an effect? Could it just have been the erratic resetting of the chip that triggered the malfunction? Did I short VCELL+ to Pin28 while messing about? Was there high voltage on VCELL+? Was it just ESD?
No idea. But I did manage to reproduce the result on another chip using the same procedure. So when in doubt and you have nothing to lose, act like a caveman, I guess?
The only good thing about this method is that even if you have 0 knowledge about whether there even IS a method for entering the Boot ROM in the firmware let alone what it is there's still a high chance that you'll get in. How much of the firmware survives is another question.

Disassembly

A couple of hours of staring at unfamiliar assembly code later, here are the relevant parts for entering the Boot ROM with annotations:

cmd_handle_71
    ..      
    calls       smb_ACK
    ..
    calls       smbSlaveRecvWord
    move        a, (i3,0x1A)
    or          a, (i3,0x1B)
    jeq         check_71_pass
    move        r2, (i3,0x1B)
    add         r2, (i3,0x19) ; smb_word_LSB
    move        r3, (i3,0x1A)
    addc        r3, (i3,0x18) ; smb_word_MSB
    or          a, r3, r2
    jeq         accesslevel_oreq_40
    move        a, #0
    move        (i3,0x1A), a
    move        (i3,0x1B), a
   
check_71_pass:
    ..
    move        i1l, (i3,0x19) ; smb_word_LSB
    move        i1h, (i3,0x18) ; smb_word_MSB
    cmp         i1h, #2
    jne         wrong_pass
    cmp         i1l, #0x14  ; is 71 0214?
    jne         wrong_pass
    ..
    jeq         accesslevel_oreq_80


This is the first password check, seem familiar? It's the one that we saw in the screenshot above 0x0214 to 0x71. It sets an access flag that gets checked later on. Basically if (smbSlaveRecvWord(0x71) == 0x0214) { access_level |= 0x80 }; But wait.. It can set two access flags based on whatever (i3,0x1A) and (i3,0x1B) are. Hrmm.. Well I don't know what those are and can't find where they're set so let's assume the first jeq will not jump once we've given the correct first password because it would make sense. We can also see that it checks the word we send against those mystery bytes somehow and if it likes what it sees it sets access flag 0x40 and the mystery bytes to 0.

A little bit further up we find the entry point for the Boot ROM:

cmd_handle_70:
    *snip*
    move        r3, access_level
    and         r3, #0x40
    cmp         r3, #0        ; don't even bother if access
    jeq         cmd_handle_71 ; flag 0x40 is missing          
    *snip*   
    calls       smbSlaveRecvWord
    move        r2, (i3,0x19) ; smb_word_LSB
    move        r3, (i3,0x18) ; smb_word_MSB
    cmp         r3, #5
    jne         wrong_pass
    cmp         r2, #0x17      ; is 70 0517?
    jne         wrong_pass
    *snip* (prepare leaving the firmware safely)
    calls       bootrom_execute

So now we know pretty much what we need to do.

1. Send 0x0214 to 0x71
2. ???
3. Send 0x0517 to 0x70
4. Profit

And we've made the educated guess that Step 2 is really "Send 0x???? to 0x71" so we're pretty much done with the disassembly as 16 bits is way within the realm of bruteforceability and since I had another sacrificial board as well as a battery pack running SANYO firmware I had everything I needed to attempt it.
As it turns out there's another mandatory step between 1 and 2 and it was sheer luck that I left it in my brute force loop. 0x73, the command unlocked by sending the first password needs to be read before entering the second password. Which is...*drumroll*

0xFDC3

After realizing that the first unlocked command is important (why else would they have made it mandatory otherwise) it's not that surprising that when adding the number returned by it (0x023d) to the bruteforced value we get a nice round result: 0x10000 which is probably what the adding in the assembly and the mystery numbers are all about.

So to sum it all up:

1. Send 0x0214 to 0x71
2. Read Word X from 0x73
3. Send (0x10000 - X) to 0x71
4. Send 0x0517 to 0x70

Actually, sending the correct word in Step 3 will unlock several extra commands not just 0x70 for the BootROM entry but they all disappear as soon as you send an unrelated command much the same way as 0x73 does with the first password.

We don't really care about those though because we already have what we wanted:

$ smbusb_comm -a 16 -c 71 -w 0214
$ smbusb_comm -a 16 -c 73 -r 2

023d
$ smbusb_comm -a 16 -c 71 -w fdc3
$ smbusb_comm -a 16 -c 70 -w 0517

$ smbusb_bq8030flasher -p prg.bin -e eep.bin
------------------------------------
        smbusb_bq8030flasher
------------------------------------
SMBusb Firmware Version: 1.0.1
PEC is ENABLED
TI Boot ROM version 3.1
------------------------------------
Reading program flash
.............................................................
.............................................................
*snip*
.................................................
Done! 
Reading eeprom(data) flash
...................................................
Done!

$ xxd eep.bin
0000000: ffff 0031 076c 00c8 ffff 11f8 19e0 0355  ...1.l.........U
0000010: 0853 414e 594f 0030 3820 20ff ffff 0407  .SANYO.08  .....
0000020: 0b49 424d 2d34 3254 3532 3531 2020 2020  .IBM-42T5251   
0000030: 044c 494f 4e20 ffff ffff ffff ffff ffff  .LION 

*snip*


Huzzah!


Reset


To actually remove the permanent failure flag we need to look at the eeprom area.
The file is 2048 bytes and it has two sections.

The first 1024 bytes contains the static data (the beginning of which you can see in the hex dump above). It contains all the data set by the manufacturer that never changes during the lifetime of the battery. Design capacity/voltage, serial and model numbers, default settings, etc.
This part is protected by a checksum somewhere which you'll need to find and fix if you want to modify anything in there.

The second part contains the dynamic data. Basically the "log" of the battery with current remaining capacity and similar things that get updated as the battery is cycled.  Also, the failure flag.

You pretty much just need to start mapping out the values and then zeroing or FF-ing out the ones that you can't map to anything to see if that fixes it or breaks something else. There's no checksum on the dynamic area so you are free to modify this section all you want. Repeat until desired outcome is reached. That's what I did.
Some helpful tips:
  • On my specific battery the log starts at 0x500 and has several entries that all need to be modified (mostly duplicate data)
  • Battery capacity is stored as the remaining capacity reported through SBS divided by 2.
  • Cycle count is stored as CycleCount-1 (eg.: SBS value: 223, Eeprom byte: 222)
  • Remaining Capacity Alarm is stored as-is. A good place to start mapping.
  • It's a good idea to reset the cycle counter. I don't want to start conspiracy theories but... at least with this specific model there's been a lot that died inexplicably around the 200 cycle mark. Coincidence? Probably, but it can't hurt.
  • Please don't ask me to fix eeprom dumps :-) 
  • Good luck!
And the result:


It took the estimate a charge cycle to normalize. This particular battery lasts 2 hours on constant high CPU load after external recharging and clearing of the fail flag. Not bad for a 10 year old battery in a 12 year old machine and since the other choice was THROW IT AWAY AND BUY A NEW ONE  I consider this a win :)

87 comments:

  1. It was such a pleasure to read this! Thanks for posting it.

    Secret hacking recipe: "How about I try to abuse N/C pins instead."
    :o)

    ReplyDelete
  2. I've always wondered how boot ROM is loaded onto these chips in the first place. If one can overwrite the gauge chip with a custom boot ROM, wouldn't that allow loading arbitrary firmware?

    Also, do these chips have a JTAG interface that will allow for easy uploading/downloading of the firmware?

    ReplyDelete
    Replies
    1. There wouldn't be a need to mess with the boot rom if this low-level programming access was available. Could just use it to manipulate the other parts directly :-) But for all we know the boot rom could be stored in actual mask ROM on the chip, never to be changed.

      I wouldn't be surprised if there was some sort of hardware-level programming interface that they use to upload the boot rom in a manufacturing step but there's no way of knowing what/where it is or whether it was permanently disabled afterwards or not (that I know of).

      Delete
  3. Hi. Good job. I would like to ask You, maybe someone knows how to unlock charging in dell batteries with external power supply ? I know dell batteries must have 100 ohm resistance from GND to SYSpress pin, discharge works, but charge not. Maybe someone knows smbus command to unlock charge ?

    ReplyDelete
    Replies
    1. No clue, sorry. I haven't worked on them and Dells seem to be one of those packs that have "special" firmwares based on screenshots from payware battery hacking software. Honestly if you're not hell bent on not paying a cent to anyone like I was you're probably better off finding a local re-celling business. Good luck!

      Delete
    2. Hi. It is possible. Just send to manufacturrer access comand 0x108 in hex

      Delete
  4. Hi,

    I found this blog using Google after scratching my head over a few days.
    My ThinkPad T430 battery has gone kaput. I disassembled the battery. The cells is good, each holds a charge of 3.9V but there is no output on the battery header (7 pins).
    My guess is the controller chips seem to think that it's time to declare death to my battery.
    How to reset this controller chips? Is it even possible to write a new firmware to these chips so they will accept to work again?
    I see a bd8030A and bq29330 chip.
    Below is pictures of my actual battery, disassembled.
    imgur.com/a/8IJi2

    ReplyDelete
    Replies
    1. The method described in the article above should work with that pack, yes. Some experience with electronics and reverse engineering binary data files is required. The article about fuses (sidebar, 2016, September) is also relevant. I can't offer any assistance beyond that. Good luck!

      Delete
  5. Very good job!
    I have here battery from Thinkpad Edge E520 which is working, but have low capacity. I want to try change cell for new Sanyo NCR18650GA 3500mAh and change FW to the right capaity.
    I hope that it will be success, I never tried play with laptop batteries chips :)

    ReplyDelete
    Replies
    1. I hope so too! Let me know how it turns out.

      Delete
  6. Hi, nice guide; I'm trying this out on some old X61 batteries
    I read out the eeprom and flash areas successfully, but when I do sbsreport subsequently I'm stuck with the error messages (with the date at 1980 etc, as you had above). How do you reset that?

    ReplyDelete
    Replies
    1. Hi,

      Did you try "smbusb_bq8030flasher --execute" ?

      Delete
  7. Hi Victor.
    I try to recover my dell battery. It has bq8050 on a board. And I have a question, how do you able to get a software from Bq8030 before disassembling a code? I don't understand, how do you know about 0x0214 password and I fully not understand 0xfdc3... Thank you!

    ReplyDelete
    Replies
    1. I have no clue about the bq8050 so keep in mind that it may not be compatible with the tool I've released. Also keep in mind that this bootrom entry method is SPECIFIC to the Sanyo firmware. Dell likely has their own custom firmware even if the cells used in the pack are Sanyo based on what I've seen in payware battery hacking software so this method is unlikely to work.

      On to the questions:
      It was possible to glitch the bq8030 into clearing the first block of program flash hence ending up in the boot rom "permanently". The method is written in the article. You will not be able to recover the chip after this without an intact firmware image so I wouldn't try it if you only have one battery and also YMMV. I had several controller boards to sacrifice so I didn't care. Once you're in the boot rom you can read the (corrupted, first block missing) firmware and since you're only missing initialization code at the start you can still disassemble this to extract the password(s) that you can then use on other batteries. Password #3 was brute-forced as I've also written. This was done with a one-off tool that isn't included on github. From there it was guesswork to arrive at the significance of the value read from 0x73 and the final password but the correctness of this has since been confirmed by others.

      Delete
  8. Hi Viktor,
    You have done amazing work! Also very well presented!
    I'm waiting for the adapter board to try to mess around with my battery :)
    Thank you very much for sharing it!

    ReplyDelete
    Replies
    1. Hey, glad you found it interesting!

      Delete
    2. Hi Viktor,
      I received the adapter yesterday and managed to patch capacity and cycle counts in my battery.
      The problem with my battery is that I installed 4.2V cells instead of 4.3V. There're values in the first 1024 bytes of the eeprom that looks like 4300 and 12900 and I would like to try to adjust them, but I need to figure out where is the checksum and how to recalculate it. I would be easier to do having several eeprom dumps. Can you share your eeprom dump?

      Delete
    3. Shoot me an email :-) (search for "Contact" on the page)

      Delete
  9. I was just wandering is it possible to communicate with the battery using internal laptops i2c (SMBus)?
    Linux has userspace utilities i2c-tools. Is it possible to access installed battery's rom/eeprom from a running system?
    Thanks!

    ReplyDelete
    Replies
    1. AFAIK you can't access the EC's SMBus through the machine. The EC manages the bus by itself and only provides an abstracted interface that's accessible to drivers. It might be technically possible but ECs are similar to battery controllers in that you'd have to find and reverse engineer this functionality on each and every one of them and I don't see EC i2c bus drivers in the linux kernel tree. I could be wrong though but that's my understanding :-)

      Delete
  10. Hello how are you. Congratulations on the post.
    I have a lenovo battery with two IC (1: BQ8030BT, 2: BQ29330). When replacing the cells, the cali bration data and the serial number were lost. The computer recognizes it, but even though it has a load it says "0% and loading".

    I am programmer and I have done things in electronica, I have eeprom programmers, I would be grateful if you could tell me how to recover the firmware data.

    thank you very much, Diego

    ReplyDelete
    Replies
    1. Hi,

      The serial/model number and basic factory calibration are usually in the static area. There really isn't a way for them to go away unless your data flash area is corrupted but then the whole pack would just stop working.

      I can't help with individual cases I'm afraid. I could give you a couple of hints if you posted an smbusb_sbsreport of the pack but that's about it.

      Good luck!

      Delete
  11. Hi, I'm working on a DELL battery with TI chip BQ30423. Do you think if it can be hacked? With this tool? Or I have I2C analyzer.

    Thanks in advance.

    ReplyDelete
    Replies
    1. No clue, sorry. I haven't worked on them and Dells seem to be one of those packs that have "special" firmwares based on screenshots from payware battery hacking software. Honestly if you're not hell bent on not paying a cent to anyone like I was you're probably better off finding a local re-celling business. Good luck!

      Delete
  12. Hi Viktor, interesting article and good job carried out!

    You mentioned about series cases with that kind of batteries where they failure to work after reaching 200 cycles of charges. It was just an assumption.

    After you make possible to modify dinamic area of eeprom, Did you play around with that counter value? You mentioned that you just reset it, but if you set it to 195 for example and making 5 to 10 discharge cycles it become possible to confirm or not a manuf.consp theory;)...

    Can you do this trick and share us the output...

    ReplyDelete
    Replies
    1. Hello,

      Glad you found it interesting!

      I didn't do anything like that, no. That particular pack was fairly weird in that it was basically two batteries in one and the firmware "bank-switched" between a 4cell 18650 and a 4cell flat-cell (which had an obscure model number which I forgot) pack. I was pretty much joking about the the conspiracy stuff ;-) If anything it's way more likely that 200 cycles is about where this whole bank-switching business catches up with the amount of cleverness they had to put into the firmware to make this pack work.

      I no longer own the machine or the battery so I can't do any more experiments on it unfortunately.

      Delete
  13. did you replaced battery elements as well, or just cleared PF and CC flags?

    in case elements replacing its required to do calibration for new elements by changing some data flash fields like battery chemistry, design capasity and so on. Its quite easy with TI bq Evaluation Software using their EV2300 usb board. But how to do this using SMBusb? how to find (map) eeprom fields relevant for that calibration?

    Thanks for replies

    ReplyDelete
    Replies
    1. I recharged the original cells externally and cleared the fail condition, no re-celling.

      It sounds like you're talking about the calibration values in the static area. I don't think they're as much for the cells as they are for the board/pack configuration. If you replace the cells with new, identical capacity ones then you can leave the static calibration alone and just raise the Full Charge Capacity values in the dynamic area back up to the Design Capacity(+~15% since with new cells you'll probably be over the design capacity and the controller likes adjusting downwards more than up). The controller should then re-learn the actual capacity in a charge cycle or three.

      If you want to re-cell with different capacity cells than what the pack was designed for THEN you'd need to poke at the static calibration. That area is checksum protected and I haven't really looked into it.

      Delete
  14. Have you encountered with 4s delay while brute force the unknownhalf of password. It's not clear in the disassembly any related code for delays.
    Or Sanyo doesn't implement this technique?

    Me now trying to get into bq20z90 controller but chip is sealed. Default unseal key found on TI support page seems to be changed by pack manufacturer. On one freek forum me found suggestion to use external trigger/multivibrator on reset pin of bq chip to increase brute force attempts. How do you think is it good idea ? And have you ever deal with sealed bq20z90 with ti firmware? Are their bqStudio and EV2300 able to unseal their own sealed micros? Thanks

    ReplyDelete
    Replies
    1. I was able to run bruteforce loops on the bq8030 without needing to add any delay. Once I got the sequence of commands right it "just worked". That said, as you know, that isn't the TI firmware. I actually never worked on that at all.

      Resetting them is pretty safe in my experience though so if I was dealing with a delay I'd probably try going that route. Maybe hooking up the reset to a GPIO on the SMBusb board and adding the functionality to the library.

      I think bqStudio would just prompt you for the password as well.

      Delete
  15. do you remember, after resetting bq's chip, whether controller goes into active status or so called shutdown one? the latter require applying external source voltage to '+,,,-' output pins of pack to bring it into operational status again. It's need for correct implementation of 'bruteforce loop with reset'.

    ReplyDelete
    Replies
    1. I don't think any of the batteries I've worked on required me to do that. Once the firmware started up with the correct data they just started working.

      Delete
  16. Hello, I am new in this programming. After couple of evenings I managed to build the libraries. But I dont understand how to put the firmware to the cypress board. I also get an error seen below.

    $ smbusb_scan -a
    ------------------------------------
    smbusb_scan
    ------------------------------------
    Error Opening SMBusb: libusb error: -1

    How to figure out with this error?
    I am using Linux ubuntu.

    ReplyDelete
    Replies
    1. Hi, Firmware is uploaded automatically to the ram of the microcontroller. -1 error pretty much translates to "can't find/open interface". What you do get for lsusb?

      Delete
  17. Lsusb, i will get "Bus 001 Device 010: ID 04b4:8613 Cypress Semiconductor Corp. CY7C68013 EZ-USB FX2 USB 2.0 Development Kit"

    ReplyDelete
    Replies
    1. Looks correct. Any errors in dmesg? Did you build the latest commit or the release? Did you try running the tool as root to rule out permission issues?

      Delete
    2. Got it to communicate. Problem was with permissions. Tried with root and it works. Thank you for your help.

      Delete
    3. How to bruteforce the value I get with "smbusb_comm -a 16 -c 73 -r 2". Because I will get the value 062f.
      So the third step command will be different I guess?

      Delete
    4. Quote: "3. Send (0x10000 - X) to 0x71"
      0x10000 - 0x062F = 0xF9D1 so:
      smbusb_comm -a 16 -c 71 -w f9d1
      smbusb_comm -a 16 -c 70 -w 0517
      If that doesn't work then your firmware has a different protection scheme...

      Delete
    5. It worked. Got the bin files from battery. What kind of hex editor do you use? Seems that mine does decode it different. There are lots of dots and symbols, only few words similar with what i see with smbusb_sbsreport.
      Txt file what I see - https://www.upload.ee/files/7714349/eeprom_hex.txt.html
      eeprom file - https://www.upload.ee/files/7714360/eep.bin.html

      What for is the prg.bin ?

      Delete
    6. Good to hear! The file seems correct to me. It's not the hex editor. You should look into how computers store numbers. Binary and hexadecimal numbers, byte order and so forth. There are resources out there but unfortunately I can't help you with that, Google is your friend.

      prg.bin is the firmware

      Delete
  18. I accidentaly deleted the firmware from the chip, but flashing prg.bin there comes an error
    Erasing program flash
    Done
    Flashing program flash
    Error:-11

    Is there any place where are all the smbus error codes?

    ReplyDelete
  19. For unknown reason I wanted to flash eep.bin and prg.bin together. It deleted the firmware from the chip and got an error -11. Now scanning gives me result [16] ACK [17] ACK
    smbusb_scan -w 0x16
    [35] ACK, Byte writable, Word writable
    [37] ACK, Byte writable, Word writable, Block writable
    [39] ACK, Byte writable, Word writable

    nothing above 70 anymore. Is the chip bricked now?

    ReplyDelete
    Replies
    1. Do the flashing tools still work? If yes then you're stuck in boot-rom. Try flashing the firmware again. If not then pretty much yes. Error -11 there is a libusb error. The weird thing is that it's LIBUSB_ERROR_NO_MEM = -11 so.. Insufficient memory... I have no idea how that could've happened.

      Delete
    2. Unless you legit ran out of ram at the worst possible time because maybe you installed everything in a live environment? That may or may not have happened to me before :-)

      Delete
  20. May be USB board is of simplified version?

    It was reported "CY7C68013 EZ-USB FX2 USB 2.0 Development Kit" by lsusb,
    so without index 'A' and 'P' for the chip and board accordingly.

    ReplyDelete
    Replies
    1. Mine's the same string, it's not that.

      Delete
  21. And some new command reaveled? [35],[37],[39]
    Seems like intermediate access level.
    Viktor, did you saw these commands while got in bootrom?

    May be trying to read them will show some interesting?

    ReplyDelete
    Replies
    1. No idea whatsoever, I haven't saved scan results :-)

      Delete
  22. Hi Viktor!

    coming back to our discussion regarding resetting the bq controller,

    /q
    >Resetting them is pretty safe in my experience though so if I was >dealing with a delay I'd probably try going that route. Maybe hooking >up the reset to a GPIO on the SMBusb board and adding the >functionality to the library.
    /q

    me have some questions about implementing that in practice.

    In order to add this functionality to FX2LP it is required to add new function to bitbang the output pin i.e. PB0.
    Is it sufficient to edit/modify some sources/header files from project package, or it will require redesigning firmware from thescratch using Cypress SDK?

    Another question is about so called 'partial reset' of the controller.
    I found in the datasheet for bq20zxx small quantity of information about this kind of reset, and even dedicated counter in the dinamic eeprom field allotted for this. May be you know some idea on how to triger that one without a full reset. May be buffer overflow or other tricks will work? Just to check which kind of reset will perform faster for bruteforce loop.

    ReplyDelete
    Replies
    1. FX2LIB should provide that functionality in the form of having a #define for the port's registers. You may want to set that port's pin to an input when you don't want to keep it at a certain state (ie. you just want to let the controller run) and set it to an output with a low state asserted to reset it. This should all be simple bitwise manipulation of the control registers. The datasheet of the micro should help. (Note: I haven't actually tried any of this, it just usually works like this)

      I have no idea what a "partial reset" is according to TI, unfortunately... and the public datasheet isn't helping :/

      Delete
  23. Viktor, have you figured out how much bytes of firmware was corrupted after playing with pin 28 levels? May be comparing with another image..

    Is it really possible to recover in such way bricked chip with a new intact firmware of same version, say got from another source?

    ReplyDelete
    Replies
    1. It triggered a clear on the first 192 bytes (64 instructions) in the program flash. As noted by Charlie Miller, the program flash rows clear to FFFF3F which is a NOP instruction in CoolRISC, likely a feature of the chip. When the first instruction is a NOP I'm guessing the chip thinks it's blank and enters the boot-rom.

      I did reflash a valid bq8030 firmware image onto the chip I did this to and it started right up. Although note that I didn't test it at all aside from running an sbsreport (which worked).

      Delete
  24. These bytes should likely happen to corrupt in the very beginning for this described method to work? If they do somewhere in the middle the BootLoader will be able to pass boot vector next to corrupted firmware and the method will not work?

    ReplyDelete
    Replies
    1. Not entirely sure since I don't know how the clear occurs exactly. Do note that I've managed to do this twice though, so it's either very likely that the clear will occur at the beginning or if you corrupt the flash elsewhere you might end up in the boot-rom just the same. I don't remember if I read the second chip out or not, could've just checked whether it was in the boot-rom and left it at that.

      Delete
  25. > ' I did reflash a valid bq8030 firmware image onto the chip I did this >to and it started right up. Although note that I didn't test it at all >aside from running an sbsreport (which worked)'

    It's good news! Thanks

    ReplyDelete
  26. c:\karosium>smbusb_bq8030flasher -w eep1.bin
    ------------------------------------
    smbusb_bq8030flasher
    ------------------------------------
    SMBusb Firmware Version: 1.0.1
    PEC is ENABLED
    TI Boot ROM version 3.1
    ------------------------------------
    This will erase and reprogram the eeprom(data) flash on the microcontroller.
    If you're sure add --confirm_delete and try again.

    c:\karosium>smbusb_bq8030flasher -w eep1.bin --confirm_delete
    smbusb_bq8030flasher: unknown option -- confirm_delete
    ------------------------------------
    smbusb_bq8030flasher
    ------------------------------------
    options:
    --save-program= , -p = save the chip's program flash to
    --save-eeprom= , -e = save the chip's eeprom(data) flash t
    o
    --flash-program= , -f = flash the to the chip's progr
    am flash
    --flash-eeprom= , -w = flash the to the chip's eepro
    m(data) flash
    --execute = exit the Boot ROM and execute progra
    m flash
    --no-verify = skip verification after flashing (no
    t recommended)
    --no-pec = disable SMBus Packet Error Checking
    (not recommended)

    c:\karosium>

    ReplyDelete
    Replies
    1. Ah yes, that message was fixed quite a while ago but the windows binary release is a bit outdated. It's -, not _ so --confirm-delete :-)

      Delete
  27. Thank You.. I looked at the source and understand, that's good. So can You some share with where can I find a PF (permanent Failure) flags.. A EEPROM is quitely the same with Yours?

    ReplyDelete
    Replies
    1. Can't help there are at all, sorry. I just hacked away at it until it started to work. Haven't made any notes or anything :/

      Delete
  28. Oh I Find it is somewhere between adresses 0x600-0x65F. I copied a block from EEPROM above and MOSFETS are open and battery begin to charge.
    Great thanks, Viktor! Very nice work, and good base for projects.
    Another one question that I seems to erase one bq8030 it is indicating only ACK on 0x0 and 0x1, can I download there a software from another BQ8030 or me to waste it out?
    Thank You!

    ReplyDelete
    Replies
    1. Great to hear you got some use out of it :-)

      Not sure what could be going on with that second chip. If you did a full erase it should default to the boot-rom. Only two commands ACKing is weird. It is possible to flash firmware between chips but you need to be in the boot-rom otherwise the tool won't work.

      If you have a corrupt (but mostly intact) image on the chip it could be failing the checksum test and locking you out. In that case you'd probably have to try the pin28 glitching method I described in the post to get into the boot-rom first. If it's not that then I have no clue.

      Delete
    2. Tried to send image directly with address 0x00 so now it is a brick.. Nothing bad, I have many controllers to game now:-)

      Delete
  29. that is the link to EEPROM file https://yadi.sk/d/vbB1AqXL3QjTFf

    ReplyDelete
  30. Some success over here :)
    In my battery (Sanyo Lenovo 42T4644) start of log area (0x500) is kind of duplicated at 0x600 and only fiddling with bytes at the later offset takes an effect. Quick memory map:
    0x600-0x601 - cycle count as seen in SBS report. (exact, not -1 like in author's case)
    0x602-0x603 - Full Charge Capacity

    Then there was some values up to 0x61F, then all 0xFFs.
    And then some 01 00 00 at 0x640..
    Fiddling with this reveals the error flag bit is at..
    * 0x641 *
    Changing 00 -> FF makes battery report "charging current (SBS cmd 0x14)" as non-zero (5000mA).

    Now time to restore that weird fuse, recell, and $profit$. I'll force my X250 to swallow some 2008 T400's battery right at the end of 2017 :)

    ReplyDelete
    Replies
    1. Nice! Glad you could put it to good use :-)

      Delete
    2. But no. Despite bridging the fuse battery don't want to take nor give any current. I started to mess with the bytes even more, and then.. I locked it out. I can't flash the eeprom anymore. The only clue: sbs command scan gives this distinct result: https://gist.github.com/amateusz/3308986e843e8745f58535c6d89d68ac

      Disconnecting and reconnecting the cells doesn't help either.

      Delete
    3. Well you seem to be stuck in the "bad eeprom data"/recovery mode of the Sanyo firmware. I haven't released any code for this but I've actually ended up there at one point and I did code a tool to flash eeprom data with the available commands. I don't remember much about it so YMMV but here it is: https://pastebin.com/ZNPDXqZ9 Probably nothing will work besides flashing eeprom data.
      Let me know if you manage to get any use out of it. Good luck!

      Delete
  31. For make MOSFET's open after burning a fuse I found in BQ20zXX docs what is happened when controller burns a fuse:
    The Charge FET, Discharge FET, and Pre-Charge FET are all opened. 2. [TCA] and [TDA] in Battery Status is set 3. Charging Current and Charging Voltage is set to 0. 4. Data Flash Writes is disabled 5. if A and [XCFETF] or B and [XDFETF] in Permanent Fail Cfg then – 0x3672 is programmed to the Fuse Flag. – The Safety Output pins is activated which is intended to blow a fuse
    BQ8030 working is the same. So we need to set a charging voltage and current to desired value. Can controll it by SBS REPORT tool.

    ReplyDelete
    Replies
    1. I'm pretty sure this is what you meant but just to clarify: When we find and clear the fail flag it sets the charging current and voltage in the SBS report to the normal values (instead of 0) indicating that the pack is ready to take a charge. (ie. we're not setting the values directly, they change to the normal ones once we clear the flag)
      I might've forgotten to mention it in the article but yes, that is probably the quickest way to know whether you've found the fail flag.

      Delete
  32. Denis Serik, are you sure that this procedure will be the same for bq8030/Sanyo? It's firmware specific and bq20z90 running TI native firmware.
    Me have one sample battery with bq8030 and one with bq20z90 inside and I already accertained how they are different in operation just with few measurements. For example, elements in battery with bq8030 have about 700mV imbalance and battery continues operation without any PF flags set. For bq20z90 in that case it would be triggered the fuse as 100mV is deemed already critical. And I still not even found where that threshold is mapped in bq8030 eeprom. Another difference for bq8030 that battery output voltage is present at pack socket when battery removed from laptop in comparison with bq20z90, where this depends on SYSTEM_PRESENT signal at some socket pins.

    ReplyDelete
  33. I think that BQ8030 is a simplified firmware that one is used by ti in BQ20xxx.
    Ti gives an extra protection algorithms and more complicated.Sony/Sanyo enhansed an operating range of battery, allow battery to work to the bitter end, enhanses a battery life and makes it a cost-effective with enough protection. It is my opinion. PF flag set is another algorithm so if You are lucky, You may to avoid to set it for a very long time.

    ReplyDelete
  34. how did you interface the bq chip with the cypress dev board? did you take out the chip and connect with wires or otherwise?

    ReplyDelete
    Replies
    1. Through the main connector of the battery pack.

      Delete
    2. did you use an oscilloscope to find which pin is the clock, and which one is the data?

      Delete
    3. I just googled "thinkpad battery pinout" but you can also take the bq20z90 datasheet and follow the traces on the board.

      Delete
    4. i got the board. lsusb reports it with string "0x0925,Ox3881" and running "smbusb_scan -a" returns error -1. By looking at the sources it seems your code is pointing to device "0x04b4,0x8613". So I modified the code to point to what i have, and it seemed to work but once the firmware was loaded the device string changed and i had to go back to the previous version. From this point i could start working with. Is there any command i had to run before using smbusb_scan?

      Delete
    5. It sounds like you got an unusual board. Most of the cheap FX2LP devboards that I know of thus far have used 04b4/8613. You can modify firmware/dscr.a51 and all the tools to your board's vid/pid and everything should work seamlessly as it was meant to or you could use Cypress's tool to modify the vid/pid in the eeprom on your board.

      Delete
  35. have noticed on the above 'RsCont' screenshot one more interesting command 'F2: 400C00' (i.e. -c 0x40 -w 000C).
    Viktor, have you played with it or may be have any idia on it?

    Me checked on one sample of bq8030dbt, that this command [0x40] has same attributes as 'privilege escalation' command [0x71], i.e. it's 'word writable ONLY command'. Nothing can be read from both as error is returned.

    So supposed it may be another access level related command. Probably to work with online parameters modifying (in firmware mode, like [0x77],[0x78] commands are used for SubClasses reading or editing in bq20z90).

    as well noticed that BootROM entry subcommand on same screenshot is different from actually used for bq8030, (-c 0x70 -w 0502) vs (-c 0x70 -w 0517), do you brute forced it to get into BootROM too?

    ReplyDelete
    Replies
    1. I haven't really looked into them since the 0x71 lead got me to the bootrom which was all I wanted so I didn't go back for a second look.

      0517 came from the firmware disassembly and it's the one that leads to the bootrom entry call. 0502 it also checked but it does something different. Not really sure what but it might be a full erase or some sort of reset or it might put the chip into the proprietary calibration(?)/recovery mode that I posted a pastebin link for further up.

      Delete
  36. Viktor, so at what address did you find the permanent flag in your battery? I've soldered LED on fuse heater pins, and it always lights up, despite the fact that the charging current and voltage have good values.

    ReplyDelete
    Replies
    1. Sorry, no clue since it's been a couple of years now but it varies greatly which is why I didn't include it in the post. You'll find it if you keep trying.

      Delete
    2. You have to do something with cells, making them to have the same voltage, better to replace with a new ones

      Delete
    3. The difference between cells was 11 mV. I've tried to put three equal value resistors as voltage divider, making the difference no more than 2 mV. No success, heater pin is always powered, laptop does not charge the battery.
      Everytime I enter BootROM Remaining Capacity (as well as other related values) drops to zero. Is it normal? I'm thinking this could be a reason because zero is always less than Remaining Capacity Alarm (562 mAh).
      Now I can confirm than zeroing [0x540-0x542] and [0x640-0x642] values sets Charging Current to 3600 mA (otherwise 300 mA).

      Delete
  37. I managed to repair 85Wh battery. Addresses 0x640,0x641,0x642 must be all "00"
    My battery was "01 00 00".
    Making 0x641 to FF as suggested by Mateusz was making battery current reporting non zero but it does not work with laptop. All zeroes works.
    Controlled fuse is blown. Ordered from aliexpress. Meanwhile it is jumper. I do not know if it is neccessary but I soldered about 30 Ohm resistor to controlled fuse blow heater terminals when I investigated this battery.

    ReplyDelete
    Replies
    1. Cool, glad you got some use out if it!

      Delete