Paragliding in Hammar, southern Sweden

Magnus Olsson

DMTECH Photoframe

What is it?

This is an attempt to reverse-engineer the software of a DMTECH DPF-701 (Digital Photo Frame). You can get these for about 300 SEK at Kjell&Co in Sweden, making it an affordable multi-purpose standalone mini-LCD/status-gadget if you could somehow modify the firmware to allow LCD control over USB (or IR..).

Key features

The box states the following features:


Except for the main SoC, the photoframe PCB also holds 2 MB of NOR flash memory (EON F-16 100HIP) and 16 megabytes of SDRAM (WINBOND W98-series, partno W9816).

Haier HiPatriot Hi1018

The main chipset is Hi1018 (HiPatriot). This is a SoC manufacteured by Haier IC Design, a Beijing based company specialized in digital audio, video decoders and digital television. There are no publicly available datasheets for this chipset but Google reveals a bit of interesting information.

Blockdiagram Hi2028, a similar platform to Hi1018

Blockdiagram of Hi2028, supposedly a platform similar to Hi1018. Hi1018 does not contain the hardware MPEG decoder datapath (crossed out in red in figure above)

Many of these features are not usable on the photoframe (such as ethernet/networking), audio playback nor the NES emulator since they are not routed on the PCB.


There are a few labeled test-points on the PCB. These often provide useful debugging information for the developers, but can also help to understand the platform for anyone else. On more generic platforms, like your typical home-consumer network equipment, 9 out of 10 contains serial port testpoints which provides shell access to the operating system.


The following image is an attempt to map the Hi1018 pinout to its corresponding function on the PCB. Hi1018 pinout
Pin 10 = Routes to testpoint TXD (see above) Pin 11 = Routes to testpoint RXD (see above)

Extracting the flash memory contents

The shippingbox states 16 Mbit of internal for photo storage, however the userguide also mentions "Not full capacity can be used for photo storage, subject to the sharing of internal software". The swedish translation is better and it clearly states that the firmware is located on the flash (in contrast to an on-chip ROM, which is kind of a showstopper for any kind of modifications).

To disassemble the firmware and gain a better understanding of how the hardware works, it needs to be extracted from the internal flash memory.

Related links

Similar projects

What is it?

DPS Promatic AWS weatherstation

During the summer of 2010 I discovered the wonderful world of paragliding and shortly thereafter joined the local paragliding club Club Parapente Syd (CPS). To better track current weatherconditions at our most popular flying sites, CPS manages four weatherstations. These are accessible through phone and the current wind speed, direction and air temperature is read by a synthesized voice as you place a call to any of the stations.

One of the stations (DPS AWS-X, pictured to the right) support transmission of samples over GPRS/Internet, so I started experimenting with webpage publishing for easier access. I created a piece of software to receive, decode and place the samples into a database. The samples are later visualized and plotted through a webpage (swedish only).

WindWeb screenshot

The website quickly became popular among the CPS members and I started investigating ways of hooking up the other stations to the webpage in a similar way. Unfortunately, they are quite old and the legacy hardware does not support any kind of GPRS packet transmission.

Purchasing new stations to replace the old ones proved very costly, so instead I started designing a station on my own. WindWiz was born. WindWiz is an umbrella project for a scalable weatherstation system. It contains a piece of minimal sensor hardware with GPRS support. It also contains a generic version of the above mentioned software to collect and visualize samples. Finally, it also contains backward compatibility support for the commercial station I originally started experimenting with (DPS AWS-X).

The goal of this project is create a network of weatherstations to be deployed along the coasts of southern Sweden, and possibly at other locations. Weather samples collected by the sensor network should be transmitted back to a central server where it is stored in a database and later published to the web. It should be accessible both as webpages, from cellphones and to thirdparty applications. Everything should be open-sourced and the components required to construct the hardware must be easy to obtain (off-the-shelf).

WindWiz projects

Click here to view WindWiz workblog (swedish only). All projects are organized at GitHub.

What is it?

