Programming a chip programmer with another chip programmer

Recently I had a need to program a few Atmel ATtiny chips for a project, which I haven’t done in years. I rummaged through my drawers and found the necessary programming device, which is a USBasp device:


When I tried using it to program an ATtiny chip using the standard programming software (avrdude), it showed an error suggesting that I need to update the firmware on the programmer device.

$ avrdude -cusbasp -pt45
avrdude error: cannot set sck period; please check for usbasp firmware update
avrdude error: program enable: target does not answer (0x01)
avrdude error: initialization failed, rc=-1
        - double check the connections and try again
        - use -B to set lower the bit clock frequency, e.g. -B 125kHz
        - use -F to override this check

But the programmer device itself uses an Atmel chip (ATmega8a) that is only programmable using another chip programmer. What to do? Rummaging further in my drawers, I discover this contraption:


It’s an extremely cheap CH341A programmer (~$2 on AliExpress) that I’ve used in the past to dump the contents of BIOS chips on motherboards and video cards. However, perhaps it can be useful here? Looking on the back of it, we can see that it can definitely do SPI (it has MOSI and MISO pins, although the latter is misspelled “MIOS”!). Could it be that this other programmer is also supported by avrdude?


$ avrdude -c\?
Valid programmers are:
  c2n232i            = serial port banging, reset=dtr sck=!rts sdo=!txd sdi=!cts
  ch341a             = ch341a programmer (AVR must have minimum F_CPU of 6.8 MHz)
  dasa               = serial port banging, reset=rts sck=dtr sdo=txd sdi=cts

How fortunate! So, what if we just connect all the relevant pins from this programmer to our target programmer that is receiving the update:


I connected the GND, +5V, MISO, MOSI, CLK (which goes to SCK), and CS (which goes to RESET) pins from the programmer to the target, remembering also to put a jumper on JP2 to enable self-programming. I also obtained the latest firmware to be loaded onto the chip. And here we go:

$ avrdude -cch341a -pm8 -b19200 -U flash:w:usbasp.atmega8.2011-05-28.hex
avrdude error: initialization failed, rc=-2
        the programmer ISP clock is too fast for the target
        - use -B to set lower the bit clock frequency, e.g. -B 125kHz
        - use -F to override this check

Hmm, something about the ISP clock being too fast… but it suggests that we can use -F to override this check. OK, let’s try that:

$ avrdude -cch341a -pm8 -F -U flash:w:usbasp.atmega8.2011-05-28.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9307 (probably m8)
avrdude: Note: flash memory has been specified, an erase cycle will be performed.
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: processing -U flash:w:usbasp.atmega8.2011-05-28.hex:i
avrdude: reading input file usbasp.atmega8.2011-05-28.hex for flash
         with 4700 bytes in 1 section within [0, 0x125b]
         using 74 pages and 36 pad bytes
avrdude: writing 4700 bytes flash ...
Writing | ################################################## | 100% 1.25 s 
avrdude: 4700 bytes of flash written
avrdude: verifying flash memory against usbasp.atmega8.2011-05-28.hex
Reading | ################################################## | 100% 0.79 s 
avrdude: 4700 bytes of flash verified
avrdude done.  Thank you.

Wait, what? It worked! This is much easier than I thought it would be. Thanks, avrdude and cheapo CH341A programmer! I can now program ATtiny chips quickly and easily.


More huge updates to DiskDigger and FileSystemAnalyzer

I’ve finished some major updates to DiskDigger, as well as its companion tool FileSystemAnalyzer, to support a few more filesystems, some more obscure than others!

ReFS support

One of these filesystems represents a serious and substantial update: DiskDigger now has expanded support for ReFS, the Resilient File System introduced in recent versions of Windows Server and Windows Enterprise editions. ReFS remains totally proprietary and undocumented, so it required quite a bit of reverse-engineering to nail down the structures that it uses. I’m happy to report that DiskDigger now supports versions of ReFS starting from 3.0 (introduced in Windows Server 2016) through the very latest version 3.12 (in the latest insider build of Windows 11 Enterprise).


To be clear, DiskDigger had already been able to recover data from ReFS partitions by performing a heuristic (carving) search, which is independent of the actual filesystem on the disk. But now that it understands the data structures of ReFS, it can employ additional specific techniques to recover files more accurately from such partitions.

And on a lighter, more whimsical note, DiskDigger and FileSystemAnalyzer now support two other filesystem types that you’ll likely never encounter in everyday life:

RedSea filesystem

The RedSea filesystem was created by the late Terry Davis as part of his TempleOS operating system. If you’re not familiar with TempleOS, it’s an interesting rabbit hole to delve into. Literally an entire operating system built by a single person over the course of many years, TempleOS is intended to be “god’s third temple” in the form of an operating system, due to the guiding principles behind the operating system that Davis believed he was receiving from god. These principles are largely based around simplicity and purity, which is something that even the most hardened atheist like myself can appreciate. There is an expansive volume of videos in which Davis provides tutorials and explains the various features and design choices of TempleOS.

