Posted on 38 Comments

DPF hacking part two

It turned out by some further hacking that we could run a bit more than just patched code bits on these little frames. This is the next step of development, where things are actually getting fun: Running our own firmware on the AX206 chip using the SDCC’s built in bank switching technique.

128x128 DPF firmware
128×128 DPF firmware

As seen in the image, we have a little slow scope running, using the built in ADC. It turns out, that this chip is quite good at power saving, once you activate all possible options to turn off various clocks. It can obviously run for weeks with just the real time clock running, waking up the chip every second, then for example doing something every 30 seconds, then putting it back to sleep.

Also, a few extra modes for lcd4linux were explored, like setting backlight intensity and orientation. On the 320×240 frames that are for example available here, we use the display in portrait mode as seen below.

240x320 USB display hack
240×320 USB display hack

This is not very pleasant to the average user, therefore this solution will need to mature a little before it is actually safe to release.

The full blown framework to build code for the DPFs using SDCC is published here:

SVN access to the sources:

svn co dpf-ax

UPDATE: The bootloading protocol is now decoded. Code can be loaded on bricked frames, find a flash update tool in the above repository. A brief intro how it works:

When the DPF goes into Bootloader mode (showing USB ID 1908:3318), it expects max. 64 byte size USB interrupt messages with a header and payload data. The header implements a simple Remote Procedure Call format through the bootload handler. Its format is as follows:

typedef struct {
	unsigned char len;
	unsigned char chk;
	unsigned char jmp[2];
	union {
		// Structures for various backends
		// The default memory loader:
		struct {
			unsigned char offset[2];
			unsigned char buf[BUFSIZE];
		} loader;
		struct {
			unsigned char opcode;
			unsigned char n;
			unsigned char buf[16];
		} spi;
	} u;
} UsbMsg;


The ‘len’ byte specifies the full length of the USB packet. ‘chk’ is a checksum that is consecutively updated with every packet sent. The ‘jmp’ field contains the jump address of the handler that takes care of the attached data payload. For simple memory writing, the address of the internal ROM memory write routine is used. Once a program (for example flashing routines) is loaded into memory, it can be jumped into using this RPC scheme.

