summaryrefslogtreecommitdiff
path: root/posts
diff options
context:
space:
mode:
authorrekado <rekado@elephly.net>2014-09-21 11:31:25 +0200
committerrekado <rekado@elephly.net>2014-09-21 11:31:25 +0200
commitb428fd1dda6404e03c96a1b1dae1a755336443e9 (patch)
tree95e871da3593aa11e6efdf3f9f45f13df9ba1a72 /posts
parent156a7b94d1c396a35937e7b3418c04596e1657a0 (diff)
new wavedrum post
Diffstat (limited to 'posts')
-rw-r--r--posts/2014-09-18-wavedrum-firmware-disassembler.markdown121
1 files changed, 121 insertions, 0 deletions
diff --git a/posts/2014-09-18-wavedrum-firmware-disassembler.markdown b/posts/2014-09-18-wavedrum-firmware-disassembler.markdown
new file mode 100644
index 0000000..3a1d1e9
--- /dev/null
+++ b/posts/2014-09-18-wavedrum-firmware-disassembler.markdown
@@ -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).