Hello,
On 10/17/19 12:08 PM, Sean Young wrote:
Hi Antti,
I have a Logilink VG0022A device which is an af9035.c type device (with
ITE 9xxx frontned). The probe of the si2146 tuner fails and returns 0xffs.
Now I would like to work on fixing this. Mauro suggested the firmware might
be incorrect. Any tips on extracting the firmware? I can try and dump
usb traffic from Windows and see what firmware is being used there. How did
you extract the firmware?
Any other suggestions for this device? You might be able to save me a lot
of time since you have experience with these types of devices, I do not.
Extracting firmware is done almost always by following steps:
1) take sniffs from the some bus (usb/i2c)
2) identify firmware download section, detect it starting point and
ending point ~few first and last bytes
3) find that firmware binary located inside of binary driver
* grep, hexeditor, etc
* example LANG=C grep -obUaP "\x08\x05\x00" driver.sys
4) use dd command to copy firmware blob from binary driver to separate
file (you need to know firmware location and length inside binary)
It is also possible to dump firmware to file from bus sniffs too, but it
requires writing some simple script. Dumping it from the binary driver
is usually still most easiest way.
At some point I downloaded bunch of drivers to find out multiple
firmware versions for si2168 and made simple script to ease things.
Script is attached.
After all, I suspect root of issue may be still be buggy i2c...
regards
Antti
--
http://palosaari.fi/
#!/usr/bin/env python
# Silicon Labs Si2168 firmware extractor.
# Copyright (C) 2015 Antti Palosaari <crope@xxxxxx>
# Usage: si2168_extract_firmware.py binary_driver_name.sys
import sys
import struct
import md5
fread = file(sys.argv[1], 'rb')
binary = fread.read()
offset = 0
# Known firmware md5 and its version
fw_ver_tab = {
'02c9b1e751f362621c649ea831410b61' : '4.0.7',
'b2670d8ae5e3369fc71edbb98cdd8f6e' : '4.0.11',
'8dfc2483d90282bbb05817fbbc282376' : '4.0.19',
'c8e089c351e9834060e962356f8697b8' : '4.0.25',
}
while True:
# Match 17-byte firmware header
# 04 01 00 00 00 00 9a 41 05 1b af 33 02 1b 3e 7d 2a | A20 (not supported)
# 08 05 00 xx xx xx xx xx xx 00 00 00 00 00 00 00 00 | B40
offset = binary.find('\x08\x05\x00', offset)
if offset == -1:
print "Done"
break
if (binary[offset + 9:offset + 17] != '\x00\x00\x00\x00\x00\x00\x00\x00'):
offset = offset + 1
continue
print "Possible 17-byte Si2168-B40 firmware header found at 0x%x" % (offset)
fw_filename = 'dvb-demod-si2168-b40-01.fw_' + str(offset)
fw_write = open(fw_filename, 'wb')
fw_md5 = md5.new()
while True:
fields = struct.unpack("B", binary[offset])
fw_data_len = fields[0]
# Firmware chunk first byte tells bytes to upload - 16 is max
if fw_data_len == 0 or fw_data_len > 16:
break
# Check remaining (unused) bytes on firmware 17-byte chunk are all zero
data_valid = True
for x in range(offset + fw_data_len + 1, offset + 17):
if (binary[x] != '\x00'):
data_valid = False
break
if data_valid == False:
break
# Firmware chunk validated, write it to file
fw_write.write(binary[offset + 0:offset + 17])
fw_md5.update(binary[offset + 0:offset + 17])
offset = offset + 17
fw_write.close()
if fw_md5.hexdigest() in fw_ver_tab:
fw_ver = fw_ver_tab[fw_md5.hexdigest()]
else:
fw_ver = '<unknown>'
print "Firmware md5 '%s'" % (fw_md5.hexdigest())
print "Firmware version '%s'" % (fw_ver)
print "Firmware stored to file '%s'" % (fw_filename)
offset = offset + 1
fread.close()