Custom Firmware on the OP-1

First things first. A disclaimer:

Dear Teenage Engineering: I love your company, I love the OP-1. Your design work is incredible and you seem like one of the nicest companies I know. So please understand that I do not in any way, shape or form want to harm you. I simply like to tinker and play with my hardware and I love reversing stuff and finding out how things work. Since this research may very well lead to custom firmware with your IP in it, I will not release it without your blessing. If you want to get in touch, send me an email to
tabascoeye AT gmail DOT com.

Now that this is out of the way, let's get into it.

I stumbled into all this after getting my OP-1 about 2 years ago. Looking at firmwares is kind of a hobby, so naturally when a filetype ".op1" comes along, I'm interested in taking it apart.

1) OP-1 update file contents

The update files that you can download from teenage engineering actually are just a compressed file containing more files. The format is called LZMA and is a compression algorithm. To make sure that the file arrived on the OP-1 when you transferred it, a 4Byte checksum (CRC32) is added infront of the compressed file.
That is usual practice with files in embedded systems.

So if you strip those 4 Bytes, you can just decompress the contents. (Since I am a lazy bastard, I usually just let 'binwalk' do its thing on files I don't know)

The contents are [using the leaked Beta FW op1_076.op1]:
β”œβ”€β”€ content
β”‚ β”œβ”€β”€ audio
β”‚ β”‚ β”œβ”€β”€ drum
β”‚ β”‚ β”‚ β”œβ”€β”€ drum_0.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ drum_1.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ drum_2.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ drum_3.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ drum_4.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ drum_5.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ drum_6.raw
β”‚ β”‚ β”‚ └── drum_7.raw
β”‚ β”‚ β”œβ”€β”€ factory_drum
β”‚ β”‚ β”‚ β”œβ”€β”€ adm perc1.1.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ berlin.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ bread of sugar.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ deep africa.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ detroit.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ funky old.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ future tech.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ india.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ jazz.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ jeff-s 01.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ jeff-s 02.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ lenk.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ live-ish.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ neon-80s.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ reggae type.raw
β”‚ β”‚ β”‚ └── steeezo r2.raw
β”‚ β”‚ β”œβ”€β”€ factory_synth
β”‚ β”‚ β”‚ β”œβ”€β”€ bladerunner.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ creep dish.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ distort a log.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ engine rev.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ ghettobass.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ harm a chord.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ op303_s2.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ punchsub.raw
β”‚ β”‚ β”‚ β”œβ”€β”€ rmk2 note.raw
β”‚ β”‚ β”‚ └── subway bass.raw
β”‚ β”‚ β”œβ”€β”€ preset_drum
β”‚ β”‚ β”œβ”€β”€ preset_synth
β”‚ β”‚ β”œβ”€β”€ speech
β”‚ β”‚ β”‚ └── op1patch.raw
β”‚ β”‚ └── synth
β”‚ β”‚ └── synth_7.raw
β”‚ β”œβ”€β”€ display
β”‚ β”‚ β”œβ”€β”€ adsr.svg
β”‚ β”‚ β”œβ”€β”€ album.svg
β”‚ β”‚ β”œβ”€β”€ apetape.svg
β”‚ β”‚ β”œβ”€β”€ bendlfo.svg
β”‚ β”‚ β”œβ”€β”€ bode.svg
β”‚ β”‚ β”œβ”€β”€ clock.svg
β”‚ β”‚ β”œβ”€β”€ cls.svg
β”‚ β”‚ β”œβ”€β”€ colors.svg
β”‚ β”‚ β”œβ”€β”€ com.svg
β”‚ β”‚ β”œβ”€β”€ cranklfo.svg
β”‚ β”‚ β”œβ”€β”€ dbox.svg
β”‚ β”‚ β”œβ”€β”€ delay.svg
β”‚ β”‚ β”œβ”€β”€ drum2.svg
β”‚ β”‚ β”œβ”€β”€ drw.svg
β”‚ β”‚ β”œβ”€β”€ dsynth.svg
β”‚ β”‚ β”œβ”€β”€ duallfo.svg
β”‚ β”‚ β”œβ”€β”€ dynaenv.svg
β”‚ β”‚ β”œβ”€β”€ endless.svg
β”‚ β”‚ β”œβ”€β”€ eq.svg
β”‚ β”‚ β”œβ”€β”€ etchasketch.svg
β”‚ β”‚ β”œβ”€β”€ fm.svg
β”‚ β”‚ β”œβ”€β”€ ftwo.svg
β”‚ β”‚ β”œβ”€β”€ grid.svg
β”‚ β”‚ β”œβ”€β”€ help.svg
β”‚ β”‚ β”œβ”€β”€ id.svg
β”‚ β”‚ β”œβ”€β”€ in.svg
β”‚ β”‚ β”œβ”€β”€ iter.svg
β”‚ β”‚ β”œβ”€β”€ lander.svg
β”‚ β”‚ β”œβ”€β”€ lpc.svg
β”‚ β”‚ β”œβ”€β”€ master.svg
β”‚ β”‚ β”œβ”€β”€ micline.svg
β”‚ β”‚ β”œβ”€β”€ midilfo.svg
β”‚ β”‚ β”œβ”€β”€ midi.svg
β”‚ β”‚ β”œβ”€β”€ mixer.svg
β”‚ β”‚ β”œβ”€β”€ mllp.svg
β”‚ β”‚ β”œβ”€β”€ mmmf.svg
β”‚ β”‚ β”œβ”€β”€ octave.svg
β”‚ β”‚ β”œβ”€β”€ ok.svg
β”‚ β”‚ β”œβ”€β”€ opfont.svg
β”‚ β”‚ β”œβ”€β”€ pattern.svg
β”‚ β”‚ β”œβ”€β”€ pd.svg
β”‚ β”‚ β”œβ”€β”€ playmode.svg
β”‚ β”‚ β”œβ”€β”€ pls.svg
β”‚ β”‚ β”œβ”€β”€ presetbrowser.svg
β”‚ β”‚ β”œβ”€β”€ ptch.svg
β”‚ β”‚ β”œβ”€β”€ radio.svg
β”‚ β”‚ β”œβ”€β”€ reroutelfo.svg
β”‚ β”‚ β”œβ”€β”€ rndlfo.svg
β”‚ β”‚ β”œβ”€β”€ rymd.svg
β”‚ β”‚ β”œβ”€β”€ sampler.svg
β”‚ β”‚ β”œβ”€β”€ save.svg
β”‚ β”‚ β”œβ”€β”€ signalflow.svg
β”‚ β”‚ β”œβ”€β”€ simple.svg
β”‚ β”‚ β”œβ”€β”€ singlelfo.svg
β”‚ β”‚ β”œβ”€β”€ sketch.svg
β”‚ β”‚ β”œβ”€β”€ slump.svg
β”‚ β”‚ β”œβ”€β”€ st.svg
β”‚ β”‚ β”œβ”€β”€ subscreenhand.svg
β”‚ β”‚ β”œβ”€β”€ t10.svg
β”‚ β”‚ β”œβ”€β”€ tapeconfig.svg
β”‚ β”‚ β”œβ”€β”€ tape.svg
β”‚ β”‚ β”œβ”€β”€ tempo.svg
β”‚ β”‚ β”œβ”€β”€ tombola.svg
β”‚ β”‚ └── tune.svg
β”‚ β”œβ”€β”€ kerntable.db
β”‚ β”œβ”€β”€ op1.db
β”‚ β”œβ”€β”€ op1_factory.db
β”‚ └── tape.db
β”œβ”€β”€ OP1_vdk.ldr
└── te-boot.ldr

10 directories, 107 files


Thanks a lot! :slight_smile:

.raw is sound and .svg is a image vetor format, but how about the .db and .ldr files? What are those formats?

.ldr, hmm. Maybe, and that would be funny and awsome at the same time, it is that:

.db should be some sort of database file

2) The Display

