Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding support for /dev/i2c on linux? #19

Open
5ch4um1 opened this issue Feb 24, 2020 · 5 comments
Open

adding support for /dev/i2c on linux? #19

5ch4um1 opened this issue Feb 24, 2020 · 5 comments

Comments

@5ch4um1
Copy link

5ch4um1 commented Feb 24, 2020

First of all: thank you so much for all that useful information! :)

I was wondering if somebody has already adapted the tools to work with /dev/i2c on linux?
This is probably not a good idea, but messing with batteries is not a good idea in the first place i guess?

And apart from that, somewhere in a forum i saw a post suggesting that one could use a modified video cable to talk to i2c devices, and i was able to replicate some of the functionality of smbusb with i2c-tools and the vga port, including entering boot rom mode, checking the boot rom version (also 3.1 on my chip) and reading blocks with i2ctransfer.
But before i try to write and brick the chip i thought it would be a good moment to ask some dumb questions...
would it e.g. be possible to just edit/rewrite single blocks? (or actually 2 blocks if i understood that right?)
or in other words, is it necessary to dump, erase and rewrite everything?
the erase part is necessary as far as i understood?
I tried to understand the code of the flashing process without too much success so far.
if i get that right, a word write of 0x83DE to 0x12 would erase everything?
and then it does block writes?
and then, what does the
SMBSendByte(0x16,CMD_EXECUTE_FLASH);
do? is that just to exit the boot rom mode?
sorry for all the stupid questions...

@5ch4um1
Copy link
Author

5ch4um1 commented Dec 24, 2020

Well, i recently got one of those cheap 8 channel logic analyzers...turns out, they are based on the fx2...the i2c pins are not broken out, but that eeprom is a nice place to solder wires to:
image
so thanks to smbusb_bootstrap i finally managed to get dumps of the firmware and the eeprom and could compare them to the results of some scripts i had written some time ago, and i could fix some errors.
I think i managed to dump both firmware and eeprom now via /dev/i2c
`#!/bin/bash

max=18416
for ((i=16384;i<=max;))

do
y=$(printf "%#.4x\n" $i)
let "i+=32"

sudo i2cset -y 1 0x0b 0x09 $y w
sleep 0.01
r=$(sudo i2ctransfer -y 1 w1@0x0b 0x0c r33)
echo $r | cut -c6-
sleep 0.01
done`

(edit: not sure what i smoked yesterday, but it took me way to long to realize that 20 actually means 0x20, aka 32...worked anyway, but i fixed this now and it reads the 32 bytes it should)

this for example should dump the content of the eeprom.
The output format is obviously different from what your tools produce, but i guess when doing the writes with i2ctransfer we'll need the data like that anyway.
I think i'll try these days if i first can finally fix my battery using your tools and then maybe try to write to the chip with /dev/i2c.
By the way, has anybody tried single block writes instead of writing the whole thing? iirc, the datasheet suggests that this should be possible? Oh, and for those who don't want to use the display data channel, but own a raspberry pi, this should work on a pi too.

@karosium
Copy link
Owner

karosium commented Jan 4, 2021

Your description of the erase->write->exit process is correct.
https://www.ti.com/lit/ug/sluu187/sluu187.pdf might help with commands.

Someone wrote tools for /dev/i2c here: https://github.com/noolex/lenovo_battery_repair

Multi interface support would be good to have but I won't be able to work on it any time soon unfortunately.

@5ch4um1
Copy link
Author

5ch4um1 commented Jan 4, 2021

Ah, that's nice, that bat_hack script even does the math. :) I guess we can call this issue resolved then.
Unfortunately my battery stopped talking to me, so i can't test right now. (thought about buying a chip on aliexpress to keep playing, this broken battery has had a huge educational value for me so far...)
Another interesting project i stumbled upon these days was this: https://github.com/iam4722202468/ThinkpadBattery which is basically a smart battery emulator for arduino platforms. He simply uses an attiny85 to tell the laptop what it wants to hear. Tried this with an arduino nano clone, works like a charm, and also might be pretty practical for testing real batteries i guess.
And last but not least, for those of you who are interested in the firmware, there is this guy from australia who wrote a ghidra plugin: https://github.com/pelrun/ghidra-cr816
which is still way above my capabilities, but i hope to make use of it one day.
Anyway, thank you very much for you work, i have learned a thing or two from reading your code, and finally got a backup of both firmware and eeprom data.

@mefistotelis
Copy link

Responding more to the title of the issue than the actual discussion - it so happens that I made a tool which uses /dev/i2c.
It actually uses 'smbus2' Python module, and that Python module opens the device and does ioctl calls on it.

The tool:
https://github.com/o-gs/dji-firmware-tools#comm_sbs_bqctrlpy
Usage example:
https://www.youtube.com/watch?v=P5PNOO2GebY

@5ch4um1
Copy link
Author

5ch4um1 commented Mar 12, 2021

that looks like a lot of work, really nice!
i like that sbs_read_firmware_version_bq_sealed function! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants