CH341A USB serial EEPROM reader under Linux

I nprogrammereeded to backup original firmware of my favorite Chinese wireless router but I didn’t want to spend much time with hacking the embedded Linux. So I have ordered this cheap USB serial EEPROM programmer on ebay. You can easily find the original utility & driver for Windows on the Internet but the chip manufacturer doesn’t provide software for Linux.

After examining the board I found out that the chip is CH341A (datasheet) so I googled for some Linux software and I’ve found 2 opensource drivers:

The first one can be used for programming 24C… I2C EEPROMs. The second one is for 25Q… SPI flash chips so it was my choice.  After compiling and connecting my chip, I was able to read info about my flash.

Unfortunately, when I tried to read memory contents I was only able to get first few bytes of my memory, probably because the chip was detected incorrectly. So I forked the original github repo and added an option to manually set memory length. After setting the length manually, I was able to download complete data from my flash.


After some time I also needed to use it for 24C… programming. There are two forks of ch341eeprom on github. One which does pretend to support eeproms smaller than 128kb ( this one ) and one which really does ( this one ). Until I have found the second one, I also used a kernel module which adds /dev/i2c-x interface driver and wrote a script for writing eeproms here:

Enjoy whichever method you like.

25 thoughts on “CH341A USB serial EEPROM reader under Linux”

  1. i compiled your code but the read file contents are all zeros
    I read using the command ./ch341prog -l 8388608 -r test.bin)
    I have w25q64 , can you explain more about reading ?

    1. Did you connect all pins? Some chips need to have /HOLD and /WP pins also connected to VCC.

      1. I am trying to unbrick the same Chinese router. I am trying to read the content for now, I get this:

        sudo ./ch341prog -l 8388608 -r test.bin
        Device reported its revision [4.03]
        Manufacturer ID: ff
        Memory Type: ff
        Capacity: ff
        Chip capacity is -2147483648

        cbBulkOut: error : 1

        cbBulkIn: error : 1
        ch341SpiRead: Failed to write 3 bytes ‘Interrupted system call’

  2. How do I debug this? Any ideas? I have a w25q128fv. And usb Ch341a

    root@stock:~/ch341/ch341prog-master# ./ch341prog -l 16777216 -r nand.dump
    Device reported its revision [4.03]
    Manufacturer ID: 00
    Memory Type: 00
    Capacity: 00
    Chip capacity is 1

    cbBulkOut: error : 2

    cbBulkIn: error : 2

  3. I got it working now, I had to use the ch341 on a physical machine running linux rather than a VM.

  4. Dan,

    Thanks for your work! I’m currently trying to disable the write protect on my Thinkpad 13’s W25X40CL. I’ve got the back popped off and can read the chip using flashrom 0.9.9 so I know it’s working.

    Anyway, my question is:
    Can I use your programmer to disable the write protect, and if so how would I do that?

    I understand if I brick it, it’s on me. I appreciate the help!

      1. I busted out the multimeter and WP is tied to VCC. My understanding of the data sheet means the chip does not have hardware write protect, only software.

        Does that seem right?


          1. Dan,

            Dave again. I had to add a few lines of code to do generic status register read/write. It’s a bit hacky but I was able to disable the software write protect!

            Thank you so much for your code! Couldn’t have done it without your work! If there’s a way to send you my code if you wanted to add it, just let me know how.

            Thanks again,

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.