Terry was a troubled soul: he was living with uncontrolled schizophrenia which led to his eventual demise, and his videos occasionally contain some bizarre and horribly racist commentary, all of which make him more pitiable than admirable as a person. However, he was an undeniable savant at building an operating system, and I will defend the idea that we can learn something from his kernel, his compiler, and his insistence on simplicity. As a tribute to his work, I’m including support for the RedSea filesystem in DiskDigger and FileSystemAnalyzer.

The RedSea filesystem is, in many ways, the simplest filesystem possible:

  • All files are contiguous! There’s no concept of fragmentation.
  • There are no B-trees, no journaling, no symbolic links, no encryption, etc.
  • There’s no concept of clusters; block sizes are the same as sector sizes, i.e. 512 bytes.
  • Directory blocks are just a sequential list of directory entries.
  • For determining where to write new files, there is simply an allocation bitmap, where each bit represents whether the corresponding block is allocated.


One other interesting feature of the RedSea filesystem is that it performs a sort of semi-automatic compression of files, using a form of LZW compression. If you give a file a name that ends with a “.Z” extension, it will be compressed when it’s written to the disk, and then uncompressed the next time it’s read from the disk (transparently to the user). This compression is also supported in DiskDigger, i.e. files recovered from a RedSea partition will be automatically uncompressed.

Commodore 64 disk images

As another fun diversion, I also added support for Commodore 64 disk images (D64 files)! The file system on these disks is thoroughly documented, and is also very simple: files are represented as a linked list of blocks (a primitive “block chain”, as it were). If you have these disk images lying around, you can now peruse their contents!


As with all filesystems supported by FileSystemAnalyzer and DiskDigger, these additions are read-only, since these are intended to be tools for forensic analysis, and not intended for two-way interoperability.

Updates to DiskDigger and FileSystemAnalyzer, October 2023

Usually I post updates about DiskDigger on its own website, but my most recent round of updates merits a slight technical digression.

Previous versions of DiskDigger and FileSystemAnalyzer have already had basic support for 4K-native disk drives, i.e. drives that have 4 KiB sectors instead of the usual 512 bytes. However, only recently have I been able to test this support more thoroughly, fixing a few bugs along the way. 4K-native drives have been around for a while, and in fact most modern drives already use 4K sectors natively under the hood, but simply emulate 512-byte sectors to the outside world. However, increasingly we’re seeing more drives that no longer emulate 512-byte sectors (exposing the native 4K sectors to the operating system), as well as users who are opting to reconfigure the firmware of their drive to use 4K sectors instead of 512-byte emulation. DiskDigger and FileSystemAnalyzer can now handle all of these cases when mounting and searching file systems that might be present on such disks (FAT, NTFS, ext4, etc).

I did most of my testing and experimenting using a real 4Kn drive, but some testing I did with emulated disk images. Here is how you can configure qemu to treat a disk image as a 4Kn drive:

qemu-system-x86_64.exe -machine q35 -m 8G -boot d -cdrom "linux.iso" -drive file=mydisk.vdi,if=none,format=vdi,id=D24 -device nvme,drive=D24,serial=1234,logical_block_size=4096,physical_block_size=4096

The above example boots qemu from an ISO file, which can be a Linux live DVD, and makes the hard disk become a NVMe device, which allows us to configure its physical and logical block size, which we set to 4096. Linux should detect this NVMe device automatically, which will then let you create partitions and file systems on it for experimentation.

The other interesting update has to do with ancient retro file systems that are supported by FileSystemAnalyzer (and by extension DiskDigger). By coincidence, I’ve been contacted by multiple people in a short span of time regarding recovering data from Xenix file systems which they’ve saved as binary disk images. One image is from an Intel System 320 Multibus System owned by Herb Johnson of, and another is from an owner of an Altos 586 system in New Zealand.


Each of these images used a slightly different version of the Xenix file system, each of which use a different structure for their superblock (and each of which is different from the Xenix/SysV support that’s built into the current version of the Linux kernel). This took a bit of effort to reverse-engineer, but ultimately wasn’t too difficult to crack and integrate into FileSystemAnalyzer. The nice thing about dealing with very old data formats is that they’re usually very simple, not to say primitive. Best of all, these Xenix images contain C header files that actually describe their own filesystem structure (can I call them eigenheaders?), which I was able to use for refining and solidifying support for these file systems.


I even learned something else that was new to me: in addition to little-endian and big-endian byte orders, there’s also something called “middle-endian” or “PDP-11-endian”, where 16-bit values are stored in native little-endian order, but 32-bit long integers are composed of two 16-bit words in big-endian order (while the numbers in both 16-bit halves are still little-endian). This was the encoding used by the PDP-11 system, and apparently also by the Altos 586 system which was running this version of Xenix. All of these variations are now supported in FileSystemAnalyzer.

Brain dump, September 2023

I finally did something I’ve been meaning to do for a long time: get the final version of the ftape driver to work on a Linux distro that I can use in my data recovery workstations. This is for the purpose of using Linux to dump the contents of QIC-80 and similar tapes, using “floppy tape” drives, i.e. tape drives that connect to the floppy disk controller on the motherboard.

Up until this point, I’ve been using an old version of Ubuntu that has ftape pre-packaged into the kernel. The problem with this is that this version of ftape is not the latest. Development of ftape seemed to continue independently of the version that was included with the kernel. And the “last” version of ftape that is available (version 4.04a, from around July 2000) contains many enhancements over the version that was in the kernel, which seems to be 3.04, specifically compatibility with parallel port tape drives such as the Iomega Ditto 2GB.

This meant that I needed to compile the driver from source. Sounds simple enough; the driver is just a couple of loadable kernel modules. However, I would need to compile it for a version of the kernel that can boot nicely on my workstation. Browsing the source code of the driver, it appears to be intended to be compiled for kernel version 2.4.x. As an amateur kernel hacker in a previous job, I knew that even patch version changes (the third version number) in the kernel can break compilation of custom kernel modules. So, I tried to find a Linux distro that uses the earliest possible patch version of the 2.4 kernel, and still runs well on my workstation.


CentOS 3.5 to the rescue! I was able to find ISO installation media that I used to install CentOS 3.5 flawlessly onto my recovery workstation. It uses kernel version 2.4.21, which still turned out to be “too new” for compiling ftape successfully. I got a number of compilation errors, but thankfully they were all errors that were comprehensible and easy to remedy by an amateur. After just a few hacky modifications, I got the driver to compile into a loadable module!

And would you look at that – it’s able to communicate successfully with all of my floppy tape drives, as well as my parallel port Ditto 2GB drive!


Here’s my repository on GitHub that has the source code for the ftape driver, with my modifications for getting it to build in CentOS 3.5.

In other news, I found and restored an old ThinkPad X131e, which came to me as a Chromebook, i.e. with ChromeOS installed. In order to remove ChromeOS and install a regular Linux distro, I had to overwrite it with custom firmware that allows installing other operating systems. And in order to overwrite the firmware, I had to disassemble it and flip a physical write-protect switch that allows the firmware to be written. Why do they do this?! Anyway, with the latest version of the lightweight Xubuntu installed, this tiny thing works beautifully, and can now have a second life.


Brain dump, February 2023

As a software archaeologist I often find myself trying out old software that I hadn’t used myself in my own career. I think this can be very instructive, since old software can often have some good ideas built into it, ideas that might have been forgotten, but nevertheless ideas from which we can draw when building today’s software.

Recently I played around with Microsoft QuickC for Windows 3.1, which was a C development environment (IDE) targeted at individual developers, and had a rather modest set of features compared to enterprise-caliber IDEs of the era. Nevertheless my existing knowledge of Windows programming, coming from Windows 9x development and onward, transferred fairly easily onto QuickC, and I was able to develop a sample app fairly quickly:


It’s a Mandelbrot viewer/explorer app, which is one of my favorite “sample” apps to build in a new environment. It runs in any version of Windows 3.x, has no dependencies, and weighs in at 20KB. Here is the source code, if you like!

What struck me about using QuickC is the simplicity and efficiency of it. Even though it still has the familiar issues of native Windows programming — many screenfuls of boilerplate code and having to manually handle message loops and drawing subroutines — after this was out of the way, the sailing was smooth.

Today I make Android apps for a living, and I can’t help but compare the user experience of building an Android app (using Android Studio) to the experience of building old-school Windows apps, specifically in the way of efficiency. The compilation time of my QuickC app was no more than a few seconds (in an emulator that was emulating a 50 MHz PC). Compare this with building a similar Android app, where kicking off a clean Gradle build is a cue to take a coffee break, even on the most modern hardware. Of course over the years the Gradle build process has gotten faster, and the Android folks at Google are quick to award themselves a medal for improving build speeds by a few seconds. Still, it’s only very recently that Gradle has gotten fast enough to finish building a Hello World app in under a minute. I won’t even get into the sizes, now measured in gigabytes, that modern IDEs require to make themselves at home on our workstations, whereas the entirety of QuickC was able to fit on three floppy disks.

Is this kind of level of efficiency and streamlining squarely in the distant past of software tools, or can we in the present day take steps to get back to that spirit?