Hashauth is a set of tools that helps you manage your passwords. Hashauth differs from traditional 'password managers' by deriving your passwords from mathematical functions (hash functions) rather than storing them on disk, and thus is completely liberated from password databases.

Key features

Why would I want to use it?

Users are notorious for choosing obvious and weak passwords; Passwordstrength is difficult to achieve by manually choosing a password, but in turn, generated passwords are tedious to remember.

However, a single strong password may not be enough. Using the same password for multiple resources only becomes as strong as the weakest link.

It is naive to believe that account information is stored in a secure encrypted form at all times. In fact, many websites out there still keep passwords in plaintext, which will render your strong password useless if the site is compromised. When the same password is used for multiple services, a malicious user may gain access all your accounts by attacking the weakest link.

How do I use it?

Hashauth uses generated passwords, and so you need to replace all your existing passwords with new ones generated by Hashauth. To generate a new password, point your browser to

You may also download your own copy of HashAuth and use locally. HashAuth is written in JavaScript and thus does not rely on any serverside magic to run. The latest stable version of Hashauth is v1.0, click here to download.

To obtain the unstable (latest) version of Hashauth, clone the Hashauth JS git repository:

git clone git://

Field description


To speed up re-generation of your passwords, profiles can be created which automatically fills in the Salt, Output length and Hash engine given a resource string. This reduces the amount of human input by sacrificing a bit of 'privacy'.

To attach a profile, enter the JSON encoded profile filename and press the "Attach profile" button. HashAuth will then load the file using an AJAX call and parse the contents. Please note that most browsers disallow AJAX requests outside the local domain, so your profile file must be located on the same domain where HashAuth is hosted. With a valid profile loaded, HashAuth will attempt to autocomplete the resource string and fill out the necessary values whenever a match is made.

Please note that the profile file is useless without the master password, which is NOT stored anywhere by HashAuth. A profile file can however reveal certain information if someone finds the file:


PEEX synchronization

What is it?

Python wEbpage EXchanger (PEEX) is a non-interactive FTP client for updating webpages. Peex is an utility designed to automate the task of remotely maintaining a web page or other FTP archives. It will synchronize a set of local files to a remote server by performing uploads and remote deletes as required. Peex is heavily inspired by Weex with the important difference that Peex does not try to cache remote directory structures locally. This makes it more cooperative with alien files introduces by 3rd parties. It also enables multiple developers to collaborate more efficiently.

Key features

Peex is unique in that it can protect 3rd party generated content on your server. A typical scenario is content uploaded by users on your webpage. Using a traditional synchronization tool, these files will be flagged as 'obsolete' (since they are not present in your local tree) and incorrectly removed during the synchronziation.

Example: Consider a webpage where users can upload profile images for their useraccounts. New content is added to the remote tree which should not be removed if a new version of the PHP script (uploadscript.php) is to be synchronized.

Local Tree              Remote Tree
-----------             -------------
.                       .
|-- avatars             |-- avatars
|   `-- user0.png       |   |-- user0.png
|                       |   |-- user1.png      (incorrectly flagged as obsolete)
|                       |   `-- user2.png      (incorrectly flagged as obsolete)
|                       |
`-- uploadscript.php    `-- uploadscript.php

Surprisingly few synchronization tools support this use-case in a good way.

Whats wrong with existing synchronization apps?

Most apps build up a local cache of the remote file tree as files are initially put into place. Files added to the remote tree by 3rd party will be ignored since they are not in the cache. In other words, they only care about content they've put into the remote tree (sane logic).

This is how Weex and several other apps work. While they do support the above case, it is not a very robust solution. If the local cache is lost, there is no way of separating obsolete local files and content added by 3rd party.

Weex and others fail when:

PEEX tries to work around this by not maintaining a local cache. Instead it refreshes the remote tree before each synchronization and relies on a set of regular expressions to detect files which should not be flagged as obsolete.

While this becomes considerably slower than a local cache, it provides a more reliable solution.

For very large single developer trees or trees where no 3rd party is involved, you should use Weex.


PEEX v1.0 is available for download here.

To obtain the unstable (latest) version of PEEX, clone the PEEX git repository:

