dn2_firmware_explore

by angellinares·Mod

A repository to experiment on the Elektron DN2 firmware

Works withDigitone II
Updated 12 hours ago
dn2_firmware_explore
Preview picture from GitHub

About

Tools for inspecting and rebuilding Digitone firmware, plus a growing set of mods for the Digitone II on OS 1.11. You can apply the mods in your browser or on the command line.

Highlights
  • lfo4: a fourth LFO under [MOD], kept with the project and across power cycles
  • arpmodes (SHUF and RAND), midiarp (the arpeggiator on MIDI tracks) and more MIDI options
  • fxmod: LFOs can modulate 24 chorus, delay and reverb parameters
  • moddest and lfowaves: more LFO destinations and seven new waveforms, three of them your own wavetables
  • Browser patcher: runs in your browser, nothing is uploaded, same result as the command line

What you need
A Digitone II on OS 1.11 and your own OS file from Elektron. The command line tools need Python 3.11 or newer.

Good to know
The README marks most mods as confirmed on hardware and lists the state of each one. Check its compatibility matrix before combining several mods. The inspection tools also read Digitone MKI / Keys images.

README

dn_firmware

Tools for inspecting, modifying and rebuilding Elektron Digitone firmware — the Digitone II (DN2) and the original Digitone / Digitone Keys (DN1) — and a set of mods for the Digitone II built with them.

This repository holds code and documentation only. It contains no Elektron firmware, original or modified, and never will. Bring your own OS file — the one Elektron publish for your instrument. Every mod applies to your copy of it, and checks that copy is the one it was measured against before it writes.

Mods for the Digitone II 1.11

Applied with dnfw mods apply, or in the browser on the project site, https://angellinares.github.io/dn2_firmware_explore/, which runs entirely in your browser, with nothing uploaded. The browser and the command line produce the same file, byte for byte; that is tested.

