new wavedrum post
authorrekado <rekado@elephly.net>
Sun, 21 Sep 2014 09:31:25 +0000 (11:31 +0200)
committerrekado <rekado@elephly.net>
Sun, 21 Sep 2014 09:31:25 +0000 (11:31 +0200)
images/posts/2014/wavedrum-word-packing.png [new file with mode: 0644]
posts/2014-09-18-wavedrum-firmware-disassembler.markdown [new file with mode: 0644]

diff --git a/images/posts/2014/wavedrum-word-packing.png b/images/posts/2014/wavedrum-word-packing.png
new file mode 100644 (file)
index 0000000..98161a6
Binary files /dev/null and b/images/posts/2014/wavedrum-word-packing.png differ
diff --git a/posts/2014-09-18-wavedrum-firmware-disassembler.markdown b/posts/2014-09-18-wavedrum-firmware-disassembler.markdown
new file mode 100644 (file)
index 0000000..3a1d1e9
--- /dev/null
@@ -0,0 +1,121 @@
+---
+title: Disassembling the Wavedrum firmware
+tags: DIY,electronics,music,hacking,wavedrum,SHARC
+---
+
+The Wavedrum's processing unit is an ADSP-21375 by Analog Devices, a
+member of the SHARC processor family.  The firmware of the Wavedrum,
+which is stored on a micro SD-card and, more importantly, on the flash
+memory chip is loaded into the processor during the boot process.
+
+[Last time](2013-12-09-wavedrum-connectors.html) I confirmed by tracing the
+connections of the two boot pins that the processor is wired to boot
+from EPROM/Flash (`BOOT_CFG1-0 = 10`).  I'm too lazy to try to verify
+that the firmware on the micro SD-card is identical to the contents of
+the flash memory, so I'll just assume that this is the case.
+
+When the processor is initially powered on, the internal memory is in
+an undefined state.  According to the
+[ADSP hardware reference](http://www.analog.com/static/imported-files/processor_manuals/ADSP-21367_hwr_rev2-1.pdf)
+(section 17-7 *Processor Booting*), the processor core is put into
+`IDLE` mode while loading the boot kernel from an external source (in
+our case this is the flash memory) into the internal memory at address
+0x90000 (`IVT_START_ADDR`), and finally executes the boot kernel code
+when a peripheral interrupt signals that the kernel has been loaded.
+Then the application code is loaded from the memory and finally the
+application's Interrupt Vector Table (IVT) is loaded.  The boot kernel
+is 256 48-bit words long, as is the IVT.  The application code is of
+arbitrary length.
+
+
+# Word packing
+
+The boot kernel is exactly 256 48-bit words long (shorter kernels are
+padded with NOPs), but the words are not transferred as 48-bit words.
+The boot kernel is transferred from the external memory as a stream of
+384 "packed" 32-bit words (see table 17-6 in the hardware reference).
+To understand packing we have to know that conceptionally the internal
+memory consists of many rows of four columns, each of which is 16 bit
+wide.  Accessing 48-bit words is often referred to as 3-column access
+in the reference, whereas accessing 32-bit words is called 2-column
+access.  All of the SHARC instructions are 48 bit wide.  This means
+that any 32-bit wide package never contains the full instruction.
+Dependent on the order of the packages, the 48-bit words can be
+reconstructed from a stream of 32-bit words.
+
+Here's the original explanation in the hardware reference on page
+17-27:
+
+> During the boot process, word packing (for example 8 to 32-bit) is
+> performed over the SPI. In other words, the kernel is not loaded
+> directly with 256 x 48-bit words, instead it is loaded with 384 x
+> 32-bit ‘packed words’ (2-column access). The same physical memory
+> for instruction boot is loaded via DMA in normal word (NW) 2
+> column. However, after booting the same physical memory region is
+> fetched by the sequencer in NW 3-column. For example the loader
+> kernel itself has a NW 2 columns count of 256 x 3/2 = 384 words but
+> the kernel is executed with 256 instruction fetches.
+
+When booting from external memory the bus width is set to 8 bits.
+According to the
+[ADSP hardware reference](http://www.analog.com/static/imported-files/processor_manuals/ADSP-21367_hwr_rev2-1.pdf)
+(section "External Port Booting"), the processor reads a stream of
+8-bit words from the data port and packs four of them into 32-bit
+words (LSB first) before storing them into the internal memory.
+
+Figure 17-5 in the hardware reference visualises this process rather
+nicely.  It shows how streams of different word sizes end up being
+stored in the internal memory.
+
+<img class="full stretch" src="/images/posts/2014/wavedrum-word-packing.png" alt="word packing" />
+
+Once I understood that words are transferred from the memory in 8-bit
+chuncks with the LSB first, writing a disassembler that would
+translate the binary boot kernel into assembly code was no longer very
+challenging.
+
+
+# A free disassembler for ADSP-213xx
+
+I implemented a simple tool in Haskell that takes a binary firmware
+and spits out assembly code for the ADSP.  At the moment it only
+supports a limited set of instructions, just enough so that I could
+translate the boot kernel.  The remainder of the instructions
+will be implemented later as I happen to encounter them in the
+application code.
+
+It currently only parses the first 256 words of the firmware,
+i.e. only the boot kernel.  Before I can parse the remainder I need to
+figure out the memory layout.
+
+The code is freely available under the
+[GPL](http://www.gnu.org/licenses/#GPL) and can be downloaded from
+[gitorious](https://gitorious.org/wavedrum/sharc-disassembler) or
+[Github](https://github.com/rekado/sharc-disassembler).  See the
+included instructions for assistance in compiling and using the
+disassembler.
+
+
+# Next steps
+
+My work isn't over yet.  Next I'll focus on the following tasks:
+
+- figure out how the boot kernel loads the application code into the
+  processor
+- disassemble (parts of) the application code
+- look out for snippets that involve loading code from the micro-SD
+  card to the flash memory, because that's our ticket to upgrade the
+  firmware easily
+
+If you want to help me, I'd be happy if you could send me a copy of
+the Global Edition's firmware.  To do this you only need to take out
+the micro SD-card and create a disk image of it.  (On GNU/Linux this
+can easily be done with `dd` on the command line; see
+[my first post on hacking the Wavedrum](http://elephly.net/posts/2013-08-11-hacking-the-wavedrum.html)
+for more detailed instructions.)
+
+I would also be very grateful for code reviews and patches.
+Translating the various specifications into executable code wasn't
+always easy and I'm sure there are bugs in the code here and there.
+
+Read [more posts about the Wavedrum here](http://elephly.net/tags/wavedrum.html).