git clone git://

How to setup and use PEEX

PEEX is configured partly through commandline switches and partly through config files. The config files contain per-project settings and the command line switches are more general options.

Run PEEX without any arguments to show available commandline switches and its description.

Once the configuration file is setup, synchronization is started by issuing:

$ mysite.peex

It is recommended to set restrictive file permissions on your PEEX configs as they contain sensitive account details. E.g.

$ chmod u=rw,o=-rw,g=-rw mysite.peex

For a little bit more details on progress, use:

$ -v mysite.peex

For colored output use:

$ -c -v mysite.peex


Configuration fileformat (one per project)

source=<source directory on local disk e.g. /home/user/myfiles/>     
dest=<destination directory on FTP e.g. /www_files/>


The exceptions section lists files which should either be protected on the
server, or ignored in the local tree.

Example patterns:


What is it?

D-Link DSL-504T PCB+Case

The D-Link DSL-504T is an AR7-based MIPS 4KEc ADSL router designed for home and small office use. They are quite hack friendly with a pre-soldered serial connector and announced OpenWRT support (as of v8.09). This means that you can re-install a vanilla kernel on the device, and customize it to be much more than just a ADSL router.

On this page, you will find instructions on how to install and configure OpenWRT to replace the DSL 504-T stock firmware. Please note that re-flashing your device with a 3rd party firmware voids your warranty, and you also risk completely bricking your device. I take no responsibility for whatever damage the following procedure may cause on the device (or you :)

If you run into problems, a useful resource is the #openwrt channel on FreeNode where a lot of senior embedded developers hang out to discuss OpenWRT and related topics.

DSL 504-T hardware features

Installing OpenWRT

Until I get around writing detailed instructions for this section, you can find pre-compiled DSL504-T OpenWRT images at (look for openwrt-ar7-squashfs.bin in the kamikaze/*version*/ar7 directory). These images are configured to allow your DSL504-T to act as a router, much like your old stock firmware. It does however NOT include a web interface, and so you need to configure most aspects of the system manually through SSH. If you are familiar with Linux, this should not be an issue.

If you wish to build a completely customized image, you can checkout the complete OpenWRT tree from their SCM at I recommend that you have at least basic knowledge in build-systems and some experience with embedded development (in particular, understanding the concept of cross-compiling) before doing this.

Console access

Even though console access isn't required to reflash the device, it can be an invaluable tool for developers. It can be used to inspect early kernel messages and to debug low-level subsystems. If you wish to interact with the ADAM2 bootloader prompt (Hello World-example application), a serial cable is required. If your only plan is to replace the stock firmware with an OpenWRT image, the ADAM2 FTP flashing capabilities are sufficient, but for all other purposes you should consider hooking up a serial cable to target.

USB to serial cables are usually available off-the-shelf in many electronics stores. I recommend getting a cable based on one of the FTDI USB to serial chipsets, as they are known to work well with Linux. Have a look at for more details on what you need.

The console can be accessed through the pre-soldered serial port connectors found on the PCB. Pinlayout is RX, GND, +5V, GND, TX. For your convenience, I have marked the UART pins with labels in this PCB photo. To connect, use any serial terminal client: On Windows, I prefer PuTTy (recent versions support serial ports), for Linux minicom works fine (albeit a bit clumpsy). You need to set up the connection to use no flow control, a baudrate of 38400, 8 databits, no parity and one stopbit (38400 8N1).

To verify the connection, try rebooting the device and look for ADAM2 messages and/or Linux kernel output. A common mistake is to mix up the RX and TX pins. If the terminal is silent while your system boots, try swapping pin 1 with 5.

Related links

Stock firmware boot-sequence output