Mod What it does Status In the browser
lfo4 A fourth LFO under [MOD], like LFO1–3. Modulates on every voice; kept by SAVE PROJECT and across a power-cycle confirmed on hardware yes
arpmodes SHUF and RAND as real arpeggiator modes confirmed on hardware yes (#131)
fxmod An LFO can be aimed at 24 Chorus, Delay and Reverb parameters confirmed on hardware yes
moddest 13 more per-voice parameters open as LFO destinations confirmed on hardware yes
lfowaves Seven new LFO waveforms, three of them your own wavetables confirmed on hardware yes
midiarp The arpeggiator on MIDI tracks confirmed on hardware yes
layermidi TRACK WILL TRIGGER onto a MIDI track plays it over MIDI: notes, chords, releases confirmed on hardware yes
arpplocks MODE, SPEED, RANGE and N.LEN lockable per trig confirmed on hardware; changed since, emulator-checked no
bootscreen Your own mark in the start-up animation confirmed on hardware yes
transients Replace the FM drum transient bank with your own samples confirmed on hardware yes
songguard A song with a damaged row count loads as empty instead of halting the instrument (a stock bug) confirmed on hardware no

Combining them. dnfw mods matrix tries every pair in both orders and writes the result into docs/mods-compatibility.md and the site. Most pairs combine freely; a few need an order (dnfw mods apply applies them in it), and lfo4, lfowaves and bootscreen exclude each other because each needs the start-up hook. One pair has been flashed together and confirmed on the instrument: bootscreen + layermidi (2026-10-02, docs/flashing.md).

Old projects that halt on load: a project with a damaged song row count halts even stock 1.11 on load (EXCEPTION DS0059). The songguard mod bounds the count, and it is confirmed on the instrument (docs/old-project-load.md).

In development: Waverider, a wavetable machine for the Digitone II modelled on Tonverk's Wavefinder (docs/waverider-feasibility.md). A baked table has been read back on the instrument (Milestone 0), and Milestones 1–4 run offline in digikit's SHARC emulator: our own SHARC reader, inside a real DN2 voice, through the per-track chain, with its tables baked into the DSP image. The first flashable build is Milestone 5.

Install and run

Python 3.11+, no dependencies.

pip install -e .
dnfw inspect 00_Resources/00_Firmware/Digitone_II_OS1.11_dist.zip
dnfw mods apply Digitone_II_OS1.11.syx --mod lfo4 -o modded.syx

Or without installing: PYTHONPATH=src python -m dnfw.cli.main ...

A .zip as Elektron ship it is accepted anywhere a .syx is.

Commands

Command Does
dnfw inspect <image> report transport, container, sections and every integrity field
dnfw extract <image> -o DIR write each section out, depacked where it is compressed
dnfw build <image> -s 3=FILE -o OUT rebuild with a replaced section, recomputing every checksum
dnfw diff <a> <b> compare two images section by section
dnfw mods list / apply / extract the mods above: list them, apply them, extract their factory content
dnfw mods matrix <image> try every pair of mods and report which combine
dnfw patch list / apply declarative single patches with stock-byte guards
dnfw params <image> find and dump the instrument's parameter table
dnfw symbols / symbolmap <image> the C++ names GCC left in the image; a Ghidra seeding script
dnfw disasm <image> ADDR [N] disassemble a span (ColdFire V4e, via objdump)
dnfw validate-disasm <image> ADDR [N] check another disassembler against objdump
dnfw cave <image> find free space and size a hook for a code-cave detour
dnfw fn <image> ADDR count direct callers of an address, or find the function containing it
dnfw ldr <image> walk the SHARC program (section 7) as an ADI boot stream
dnfw waverider ... Waverider's tables: scan and reduce WAVs, bake, render a reference, build a frame

build, patch apply and mods apply re-load and re-verify their own output before writing it. Nothing leaves this tool that it cannot check.

How a change is checked before it reaches an instrument

  • Integrity: every checksum and the HMAC-SHA256 signature are recomputed and re-verified on the rebuilt file.
  • Boot from reset in an emulator: scripts/emu_boot_check.py, on digikit's ColdFire emulator, against a stock control. A snapshot of a machine that has already booted does not count (docs/emulator.md).
  • The engine and save/load: scripts/emu_boot_engine.py runs the audio engine's evaluator and a stored sound through LOAD and SAVE.
  • ColdFire encodings: scripts/check_coldfire.py rejects an addressing mode the chip refuses and generic emulators run.
  • Per-mod harnesses under scripts/emu_*.py, each with a stock control.
  • DSP code runs offline in digikit's SHARC runner and is compared with a Python reference (scripts/sharc_waverider_*.py).
  • On the instrument: each hardware test has a written pass and fail in the project's test plan before anything is flashed. The recovery route (stock through the Early Start-up Menu) is proven; send it over a clean MIDI link (docs/flashing.md).

What the firmware is

Measured from the images. Evidence in docs/ele3-format.md and docs/mainos-image.md.

  • An ELE3 container inside a block-streaming SysEx transport.
  • Sections compressed with an aPLib variant. MAIN OS loads at 0x40000400: big-endian ColdFire V4e code, built with GCC and still carrying its C++ RTTI names. Section 7 is the SHARC+ DSP program, as an ADI boot stream.
  • The DN2 container is signed with HMAC-SHA256, keyed from material in the image itself, so a modified image can be signed correctly. The DN1 container is unsigned: its trailer is 32 zero bytes.
  • The +Drive is a 32 GB eMMC with no filesystem: fixed slots for projects, presets and kits, and about 21 GiB the stock firmware never touches (docs/drive-storage-research.md).

Testing

pytest -m "not slow"     # the fast set
pytest                   # everything, a few minutes

Gate F needs an m68k objdump; on Windows, wsl -u root apt-get install -y binutils-m68k-linux-gnu. The browser parity tests need Node. The emulator gates need digikit (docs/emulator.md). Tests that need something absent — the OS images in 00_Resources/, objdump, Node — skip and say so.

Documentation

File Subject
docs/PRINCIPLES.md how code here is built, and why
docs/mods.md every mod: what it changes, how it was verified
docs/mods-compatibility.md which mods combine, generated by dnfw mods matrix
docs/flashing.md the recovery path, and the order hardware steps happen in
docs/emulator.md running builds in digikit's ColdFire emulator
docs/instruments.md which tool answers which question
docs/lfo4-build-plan.md the whole LFO4 story, including the dead ends
docs/waverider-feasibility.md Waverider, milestone by milestone
docs/drive-storage-research.md the +Drive, and where a sample library could live
docs/ideas-backlog.md ideas, costed, with their state
docs/ele3-format.md the transport, container, codec and integrity layers
docs/mainos-image.md the CPU, the load address, and which disassembler to trust
docs/sharc-voice-path.md the DSP voice path, as measured in the runner
docs/references.md prior art, what each is good for, and its licence

Licence

GNU AGPL-3.0-or-later. Use it, fork it, change it; keep the notices and pass on the same freedoms. A modified version you distribute — or run as a service — stays open. Same licence as DNX, for the same reasons.

Parts of it derive from MIT projects, whose notices are carried in THIRD-PARTY.md.

Credit

The container, transport, codec and integrity work stands on mischa85/elektron-firmware-tool (MIT). The patch model comes from bryantysinger/octa-bt-pt (MIT), and the ColdFire disassembly findings from sambanks/octabam (MIT). The ColdFire and SHARC emulators are m-dwyer/digikit's (GPL-2.0-or-later), used as external tools; our own SHARC code is assembled with js216/selache (GPL-3.0). The Digitone data formats come from the sibling project DNX. What was taken from each, and where this project deliberately diverges, is in docs/references.md.

None of them is affiliated with Elektron, and neither is this. Everything in docs/ was measured from OS files Elektron publish; no Elektron code has been copied into this repository and no firmware is redistributed by it.

Pictures in the README load from GitHub.

Language
Python
License
GNU Affero General Public License v3.0
Stars
13
Forks
3
Created
09-07-2026
Last commit
12 hours ago

Added by Neutron on Yesterday · History (1 version)




User Profile Send Private Message E-mail Find all posts Find all threads Mod Tools Admin Tools