diff options
author | rekado <rekado@elephly.net> | 2014-09-21 11:31:25 +0200 |
---|---|---|
committer | rekado <rekado@elephly.net> | 2014-09-21 11:31:25 +0200 |
commit | b428fd1dda6404e03c96a1b1dae1a755336443e9 (patch) | |
tree | 95e871da3593aa11e6efdf3f9f45f13df9ba1a72 /posts | |
parent | 156a7b94d1c396a35937e7b3418c04596e1657a0 (diff) |
new wavedrum post
Diffstat (limited to 'posts')
-rw-r--r-- | posts/2014-09-18-wavedrum-firmware-disassembler.markdown | 121 |
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). |