The stock firmware appears to be running a Linux 2.4-based MontaVista kernel.
ADAM2 Revision 0.22.02 (C) Copyright 1996-2003 Texas Instruments Inc. All Rights Reserved. (C) Copyright 2003 Telogy Networks, Inc. Usage: setmfreq [-d] [-s sys_freq, in MHz] [cpu_freq, in MHz] Memory optimization Complete! Adam2_AR7RD > Press any key to abort OS load, or wait 5 seconds for OS to boot... Launching kernel decompressor. Starting LZMA Uncompression Algorithm. Copyright (C) 2003 Texas Instruments Incorporated; Copyright (C) 1999-2003 Igor Pavlov. Compressed file is LZMA format. Kernel decompressor was successful ... launching kernel. LINUX started... Config serial console: ttyS0,38400 CPU revision is: 00018448 Primary instruction cache 16kb, linesize 16 bytes (4 ways) Primary data cache 16kb, linesize 16 bytes (4 ways) Number of TLB entries 16. Linux version 2.4.17_mvl21-malta-mips_fp_le (Jenny@products.adsl) (gcc version 2.95.3 20010315 (release/MontaVista)) #60 Tue Sep 21 10:10:24 CST 2004 Determined physical RAM map: memory: 14000000 @ 00000000 (reserved) memory: 00020000 @ 14000000 (ROM data) memory: 00fe0000 @ 14020000 (usable) On node 0 totalpages: 4096 zone(0): 4096 pages. zone(1): 0 pages. zone(2): 0 pages. Kernel command line: the pacing pre-scalar has been set as 600. calculating r4koff... 000b71b0(750000) CPU frequency 150.00 MHz Calibrating delay loop... 149.91 BogoMIPS Freeing Adam2 reserved memory [0x14001000,0x0001f000] Memory: 14568k/16384k available (1344k kernel code, 1816k reserved, 111k data, 48k init) Dentry-cache hash table entries: 2048 (order: 2, 16384 bytes) Inode-cache hash table entries: 1024 (order: 1, 8192 bytes) Mount-cache hash table entries: 512 (order: 0, 4096 bytes) Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes) Page-cache hash table entries: 4096 (order: 2, 16384 bytes) Checking for 'wait' instruction... unavailable. POSIX conformance testing by UNIFIX Linux NET4.0 for Linux 2.4 Based upon Swansea University Computer Society NET3.039 Initializing RT netlink socket Starting kswapd Disabling the Out Of Memory Killer devfs: v1.7 (20011216) Richard Gooch ( devfs: boot_options: 0x1 pty: 32 Unix98 ptys configured Serial driver version 5.05c (2001-07-08) with no serial options enabled ttyS00 at 0xa8610e00 (irq = 15) is a 16550A ttyS01 at 0xa8610f00 (irq = 16) is a 16550A block: 64 slots per queue, batch=16 PPP generic driver version 2.4.1 avalanche flash device: 0x400000 at 0x10000000. Amd/Fujitsu Extended Query Table v1.0 at 0x0041 Flash Vender ID=1f Physically mapped flash: JEDEC Device ID is 0xC8. Assuming broken CFI table. Physically mapped flash: Swapping erase regions for broken CFI table. number of CFI chips: 1 Looking for mtd device :mtd0: Found a mtd0 image (0xa0000), with size (0x350000). Looking for mtd device :mtd1: Found a mtd1 image (0x10000), with size (0x90000). Looking for mtd device :mtd2: Found a mtd2 image (0x0), with size (0x10000). Looking for mtd device :mtd3: Found a mtd3 image (0x3f0000), with size (0x10000). Looking for mtd device :mtd4: Creating 4 MTD partitions on "Physically mapped flash": 0x000a0000-0x003f0000 : "mtd0" 0x00010000-0x000a0000 : "mtd1" 0x00000000-0x00010000 : "mtd2" 0x003f0000-0x00400000 : "mtd3" NET4: Linux TCP/IP 1.0 for NET4.0 IP Protocols: ICMP, UDP, TCP, IGMP IP: routing cache hash table of 512 buckets, 4Kbytes TCP: Hash tables configured (established 1024 bind 1024) Linux IP multicast router 0.06 plus PIM-SM NET4: Unix domain sockets 1.0/SMP for Linux NET4.0. NET4: Ethernet Bridge 008 for NET4.0 VFS: Mounted root (squashfs filesystem) readonly. Mounted devfs on /dev Freeing unused kernel memory: 48k freed serial console detected. Disabling virtual terminals. console=/dev/tts/0 init started: BusyBox v0.61.pre (2004.09.21-02:14+0000) multi-call binary Starting pid 9, console /dev/tts/0: '/etc/init.d/rcS' Standard Configuration File proc write:Calling Configuration Number of State module = 1 STATE = 1 STATE = 2 STATE = 3 STATE = 4 module = 2 STATE = 1 STATE = 2 module = 3 STATE = 1 STATE = 2 STATE = 3 module = 5 STATE = 1 STATE = 2 STATE = 3 module = 6 STATE = 1 STATE = 2 STATE = 3 module = 9 STATE = 1 STATE = 2 STATE = 3 STATE = 4 STATE = 5 Elements = 20 Total Length = 164 Using /lib/modules/2.4.17_mvl21-malta-mips_fp_le/kernel/drivers/atm/tiatm.o registered device TI Avalanche SAR Initializing DSL interface size=10120 size=39040 size=46688 size=45280 Texas Instruments ATM driver: version:[] Using /lib/modules/2.4.17_mvl21-malta-mips_fp_le/kernel/net/bridge/bridge.o NET4: Ethernet Bridge 008 for NET4.0 Waiting for enter to start '/bin/sh' (pid 36, terminal /dev/tts/0) Please press Enter to activate this console. Sep 8 12:00:05 cm_monitor: Monitor Starting logic: /proc/led_mod/ar7reset: [0] tree_parse_file: /etc/sysdef.xml tree_parse_config:/dev/ticfg Logger: Setting remote_loglevel=notice (5) Setting loglevel=notice (5) ===>bridge set ZIPB_MODE deactive in init time_init: syncmode:0, daylight:2, timezone:46 ip_tables: (c)2000 Netfilter core team ip_conntrack version 2.0 (128 buckets, 1024 max) - 364 bytes per conntrack Sep 8 12:00:11 cfgmgr(fdb)> Firewall NAT service started rfc2684_start(nas0): AutoPVC feature is activated rfc2684_load(nascccc1 0): 8.35 /sbin/ifconfig nas0 hw ether 00:0F:3D:F4:75:73 ===>bridge ZIPB disable ZIPB............ FLAG: 2 notify kernel event successful! Sep 8 12:00:14 cfgmgr(bridge)> Bridge Created: br0 device eth0 entered promiscuous mode br0: port 1(eth0) entering learning state Sep 8 12:00:15 cfgmgr(bridge)> Bridge Interface Added: eth0 Sep 8 12:00:15 cfgmgr(sar)> DSL Carrier is down br0: port 1(eth0) entering forwarding state br0: topology change detected, propagating
AVR chipset

