maandag 12 augustus 2013

Hard disk hack part 1

I went to OHM2013 this year and saw all kinds of different talks and hacks. The talk that inspired me the most was the one by Sprite_tm (from http://spritesmods.com) called 'Hard disks: More than just block devices'.

In the talk he showed how he hacked the controller of the hard disk to do anything he wanted it to do. A quote from the blog post that he has put up accompanying the talk: "The disk controller is also interesting as a generic controller board. You have three fairly capable CPU cores, with a pretty big amount of RAM connected to it. There's also an uart, for the serial port, and at least two SPI interfaces; one to the flash rom and one to the spindle controllers." revived an interest in me I had for a while, making a HDD clock!

I already had an Arduino back home and some harddisks to (eventually) make a HDD clock, however after seeing the talk by Sprite_tm I wanted to make one without any external logic board or just using the hard disk for the motor. In theory you could make a HDD clock by flashing custom firmware to the hard disk and adding some LEDs.

I figure that these are the steps I will need to complete:
  • Getting the JTAG to work
  • Getting custom code to control the motor
  • Getting custom code to flash LEDs by using some IO pins (perhaps using the data connector?)
  • Getting custom code to read the actual platter speed by using IO pins and an infrared emitter+detector
  • (optionally add a real-time clock)
  • Finish the HDD clock

Getting the JTAG to work.


Although I had quite a few hard disks lying around most of them I had gotten after having to remove the platters so they could be shredded. To make this process as easy as I could I chose a Western Digital which was as close to the one Sprite_tm used. After hooking up the hard disk to the power supply the motor spins for about 3 seconds, then it stops for 10 seconds, tries to spin again and then stops indefinitely. I think this is because there are no platters to read something form. I doubt it's really broken though.

Although the blog post at spritesmods.com is very informative, it's not a step-by-step guide on how to get all of this working (disclaimer: neither will this be). It also features this final sentence: "Make note: I'm not going to support the process to get all this running in any way; it's a hack, you figure it out." So I had to reverse engineer the reverse engineer.

The disk I use is the WD5001ABYS, it's a very close match to the one in Sprite_tm's blog post regarding to layout. However it doesn't have an external chip where the firmware is housed and it seems to have two piezo-electric shock sensors.


I also needed a device to act as the JTAG dongle. To fulfill this need I have the choice between an arduino, a teensy 2.0 and a Raspberry Pi. As stated in the forum thread mentioned in Sprite_tm's blog the voltage for the JTAG was 3.3v and since the GPIO on the Raspberry Pi is also 3.3v thit would be my best bet. After googling a bit I found a guide to turn a Raspberry Pi into a JTAG dongle using OpenOCD.

I deceided to solder the pins needed for the TDI, TDO, TMS, CLKin and GND after reading about the JTAG specifications online and because of the following text from the forum thread:
"Pins that MUST be used!

GND 
TDI
TMS
CLK in
TDO

Pins that can be used or not depend on your JTAG interface!

Vcc 3.3v - for powering JTAG interface or for reference.
CLK out - for VERY FAST JTAG interface that support CLK out
RST - for JTAG interface that support RST".

First I needed to find out where those pins were located, since my hard disk looks the most like the one of Sprite_tm's blog I deceided to find out what pins he had used.
In his blog he mentions he uses the 'FT2232H-board' JTAG device. I found some information on it on the following italian blog http://ao2.it/en/blog/2012/09/23/tumpa.
Using that information and the picture in the blog I made the following assumptions:
Text in picture is 'gokken', a dutch word meaning 'guesses'.
Also the image is cropped, but I used the FT2232H-board to make the guesses.
I followed the same pins to some test pads on my hard disk board. I did this because my soldering skills are best when the pins aren't 0.2 mm apart.



I soldered the pins to an old IDE cable and checked the connections using my multimeter to make sure it made a good connection. The ground connection proved the hardest to solder, even after scratching the surface the solder would let go some of the times. (In a later version I just wound the GND cable around one of the screws).


After downloading the newest Raspbian “wheezy” image and following the guide to install OpenOCD I connected the hard disk to the Raspberry Pi and ran OpenOCD.



Well shit. It can't find any taps and it gives the error 'JTAG scan chain interrogation failed: all ones'. At this point I figured the following things could be the cause of the error:
  1. I made the wrong pin assumptions and wired it wrong.
  2. The OpenOCD software isn't working.
  3. The message "This adapter doesn't support configurable speed" means it's communcating at the wrong speed, the blog shows it uses 1000kHz and the forum post shows 500kHz.
  4. The Raspberry Pi's GPIO pins are broken, which can happen since there is no over-voltage protection on the board.
  5. The hard disk is broken.
1. After comparing the pins to the forum post and finding out it is based on a standard 20 pin ARM standard (http://www.jtagtest.com/pinouts/arm20) I was quite sure the pins were correct.
2. I couldn't find any hardware lying around the house which had confirmed JTAG ports, so I couldn't test this.
3. I found out a different profile was available in the OpenOCD package that didn't use the 'SysfsGPIO JTAG bitbang driver' but the 'BCM2835 interface driver', this allowed me to set the 'adapter_khz' variable to set the correct speed, but didn't solve the problem.
4. I never hooked anything else to the GPIO pins, so I doubt they are broken.
5. I would need to get another hard disk if this is the case, I'm first gonna try other things though.

After googling for quite some time for webpages with the same error I just thought "let's hook up the pins CLKout and RST. Perhaps changing the configuration could make it work."
Right after hooking up the RST pin and running OpenOCD with the feroceon config I was greeted with the following message:



Success! Sort of... It finds a tap and I can successfully send a 'halt' command and dump memory. I'll need to adjust the configs for better support. For some reason I also needed the RST connected, even though the JTAG specifications and forum post mention it as being optional. I didn't need the CLKout pin though.

I needed to give the halt command within 3 seconds of connecting the power source to the hard disk, if I try to give the command later it doesn't seem to respond. I think this has to do with the 'Wait-For-Interrupt' state it might be in. Not sure yet though.

Now I will need to learn how to fully use OpenOCD and IDA Pro (I've only used OllyDbg and GDB so far). I will also need to learn ARM assembly since my only experience is with x86 ASM. This way I can hopefully get the motor/spindle to spin using my own code. This surely will take some time and will be discussed in Part 2 (and don't call me Shirley).

Geen opmerkingen:

Een reactie posten