One of the oddest things about the OP-1 when I read about it first was the marketing notion of the "vector based display" since the OP-1 clearly has a pixel based OLED display.

So in essence probably someone heard from the developers that they use "scalable vector graphics" (SVG) to create all the graphics.

The fun part about SVG is that it is an XML based format that has concepts like "display=none", ids and groups. So they could likely split into the programmer group, writing the animations by using ids and switching "display=none" to "display=inline", and a designer/graphics group that could change the actual graphics without the need of re-programming anything.

Btw: Most of the graphics were done with Adobe Illustrator CS4, some with CS3 and in the beta, there are files done with "17.1.0" which is probably Illustrator Creative Cloud.

1 Like

3) The .ldr files

The OP-1 works with a BF-524 as main CPU. That is a β€œBlackFin” DSP chip made by Analog Devices. It is also used in digital storage oscilloscopes because of its DSP capabilities.

The blackfin uses a weird format for files and documentation isn’t that easy to find. Essentially, the LDR (or β€œloader”) format is what the CPU expects as download format. It consists of β€œblocks” of data, each with a header and there is a bit of β€œcompression” involved (namely there are headers which say β€œthe following X Bytes are all 0”) thus when loading that file, the CPU fills its memory according to the instructions in the loader file.

According to AD documents, the file that is represented by all the blocks in the LDR file is a β€œDXE” file. I found some mentions about DXE being a lot like ELF, which says a lot and nothing at the same time.