What is it?

Magboot is a bootloader for the Atmega-family of Atmel processors. It provides the ability to write the onboard flash memory over the serial port. It can be used to flash an AVR device with new firmware without a dedicated ISP programmer device.

Key features

Why would I want to use it?

Valid question! Prior to creating Magboot I sorted through the massive amounts of bootloaders available for download. In the Arduino sourcecode repository alone, there are over 5 different bootloaders all with different features. Some are tiny, some can boot in exotic ways while others contain boardspecific stuff.

With all this configuration, and well, to be honest, messy code, it quickly becomes difficult to edit or debug for someone other than the author. I ran into some issues with the reset mechanism of the Arduino stockbootloader which forced me to debug the code. It was not pleasant!

I created Magboot to be as simple as possible. It cannot deal with anything other than raw binaries. It doesn't do EEPROM. It doesn't support any official programmer protocol or AVRdude. It is very minimal yet without any obscure code tricks nor assembly to optimize for size. It was written with readability in mind.

If you want a simple, easy-to-use serial bootloader for your Atmega-based project, Magboot might just be what you're looking for!


To obtain the unstable (latest) version of Magboot, clone the git repository:

git clone git://

Optionally you may browse the source-code here. Please refer to the README-file for detailed installation instructions.

Valid XHTML 1.0 Strict