38 thoughts on “DPF hacking part two

  1. I’ve made a preliminary package of the new firmware for testing. Careful, it is yet highly experimental. See also Changelog.


    This now also includes the updated patch for lcd4linux and some instruction on how to “hack” yet unsupported devices. Have fun!

  2. Hi hackfin,

    I tried new firmware with
    But without success
    fw$ sudo python /dev/sg3
    Opening generic SCSI device ‘/dev/sg3’
    Reading flash…
    Found matching version info
    Identifier: focal
    Now patching. There is no 100% guarantee that your device will
    work after doing this. You must never unplug the device from USB while
    it is being updated.
    Are you sure you take all risks and that you want to continue?
    Type ‘yes’ to continue > yes
    Copying sector from 0x000000 to 0x1f0000…
    Patching sector addr 1f0000 with jmptbl_pearl.ihx
    Patching sector addr 180000 with fw_pearl.ihx
    Analyzing module 37…
    CRC32 does not match: 0x2b8aef1c
    DPF might not be completely patched.

    Best regards,

  3. Hi,

    have a look at the reverse/README and check against the source files in http://localhost/files/dpfhack-0.1alpha.tgz. You’ll be on your own there, please have some understanding that we can not provide any support for this stuff.

  4. […] Es gibt eine neuere Version des Dpfhacks hier. Vorsicht: Noch im experimentellen Stadium! Twitter It! < AppoTech, AX206, Bilderrahmen, […]

  5. Thanks for your reply.
    I flashing my dpf, but screen is mirrored (as it is written in
    In future, possible fix it?

  6. Andrey: It wil be fixed, we just have to figure out the proper initialization.

  7. New intermediate release, supporting landscape mode on 320×240 frames.
    To update just the firmware, see script (pass .ihx file as first argument)


  8. For me this does not work.

    On my second frame (which was hacked with 0.10), i can’t run either nor

    sudo ./ /path/to/fw_pearl_landscape.ihx says:

    Found AX206 DPF
    bulk ACK read: Resource temporarily unavailable
    Warning: This firmware can not lock the flash
    bulk data read: Resource temporarily unavailable

    [ more like this erased. Please only post relevant lines next time. ]

    bulk ACK read: Resource temporarily unavailable
    bulk write: Resource temporarily unavailable

    I plugged it in with menu-> enable usb and also in “hacked mode” (long press Menu), same error, both time.

    It still works and is on 0.10.

    P.S.: You forgot Shebang in 😉

  9. I just realized you never put a shebang in anywhere, so that’s okay 😉

  10. # Bad quality, weak screen. Not recommended.
    # Don’t use this one. BROKEN. You will brick your frame.
    # [ (‘20090113’, ‘Jan 13 2011\xff\xff\xff\xff\xff’, ‘ProcTbl3’) ,
    # “focal_silver”,
    # “”,
    # { },
    # [ 0, 0x100000, patch4 ]
    # ]

    I have this one, is there a proper version for this one ?

  11. Quick comments before easter holiday:
    – Try running with /dev/sgX instead usb0 inside the script and not inside developer mode, just by connecting to USB via menu (this requires sudo). For some reason, there are sometimes too many timeouts on the pearl DPFs.
    – The focal silver type is currently not supported, you’re encouraged to try your own hack. My first attempt bricked a frame, so be careful. Since the screen was really bad quality, we didn’t go down that road further.

  12. “- Try running with /dev/sgX instead usb0 inside the script and not inside developer mode, just by connecting to USB via menu (this requires sudo). For some reason, there are sometimes too many timeouts on the pearl DPFs.”

    This does not work. It does not creat a /dev/sdX device anymore since it was “hacked”.

  13. Ups, little type, i wanted to write /dev/sgX device … *

  14. Forgot to mention explicitely, but the README actually tells you: To return to original mode, press RESET. Then you will get back the generic scsi device.

  15. ah okay. I try this later 😉

    But normally it should work with and usb0 – or did I understand something wrong?

  16. Mhh…does not work.
    Resetet is, so that sg0 & sg1 exist again.

    “sudo ./ /dev/sg1
    Opening generic SCSI device ‘/dev/sg1’
    Reading flash…
    No DPF found. Create a record or look for one
    (‘20090504’, ‘Mar 27 2010\xff\xff\xff\xff\xff’, ‘ProcTbl5’)”

    Strange! (/dev/sg0 also does not work, and never did.)

  17. You could just try changing the “pearl” entry in
    There are plenty of firmware revisions out there, maybe we’ll remove the date tag from the detection some time. As long as you don’t mess with the crc, you can’t really destroy things.

    The generic scsi 0 is probably your hard disk. So that’s all fine.

  18. I will try again later 😉

    One Point: /dev/sg0 and sg1 are both(!) from one dpf, none of them is from my hdd/usb.

    Dmesg when I plug dpf in:
    [ 6808.996006] sr 1:0:0:0: Attached scsi CD-ROM sr0
    [ 6809.028232] sd 0:0:0:0: Attached scsi generic sg0 type 0
    [ 6809.036215] sr 1:0:0:0: Attached scsi generic sg1 type 5

    Full log -> at “2) Hacken des DPF”.

  19. Habe die neue version des dpfhacks eingespielt und nun läuft das Display ohne probleme und zeigt keinen roten Balken mehr an.

    Das Display ist durch den hack ja jetzt im Portraitmodus und man hätte nach unten hin einiges mehr an platz. Leider ist es mir noch nicht gelungen das letzte drittel des Displays anzusprechen. Das letzte drittel belibt eibfach blau.
    Ab der Zeile 30 zeigt das Display nichts mehr an ausser einen blauen hintergrund.

    Hat jemand dafür eine lösung oder kann mir helfen den fehler einzugrenzen?

    The new version does not have dpfhacks brought in and now runs the display without problems and indicates red bars more. The display is now in the Portraitmodus and one would have downward some more at place. Unfortunately is not to be addressed me yet succeeded the last third of the display. The last third shows blue. Starting from the line 30 the display shows more on nothing except a blue background. Does someone have for it a solution or can help itself the error to limit?

    MfG: Edgar

    1. Hi, in der v.012 gibt es auch eine Landscape-Version der Firmware.

  20. Ist es möglich den dpfhack wieder rückgängig zu machen und das display wie vorher zu nutzen?

    Is it to be cancelled possible dpfhack again and the display as before to be used?

    MfG: Edgar

    1. Hallo,

      ja, sofern eine Kopie vom Original gemacht wurde, einfach den alten Sektor 4 (0x10000 ab Adresse 0x40000) wiederherstellen. Dabei darf man bloss keinen Fehler machen, sonst bleibt der Frame tot und das SPI-Flash muss extern neuprogrammiert werden.

  21. daumen hoch mit dem 12Devel läuft nun mein 2. DPF auch ohne fehler 🙂

  22. Hi,
    there is a small issue with http://localhost/files/dpfhack-0.12devel.tgz I found out while try building on i686. If you start the script for building lcd4linux ( from fresh extracted tar the buildprocess runs in an Error while linking because libdpf is not found. Looking in dpf/dpflib/ shows that there is nothing compiled. If I type make within this directory the lib compiles. If I then run again the lcd4linux build finnishes and binary runs fine.

    Additional – in dpfhack-0.12devel.tgz it seems not needed starting it with path to dpflib because all is arranged within the script.

    However – great job by hackfin

    1. Hi,
      nowadays you just run “make all” in the unpacked tgz’s toplevel directory, that should do a complete build.

  23. Habe auch das Pearl-Display, scheinbar auch mit einer etwas anderen Firmware (wie auch Evilandi666), nach ändern von

    (‘20090504’, ‘Mar 26 2010\xff\xff\xff\xff\xff’, ‘ProcTbl5’ )


    (‘20090504’, ‘Mar 27 2010\xff\xff\xff\xff\xff’, ‘ProcTbl5’ )

    hat aber funktioniert. Ich komme nur nicht in den devmode, wenn ich MENU lange drücke bei USB drin kommt ein Screen mit blauem Hintergrund, einigen Infos und dem Text “Press MENU for config mode”. Aber in der dmesg steht nur:

    [ 6825.121092] usb 2-2: new full speed USB device using uhci_hcd and address 16

    und nix mit /dev/ttyUSB0 o.ä.

  24. Habe es nach einigem ändern von includes in einigen C-Dateien und kopieren der dpflib nach /usr/include auch endlich hinbekommen, lcd4linux mit dem DPF-Treiber zu kompilieren, hier mal ein mit checkinstall erstelltes Paket (Ubuntu i386):

  25. Hi there,

    I’m getting a lot of messages lately like “my DPF doesn’t work”, “can you fix this”, etc.
    Please have some understanding that we are unable to support other models (or different firmware configurations) than recorded in the python script.


    So please have a look at the provided source on the repository listed above.
    I am happy to accept patches, and solutions, and we’ll of course publish them.
    You can also post detailed issues in the sourceforce forum.

  26. I have a question about flashsize parameter in the structures:

    [ (‘20090113’, ‘Sep 16 2010\xff\xff\xff\xff\xff’, ‘ProcTbl4’), # Version
    “DX_white”, # Short ID
    { },
    # Patch information follows here:
    # Type/Version, flashsize, patchseq
    [ 0, 0x100000, patch_white ]

    How to know what is the correct flash size? There is 0x100000 but this model has 16MB built in flash.
    I’m preparing to hack a new model but before trying to understand what is actually going on.
    “Adapt the .org statements to the locations where YOUR patched code can safely live. ” – is there any quick method to find a proper free place in memory?

  27. Hi,

    the script detects the flash size. So once you do a firmware dump (what you should always do first), you’ll know how big the flash is.
    Note that almost every DPF vendor kinda cheats on the flash size, they insinuate MegaByte, but in fact it’s megabit. Very likely that your “16MB” model has in fact only 2MByte of flash memory.

    There is no quick method to find the right place, you really have to analyze the disassembled firmware dumps.

    Aside from that: GOOD NEWS WERE BROUGHT.

    We can finally recover from bricked DPFs without having to externally reprogram the SPI flash.

    The guys at have published the ProgSPI tool that allows flashing of naked/bricked DPFs. However, you may have to adapt the flashlib.ini to make your flash recognized. Waiting for someone to snoop on the protocol and make a better working command line tool.

    Read more on the site above.


    – Strubi

  28. Hackfin,

    great work.
    Would be great if we get a firmware, that could be used at power up for lcd4linux. I have seen your comment at openschemes. Looks that you are on the way. If anything is to test, my dockstar and VDR are waiting.


  29. I just picked up a couple of clearance LCD keychains from Walgreens for fun, and stumbled upon this site and a few others. I’ve identified them as using the ax206.

    As a test, I was able to flash a full Colby dump using the ProgSPI with limited success (the next and previous buttons no longer worked, only menu and reset).

    From there, I’ve been trying to figure out what to do next, but I need a little boost. I set up a fresh install of Linux Mint, pulled the svn for DPF-AX, and tried “make all”, and then installing whatever dependency it failed on.

    Right now, it will actually finish the whole script, but it does show an error for “import intelhex” in the file. I’m sure this is a simple problem, but I can’t seem to find the solution.

    To be honest, I’m not even sure what I will get if I can ever get it to compile. Will it pop out a mostly working firmware that I can start hacking on?

    Anyone know of any new news on the scene?

  30. Poo. I just looked at it with fresh eyes and figured out how to install intelhex. That’s what I get for staying up all night.

    Now, the only warnings I’m getting are unreferenced function for handle_getprop in lcd.c:207 and fill_rect in prop.c:41, and some “ignoring return value of ‘fgets'” near the end. These don’t stop the compiling process, so I’m guessing these are trivial?

    Compiling finished. Now I just need to figure out what I made. 🙂

  31. I’ve played around with different versions of the sources.
    What is the meaning of the “flix” option in the menu of the 0.12 version ?

    Is there any possibility to stream video to the device ?

    [In the picframe project there was a patchset for mplayer using the st2205u chip – don’t want to try having it compile against recent mplayer sources, if it is not for sure that the ax chip would work as well.]

  32. I dont understand about the patching process in reverse.

    6. This routine you can patch. Take a p_start_*.s from an already hacked frame
    and make sure you understand what is happening. Adapt the .org statements
    to the locations where YOUR patched code can safely live.

    Do I have to only put the .org lines into the code.

    How do I know the correct place.

  33. hi,
    1) kudos to hackfin for this grat hack
    2) i bought the DX-frame which looks similar to the Pearl-One
    3) after playing around with the dump of the firmware i noticed that it is indeed very similar to the one from pearl.
    4) the pearl-hack does not work
    5) the jump-adresses look the same as the pearl
    6) i modified by adding my device. i cloned the pearl, new profile for patch is

    # DX like Pearl
    patch_dx320x240 = [
    (COPY, [0x000000, 0x1f0000]), # Copy sector 0
    (PATCH, [0x0, 0x1f0000], “jmptbl_pearl.ihx”),
    (BINARY, [0x0, 0x190000], “font4x8.bin”),
    (PATCH, [0x0, 0x180000], “fw_pearl.ihx”),
    # new crc here:
    (37, [ 0xcf547e21, 0x9ef54e54, 0xf0e0beea ], “p_start_pearl.ihx”),


    [ (‘20090504’, ‘Mar 31 2011\xff\xff\xff\xff\xff’, ‘ProcTbl5’),
    “DX like pearl 320×200”,
    “url goes here”,
    { },
    [ 0, 0x200000, patch_dx320x240 ]
    7) the hack works – BUT the image is mirrored. not optimal but i plan to hack something with mirrored images via imagemagick – schould be ok for my purposes…
    8) i was working with dpfhack-0.12devel.tgz
    9) anyone ported/crosscompiled the lcd4linux to openwrt already.. this will be next…

    thanks again for this awesome hack. reading the docs in “reverse” was big fun 🙂


  34. Hi guys,

    let me collect the stacked up questions and give a quick general answer:

    – The dpfhack-0.12 docs are somewhat outdated with respect to bricking your frame: IT IS NO LONGER a problem to recover the firmware, as long as you have the ProgSPI.exe tool recognize your flash type, see openschemes link above.
    – There are many DPFs even from the same vendor that have different screens using different command sequences. The mirrored screen has been seen before. It is a bit of detective work identifying the screen type, but pulling the initialization sequences and screen addressing from the disassembly is the easiest method.
    – We have some ideas about automatical screen testing, i.e. something like a wizard that tries different screen configurations and asks you if the image looks ok. But we all have a real job, too…

    Bottomline: for now you’re left with having to continue hacking on your own. Please don’t send assembly dumps via email, etc., we simply have no time left to look at them.

  35. hi,

    I also got a mirrored screen with latest version 0.12devel: when the blue screen starts all is fine but after connecting lcd4linux the screen is mirrored and keeps in this state until reset.

    But it seems to be a driver problem:
    I figured out if you are using recent 0.12devel firmware with old lcd4linux dpf driver from dpfhack-0.1alpha.tgz the screen IS NOT mirrored !!

    Very nice hack , thank you !!!

Comments are closed.