So essentially, to really run your own code on the OP-1 you would have to:

  1. write a decoder software to turn the LDR file back into DXE
  2. find out the format of DXE
  3. write a disassembler for blackfin (or hope that e.g. radare works with it)
  4. analyze the codeflow and delete/insert parts where needed
  5. turn the DXE file into LDR again
  6. re-package the whole OP-1 firmware update package
  7. upload! \o/
and yes. That is about as much pain as it sounds.
At first I thought that the OP-1 would run ucLinux on there because there are some tools and eval kits for the BlackFin running that. But there is no reference whatsoever to Linux in there, so the theory of it using VDK (the kernel from VisualDSP) is much more likely
1 Like
@TabascoEye so how long until I can install your hotrodded OS? Kind of like Jailbreak for the iphone. LOL
1 Like

4) inner workings of the firmware

The firmware uses quite some known opensource software:

  • yaffs2 - a file system for flash chips (the memory of the OP-1, noted as "grandmaster flash" on the PCB)
  • libaiff-5.0 - a library to mess with the aiff files used for audio
  • sqlite 3 - a relational database
  • box2d - a physics engine (most likely for things like tombola and the chopper game)
  • libjson - a helper library to parse the JSON format
  • probably more...
I found out most of this by just getting every readable character (ASCII) from the .ldr file. In Linux there is the "strings" command for that.

The usage of SQLite databases and SVGs is pretty ingenous as I mentioned because they could change large parts of the OP-1 without the need of recompiling all the C++ code and run it through the whole toolchain. Instead, they could just exchange SVG files or write other values in the SQLite DBs to change the behavior of the synths etc.

5) the .db files

maybe the funniest moment was when I checked the database files which are in the update package in a SQLite browser.

There is "kerntable.db" which consist of the columns "a","b" and "kerning".
You can be sure you are dealing with designers when there is a database that controls the kerning between each symbol on there :o))
Did I mention I love that company?


so apart from this fun file, there is "op1_factory.db" which seems to be the key file in doing a "factory reset". And that contains this very interesting table:


notice the "id" column. So there are some values missing: 1, 2 and 6....
1 Like

6) Moving on...

So now there are 3 areas of major work:

  1. trying out the correct values of the fx_type database table
    1. which type fits which id (is the order even important? it seems so based on my experiments)
    2. which default_params are needed for the missing fx? (this is a major pain in the butt to figure out because of the time it takes to create an FW, download it, try, fail, factory reset, back to square one)
    3. find out if the fx even works with the current firmware. maybe its broken or barely usable? Theres probably a good reason for taking them out...
  2. trying to find out the workings of the SVG files to create some nice custom graphics (as indicated in my other post.. but.... wait for it ....)

    and finally:
  3. the cown jewels: creating all the tools necessary to crack the actual firmware open, figure out how it works and mess with it until something new comes out (usually the "hello world" of custom firmware on devices is getting "DOOM" to run..... ... .....)

So thats the current state and I'll continue to work on it when I have some spare time.
In the mean time I will give you a teaser of what I have in mind when talking about "custom graphics" :o)

…chorus, lpC and tape ape!? :smiley: And that filter fossile?

dropping the bomb

1 Like

dropping the bomb

Haha F%ck yeah!



you got my attention o_o

Hahahahaha <3

@<a href=β€œ” class=β€œUsername” style=β€œmargin: 0px; padding: 0px; border: 0px; outline: 0px; font-weight: bold; font-size: 15px; font-family: β€œlucida grande”, β€œLucida Sans Unicode”, tahoma, sans-serif; vertical-align: baseline; text-decoration: none; color: rgb(66, 157, 168); line-height: 22.1px; background-color: rgb(252, 252, 255);”>TabascoEye<span style=β€œcolor: rgb(37, 38, 30); font-family: β€œlucida grande”, β€œLucida Sans Unicode”, tahoma, sans-serif; font-size: 13px; line-height: 22.1px; background-color: rgb(252, 252, 255);”> Ahaha excellent mate.

<span style=β€œcolor: rgb(37, 38, 30); font-family: β€œlucida grande”, β€œLucida Sans Unicode”, tahoma, sans-serif; font-size: 13px; line-height: 22.1px; background-color: rgb(252, 252, 255);”>Hope you manage to get the equivalent sonicwise, that would be awesome :smiley:
<span style=β€œcolor: rgb(37, 38, 30); font-family: β€œlucida grande”, β€œLucida Sans Unicode”, tahoma, sans-serif; font-size: 13px; line-height: 22.1px; background-color: rgb(252, 252, 255);”>

seconded .db is sqlite.

some info on the OP1 chunk in AIF presets here. of course if you wanted to generate a ton of patches, it is totally possible.

man some awesome fun could be had editing the SVG’s throughout the OS :slight_smile: