Useful Linux commands after data recovery

Delete files of a specific type recursively:

find . -type f -iname '*.chm' -exec rm {} \;


Find files of a specific type recursively and copy to destination folder:

find . -type f -iname '*.tif' -exec mv -i {} ~/Recovered/tif \;


Print statistics about file types/ extensions:

find . -type f | sed 's/.*\.//' | sort | uniq -c


Delete all files smaller than a certain size recursively:

find . -iname "*.tif" -size -160k -delete



How to download Google Drive shared folders with photos – using Firefox, Selenium and Python

Recently, I’ve been facing issues when I wanted to download shared folders from Google Drive: there’s an existing out-of-the-box option to download complete folders (at least since the last few years). However, this options does not seem to be bug-free – this may be by design, or not:

Before the download is started, the web interface signals the file compression. The download also works, but the downloaded zip file does not contain all of the JPEG photos which are in the shared folder. A somehow strange behavior which unfortunately has been very reproducible (both for being logged out and also in).

The workaround: download each file individually. For small shared folders this could be doable – however, it’s likely that the zip files are also fine then. So for larger shared folders, this process should be automated.

Failed approaches

First approach: Selenium IDE (failed)

My first idea was to use Selenium IDE, as I had gained some experience with it in the past. Sadly, Silneium IDE currently isn’t supported in Firefox Quantum. (Firefox 57+ Support #24, there’s even an xpi file in the /releases, but it didn’t work for me – issue #61.)

Second approach: Selenium Server Standalone (failed)

As the first approach did not work for me I stumbled across the Selenium Server Standalone and found some old docs about using the htmlSuite option:

java -jar selenium-server-standalone-3.11.0.jar -htmlSuite "*firefox" "" "HTMLSuite.html" "Results.html"
Download the Selenium HTML Runner from and
use that to run your HTML suite.

Okay, so that seems to be outdated..

Third approach: Selenium HTML Runner (failed)

I couldn’t get it working, even after trying to fix the geckodriver issue.

java -jar selenium-html-runner-3.10.0.jar -htmlSuite "*firefox" "" "HTMLSuite.html" "Results.html"
Multi-window mode is longer used as an option and will be ignored.
Mar 18, 2018 4:38:09 PM org.openqa.selenium.server.htmlrunner.HTMLLauncher mainInt
WARNING: Test of browser failed: *firefox
java.lang.IllegalStateException: The path to the driver executable must be set by the webdriver.gecko.driver system property; for more information, see The latest version can be downloaded from
 at org.openqa.selenium.remote.service.DriverService.findExecutable(
 at org.openqa.selenium.firefox.GeckoDriverService.access$100(
 at org.openqa.selenium.firefox.GeckoDriverService$Builder.findDefaultExecutable(
 at org.openqa.selenium.remote.service.DriverService$
 at org.openqa.selenium.firefox.FirefoxDriver.toExecutor(
 at org.openqa.selenium.firefox.FirefoxDriver.<init>(
 at org.openqa.selenium.server.htmlrunner.HTMLLauncher.createDriver(
 at org.openqa.selenium.server.htmlrunner.HTMLLauncher.runHTMLSuite(
 at org.openqa.selenium.server.htmlrunner.HTMLLauncher.mainInt(
 at org.openqa.selenium.server.htmlrunner.HTMLLauncher.main(

Anyway, I didn’t find good docs about how the HTML file should look like as the Silenium IDE I had fiddled around with just provided me a .side script with content which looks like JSON.

Final approach: use Selenium Client with WebDriver Python Bindings

I am not a Python programmer but my working script ended to look like this:


<find the file on github>

How to call the script:


How the script works:

  • start an instance of the Firefox browser and open the given URL
  • send the ‘v’ key press to change from grid to list view (no image preview!)
  • send several ‘arrow down’ key presses to skip the given number of files
  • send the ‘Enter’ key press to open a preview of the first photo
  • for each photo:
    • click the download button
      (the file is then automatically downloaded in the background)
    • click the next button to get to the next photo

Changes you need to make:

  • there’s an option to skip photos at the beginning – replace the magic number “1749” with your value (however, the skipped number may be a little smaller due to loading delays)
  • change the words “Weiter” (for “next”) and “Herunterladen” (for “download”) to match your language


  • every now and then I had a selenium.common.exceptions.ElementNotInteractableException exception which I haven’t handled and which crashes the script – I just called the script again with an incremented “skip number”
  • the skript may be quite slow as I added a delay after clicking the next and download buttons

Room for improvements:

  • output the current file names in the console output – I couldn’t manage to do this reliably – the elements on the website seem to become invisible, when not hovered
  • check downloaded files against files on the web (and check if we really got all the files)
  • improved exception handling
  • hand over URL and options (e.g. destination folder) via command line options
  • fix tabs and spaces 😉
  • comments in the code 😉 😉
  • <add yours>

Feel free to contribute:

Get Selenium here:

Hardware components of the solar charger

Components (ICs) on the top side:

  • Atmel ATmega32U4 8-bit microcontroller
  • LM393A dual differential comparator
  • 272BI LinCMOS precision dual operational amplifiers
  • FDS4897C dual N & P channel PowerTrench MOSFET
  • TS2951-50 150mA 5.0V ultra low dropout voltage regulator
  • 4511 AE T05C ?

Components (ICs) on the bottom side:

  • 85831 p09g 112 ?
  • tbc …

Reverse engineering and fixing your broken Ignis/Baukneckt/Whirlpool or Philips oven/ stove

As my oven/stove broke I started analyzing the system in order to find and fix the error. Basically the residual-current-operated protective device “blew” when I switched on the oven – the cooktop worked just fine.

Side note: Searching the spare parts showed that Ignis, Bauknecht, Whirlpool and Philips are using the same parts – or that the same oven is sold under different brand names.

Disclaimer: be careful when working with devices that are usually connected to mains power. Definitely disconnected the device from mains power before trying to fix it or even measuring something – and also do make sure that there’s no power!

Gaining a basic understanding

The oven is connected to mains power using the three phase conductors (L1, L2, L3), the neutral conductor (N) and protection earth (PE).

There’s a lot of components inside the device which basically can be seen as resistors. To calculate the power converted to heat simply use the following formula (derived from Ohm’s law): P=U²/R where U=230 V (mains power in Europe).

There’s a lot of cables inside the oven, some components and several knobs/ rotary switches.

Those rotary switches work the following way: dependent on the position of the know some pins on the left side are connected with their direct opposite pins on the right side. Pins on the left and on the right side can be connected among each other so that combinations of connections can be made.

About the oven

The oven consists of the following main parts (besides cabling, etc.):

  • Rotary function selector switch
  • Oven light/lamp
  • Fan on the back
  • Fan on the top
  • Heating indicator
  • Temperature selection rotary switch/knob
  • Heating element on top (for upper heat; consisting of two separate loops)
  • Heating element on the bottom (for lower heat; single loop)
  • Thermistor, fuse or bi-metal (haven’t checked it yet)

The oven has a rotary function selector switch with 7 positions. Each of the positions may connect one or several out of the 7 internal switches (it’s a coincidence that the number of switch positions equals the number of internal switches).

I have identified the following functions for each internal switch:

  • 1/P1: “enable” heating, lamp and fans (does not switch them on alone, another internal switch needs to be switched on for this!)
  • 2/P2: switch on the heating element on the bottom (for the lower heat)
  • 3/P3: switch on the outer loop of the heating element on the top (part of the upper heat; ~1600 W)
  • 4/P4: switch on the inner loop of the heating element on the top (part of the upper heat; ~900 W)
  • 5/P5: may “enable” the heating indicator, however, I think that this is strange…
  • 6/P6: switch on the fan on the back side of the oven
  • 7/P7: switch on the oven’s lamp and the fan on the top side of the oven

Which internal switches are closed/opened at which position of the rotary switch? You need to look it up in the table to get a deep understanding of that.

Textual explanation:

  • Pos. 0: everything is switched off
  • Pos. 1: switch on oven’s lamp and fan on the top
  • Pos. 2: switch on oven’s lamp, fan on the top, bottom heating element, outer loop of upper heating element and enable the heating indicator
  • Pos. 3: switch on oven’s lamp, fan on the top, bottom heating element, outer loop of upper heating element and switch on fan on the back
  • Pos. 4: switch on oven’s lamp, fan on the top, both loops of the upper heating element
  • Pos. 5: just like pos. 4 but additionally also the fan on the back
  • Pos. 6: switch on oven’s lamp and both fans (on top and on the back side), no heating element at all (used for defrosting)

Using the information gained during analysis lead me to the cause of the error: a broken heating element in the bottom of the oven. Fortunately, those are not very expensive so that I could order a new one.

About the cooktop / hot plates

The two main parts (besides cabling are):

  • Whirlpool AKM 896/IX ceran cooktop, 6.2 kW (cost of ~90 €)
  • “Kochplattenschalterblock”/”7-Takt-Schalter-Block” 4144723003 (cost of ~40 €)

Dependent on the position of the rotary switch there are different configurations of how current flows through the elements of the hot plates to generate heat. There’s a cable with 4 pins wired to each zone of the hot plates. Dependent on the position of the switch P1 and P2 are connected with different pins.

The following calculations are an example for the hot plates connected with the yellow connector (and assuming a mains voltage of 230 V):

  • Position 0: P1 not connected, P2 not connected
  • Position 1: P1 connected to pin 1, P2 connected to pin 2;
    the current will be limited by a resistance of 108+108 Ohms (~245 W)
  • Position 2: P1 → pin 3, P2 → pin 4;
    the current will be limited by a resistance of 108+64 Ohms (~308 W)
  • Position 3: P1 → pin 2, P2 → pin 4;
    the current will be limited by a resistance of 108 Ohms (~490 W)
  • Position 4: P1 → pin 2, P2 → pin 3;
    the current will be limited by a resistance of 64 Ohms (~827 W)
  • Position 5: P1 → pin 2, P2 → pins 3 and 4;
    there are two paths for the current now; the old one through the 64 Ohms and another one through 108 Ohms (~827+429=1256 W)
  • Position 6: P1 → pins 1 and 2, P2 → pins 3 and 4
    there are three current paths now; each limited by a resistance of 108/108/64 Ohms (~490+490+827=1807 W)


As I have reverse engineered the whole device, I can offer the following schematic (which may not bee free of errors):


I have also included order numbers within the schematic.


It was quite interesting to see the different components of an oven/ stove and how they work internally. Basically it’s not too complicated to fix such a device, when a component is broken. And you don’t need many tools: a multimeter is enough – or even a device only measuring resistance can be enough.


This post may be (or may be not) updated with further details in the future.

The odyssey of getting my Funduino/Arduino UNO back to normal operation

Long, long time ago I had flashed the bootloader of my Funduino UNO.

When listing my USB devices it would appear as follows:

Bus 002 Device 017: ID 03eb:2042 Atmel Corp. LUFA Keyboard Demo Application

I had flashed a firmware to get an alternative to the makeymakey board with my own shield (basically with high-imedance resistors only). So I could not flash the ATmega328P microcontroller (in the socket) via the serial interface which is usually provided via the USB of the ATmega16U2. And unfortunately I didn’t have the old shield available anymore and the controller was constantly putting out data on the HID keyboard device which was quite annoying!

This page on sparkfun explains what a bootloader is, what it does and how it basically works:

Burning the bootloader via the Arduino IDE failed:


I wasn’t too sure if my AVRISP mkII was working correctly. I remembered that I’d has issues with it before – and I hadn’t used it for a long, long time!

Same error when trying to talk to avrdude directly via command line:

avrdude -c avrispmkII -p m16u2
avrdude: stk500v2_command(): command failed
avrdude: stk500v2_program_enable(): bad AVRISPmkII connection status: Target not detected
avrdude: initialization failed, rc=-1
 Double check connections and try again, or use -F to override
 this check.
avrdude done. Thank you.

Similar error for the ATmega328P with the other connector (using “avrdude -c avrispmkII -p m328p”). How about adding the port and verbose options?

$ avrdude -c avrispmkII -p m328p -P usb -v

avrdude: Version 6.0.1, compiled on Oct 21 2013 at 15:55:32
 Copyright (c) 2000-2005 Brian Dean,
 Copyright (c) 2007-2009 Joerg Wunsch

System wide configuration file is "/etc/avrdude.conf"
 User configuration file is "/home/maehw/.avrduderc"
 User configuration file does not exist or is not a regular file, skipping

Using Port : usb
 Using Programmer : avrispmkII
avrdude: usbdev_open(): Found AVRISP mkII, serno: 1337DEADBEEF
 AVR Part : ATmega328P
 Chip Erase delay : 9000 us
 BS2 : PC2
 RESET disposition : dedicated
 RETRY pulse : SCK
 serial program mode : yes
 parallel program mode : yes
 Timeout : 200
 StabDelay : 100
 CmdexeDelay : 25
 SyncLoops : 32
 ByteDelay : 0
 PollIndex : 3
 PollValue : 0x53
 Memory Detail :

Block Poll Page Polled
 Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
 ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
 eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
 flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
 lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
 hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
 efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
 lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
 calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
 signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00

Programmer Type : STK500V2
 Description : Atmel AVR ISP mkII
 Programmer Model: AVRISP mkII
 Hardware Version: 1
 Firmware Version Master : 1.12
 Vtarget : 0.0 V
 SCK period : 4.00 us

The error message can also be found on and (DE).

Relevant info: “-vvvv” gives a very verbose mode. Let’s assume my AVRISP mkII is broken. How to proceed? I’ve still got a working Arduino Leonardo lying around – let’s try to use it as an ISP: ArduinoISP –

Before loading the ArduinoISP sketch and resetting the board:

Bus 002 Device 023: ID 2341:8036 Arduino SA Leonardo (CDC ACM, HID)


Bus 002 Device 024: ID 2341:0036 Arduino SA

The two Arduino board are connected with the following pins:

  • power supply 5V and GND from the programmer to the target Arduino
  • SPI interface (MOSI on target pin 11, MISO on target pin 12, CLK on target pin 13)
  • reset pin of the target Arduino with a controlling GPIO of the programmer Arduino

Checkout the following diagram:

If pins with the same numbers were connected with each other – like those SPI pins – wouldn’t this conflict? If MISO was connected to MISO and MOSI was connected to MOSI? Both controllers might drive the same line?

It probably would! I have stumbled across the logic in the ArduinoISP sketch and had to define:


[Comment: “Uncomment following line to use the old Uno style wiring (using pin 11, 12 and 13 instead of the SPI header) on Leonardo, Due…”]

Avrdude didn’t complain about any wrong signatures anymore. I used:

$ avrdude -P /dev/ttyACM0 -c stk500v1 -b 19200 -F -v -v -p m328p

Back to the Arduino IDE, finally:


In a next step I compiled and downloaded the simple Blink example, that worked as well. Let’s try to unplug the Arduino Leonardo (the Arduino functioning as a programmer) and replug the USB connector to the Funduino/Arduino UNO. The LED still blinks after startup, however the UNO is still not available as a serial device to be programmed, but still the HID keyboard. The bootloader/firmware of the ATmega16U2 still needs to be flashed. The ATmega16U2 acts as a USB-serial bridge between the PC and the ATmega328P microcontroller.

Resetting the Arduino UNO connects the device in a different mode:

Bus 002 Device 062: ID 03eb:2fef Atmel Corp.

Then the dfu-programmer needs to be executed:

$ sudo dfu-programmer atmega16u2 erase

$ sudo dfu-programmer atmega16u2 flash Arduino-usbserial-atmega16u2-Uno-Rev3.hex 
4034 bytes used (32.83%)

$ sudo dfu-programmer atmega16u2 reset

… and power-cycling the board finally did the trick for me: the device is back available as serial interface:

Bus 002 Device 064: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)

And now it can also be programmed via the Arduino IDE back again! 🙂


Using Adafruit NeoPixel ring with Arduino

There’s a library for the Adafruit NeoPixel which can be used with the Arduino:

When the library is missing the Arduino IDE will complain about the missing C header file:

SomeSketch.ino:1:31: fatal error: Adafruit_NeoPixel.h: No such file or directory
 #include <Adafruit_NeoPixel.h>
compilation terminated.
exit status 1
Error compiling for board Arduino/Genuino Uno.

Install the missing library via the library manager:


Compiling your sketch should now work out!

Gerber files in EAGLE

I have worked with files describing electronic schematics and PCB board layout. But so far I have never really worked with Gerber files myself. As I found out it’s not rocket science, it’s not complicated at all.

The Gerber format is used to describe monochrome vector images by an ordered stream of graphics objects. The format uses printable ASCII (7 bit) characters only.

The schematic and PCB design software EAGLE provides a job mechanism with the aid of which the creation of the output data for a board can be automated (CAM). This tool can be used to create Gerber files. The predefined job is called

For a 2-layer PCB the standard process will lead to five Gerber files (where cmp stands for component side and sol for solder side):

  • Copper, component side (.cmp)
  • Copper, solder side (.sol)
  • Silk screen, component side (.plc)
  • Solder stop mask, component side (.stc)
  • Solder stop mask, solder side (.sts)

You might want to add (if your manufacturer allows you to have it:

  • Silk screen, solder side (.pls)

Additional steps: you may want to add a drill file, specified by the Excellon file format. That’s another job in Eagle called The Excellon format (variant of the RS-274-C standard) is widely used to drive CNC drilling and routing machines in PCB manufacturing.

This will create the following two files:


  • Drill file (.drd)
  • Drill Station Info File (.dri)

The drill file is used by a drill program and includes sizes and locations of holes in the PCB.

To check my results I used the gerbv tool under Linux:

Screenshot of gerbv tool



Dumping a NAND flash, part 1

NAND flash organization

The memory of a NAND flash is organized in a hierarchy of:

  • blocks,
  • pages,
  • sectors,
  • planes.

The Hynix HY27UF084G2B consists of 4096 blocks. Each block of a NAND Flash consists of 64 pages. Each page consists of 4 sectors of data (512 Byte each) and 4 small sectors (16 Byte) of spare data, i.e. a single page consists of 2112 Byte where 2048 Bytes are data and 64 Bytes are spare. 2112 Byte blocks are also called “large block” opposed to “small blocks” of 528 Bytes (holding 512 Bytes of data and 16 Bytes of spare data).

Memory: 4096 blocks × 64 pages/block × 4 sectors/page × 512 Byte/sector = 512 MiB
Spare memory: 4096 blocks × 64 pages/block × 4 sectors/page × 16 Byte/sector = 16 MiB
Overall memory: 512 MiB + 16 MiB = 528 MiB

Flash memory is read and written in pages and erased in blocks of data. Memory must be erased before it is written to! This is also true for single byte writes.

Content of the spare areas: those out of band (OOB) area store data for error detection (e.g. a checksum), correction coding (ECC, most algorithms are based on Hamming codes) and bad block markers (if ECC cannot handle the amount of errors anymore). But can also contain data for the logical/virtual organization (blocks, pages) of physical blocks and pages. The ECC is usually a vendor/model dependent algorithm.

Creating a flash dump

Know your chip

Sometimes the interface to update firmware (e.g. via JTAG or serial port) is not exposed or not easy to find. It may then be an option to take the NAND flash device from the printed circuit board. The desoldering process is followed by dumping the flash memory, sometimes referred to as “off-chip forensics” (used in security analysis and data recovery).

In a next step the device is taken and put into a NAND flash reader/writer. There are commercial tools, but they can also be built from some basic hardware. A popular choice is to build a serial/parallel to USB adapter*. The FTDI FT2232H (and a breakout board) is a good starting point as you can toggle various GPIO pins in “bit bang” mode via its USB interface (mostly used as dual-port USB/serial converter). There’s also a project about using an Arduino NAND flash reader (no focus on speed).

It’s also good to know the NAND flash memory chip’s parameters and pinout in advance. Those specifications can be read from the datasheet, if you can read the labels written on the IC package. It is possible that your flash complies with the Open NAND Flash Interface specifications.

Taking the Hynix HY27UF084G2B again as an example:

  • 512M x 8bit NAND flash
  • package: 48-TSOP1, dimensions: 12x20x1mm, 0.5mm pitch
  • supply voltage: 3.3V (Vcc range: 2.7V..3.6V)
  • memory organization already mentioned above;
    page organization: separate data and spare areas, i.e. main field with 4x 512 Byte of data comes first, followed by 4x 16 Bytes spare
  • timings can be read from the datasheet
  • interface pins
    • x8 bus width I/O interface, i.e. IO0..IO7
    • nCE: chip enable
    • nWE: write enable
    • nRE: read enable
    • RnB: ready/busy indication
    • CLE: command latch enable
    • ALE: address latch enable
    • nWP: write protect
      (8 + 7 = 15 pins needed)
  • capacitance between Vcc and Vss as a buffer: 0.1 uF
  • address cycle map: which address bit is latched when on the I/O interface?
    • the HY27UF084G2B has 5 cycles, i.e. 5 x 8 bit = 40 potential bits
    • 512M addresses needed: log2(512M)=29, i.e. only 30 bits required (A29..A0) and 10 bits to be kept at a low logic level
  • definition of the device’s command set; some commands are single byte operations, others are composed of multiple bytes e.g.
    • READ1 (0x00 in 1st cycle, 0x30 in 2nd cycle)
    • READ ID (0x90 in 1st cycle)
    • RESET (0xFF)

The READ ID command is a good one to test if the connection with the flash can be established successfully and without causing a potentially high damage to the flash device. However, you should know what you do.

The ID to be read for my chip is: 0xAD 0xDC 0x10 0x95 0x54. Those bytes can be interpreted in the following way:

  1. Manufacturer Code: 0xAD (=Hynix)
  2. Device Identifier: 0xDC
  3. Device Identifier Description: 0x10 = 0b00010000
    • Write Cache: not supported
    • Interleave program between multiple chips: not supported
    • Number of simultaneously programmed pages: 2
    • Cell type: 2 level cell
    • Die/package: 1
  4. Device Identifier Description:0x95 = 0b10010101
    • Serial access time: 25 ns
    • Organization: X8
    • Block size (w/o spare area): 128K (see above: 64 pages × 2KB/page)
    • Spare area size (Bytes per 512 Byte): 16
    • Page size (w/o spare area): 2KB
  5. Device Identifier Description (Multiplane information): 0x54 = 0b01010100
    • Plane size: 2 Gbit = 256 MByte
    • Plane number: 2

(*Side note: our flash IC is a parallel flash, but a similar approach could be taken for an SPI flash as well, using an SPI to USB bridge.)

Building the hardware for a DIY NAND flash reader

Required hardware:

  • TSOP-48 socket
  • 0.1uF capacitor
  • wires & jumper wires
  • breakout board with the FTDI FT2232H (to read/write data from/to the NAND flash; communication with a host PC)
  • USB cable

The pins of the TSOP-48 socket (being directly connected with NAND flash memory device) are wired with the pins of the FTDI FT2232H.

(Side note: the TSOP socket may also be used to get the NAND flash memory working in it’s embedded system environment and eavesdropping on how it is accessed with a logic analyzer – flash memory at which addresses and when, e.g. at boot.)

Using software with the DIY NAND flash reader

I will run my DIY NAND flash reader under a Linux operating system. Therefore tools which already work under Windows are not applicable here. But at least the source code of ftdinandreader (Download) and Bjoern Kerler’s advancement NAND Reader FTDI can help here. I may start from scratch but also may re-use some source code.

First I got the source code and build files for libftdi. The build process and the dependencies for libftdi in turn (e.g. libusb-*-dev) are documented well in README and Afterwards I could run one of the examples coming with libftdi as I had a small breakout board with an FTDI 232RQ laying around.

$ lsusb
Bus 002 Device 004: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC

Let’s use the example:

/libftdi1-1.3/build/examples $ ./find_all_pp -v 0x0403 -p 0x6001
Found devices ( VID: 0x403, PID: 0x6001 )
FTDI (0x228c950): , ,  (Open FAILED)

Using higher access rights results in:

/libftdi1-1.3/build/examples $ ./find_all_pp -v 0x0403 -p 0x6001
Found devices ( VID: 0x403, PID: 0x6001 )
FTDI (0xd64cb0): FTDI, FT232R USB UART, <#serial> (Open OK)

There’s another example, shipped with libftdi, to access the FTDI’s internal EEPROM memory:

/libftdi1-1.3/build/examples $ ./eeprom 
Chip type 3 ftdi_eeprom_size: 128
0x000: 00 40 03 04 01 60 00 00  a0 2d 08 00 00 00 98 0a .@...`.. .-......
0x010: a2 20 c2 12 23 10 05 00  0a 03 46 00 54 00 44 00 . ..#... ..F.T.D.
0x020: 49 00 20 03 46 00 54 00  32 00 33 00 32 00 52 00 I. .F.T. 2.3.2.R.
0x030: 20 00 55 00 53 00 42 00  20 00 55 00 41 00 52 00  .U.S.B.  .U.A.R.
0x040: 54 00 12 03 XX 00 XX 00  XX 00 XX 00 XX 00 XX 00 T...X.X. X.X.X.X.
0x050: XX 00 XX 00 c4 7a 34 70  00 00 00 00 00 00 00 00 X.X..z4p ........
0x060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 ........ ........
0x070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 38 fd ........ ......8.
0x080: 28 04 d7 fb 00 00 c4 7a  34 70 42 00 00 00 00 00 (......z 4pB.....
0x090: 00 00 00 00 00 00 00 00  37 41 59 53 54 4c 46 43 ........ 7AYSTLFC
VID:     0x0403
PID:     0x6001
Release: 0x0000
Bus Powered:  90 mA USB Remote Wake Up
Manufacturer: FTDI
Product:      FT232R USB UART
Serial:       <#serial>
Checksum      : <#checksum>
Internal EEPROM
Oscillator: Internal
Enable Remote Wake Up
PNP: 1
Channel A has Mode UART VCP
C0 Function: TXLED
C1 Function: RXLED
C2 Function: TXDEN
C3 Function: PWREN
C4 Function: SLEEP

In a next step I used some of the example code and used it in my own first C file. I compiled it using a simple Makefile and the gcc build tools.

Next steps:

  • getting the required hardware
  • assemble the parts
  • unsolder the flash IC
  • use/develop software to dump the NAND flash memory
  • analyze the dump

Good resources


How to produce EXEs that only contain printable ASCII

Dr. Tom Murphy (@tom7) wrote a paper about “compilers, bits and assembly” – it is about producing DOS-executable EXE file which contain the limited set of only the printable ASCII bytes. In principle, he explains which steps to be taken and some necessary tricks/workarounds when writing a C89 compiler to fulfil these requirements. You can also learn something about the x86 instruction set. Find the paper (20 pages with some ASCII art in it) here. And he also made an explanation video: