Rick's b.log - 2011/04/19 |
|
It is the 18th of December 2024 You are 3.16.135.54, pleased to meet you! |
|
mailto:
blog -at- heyrick -dot- eu
What I can do is explain a little about what JTAG is and how it can help us.
Originally, JTAG was defined as a "boundary scan" system. To understand this, we need to consider automated board testing. Let's consider a cross-section of an old circuit board, like any '80s home micro...
It was possible to perform automatic testing of certain things, namely the integrity of connections between major components (ie address and data bus etc) by using a device referred to as a "bed of nails". Because in the old days, pretty much every chip had legs sticking out of it, it was possible to make something that fit down over the top of the chip in order to test, like this:
The problem arises when we consider newer hardware. For example, the TMS320DM320 that drives the Neuros OSD. Here is a picture of one on a circuit board:
This is because high-density devices with many connections are attached to the board by connections on the underside. It looks a little like this:
This method of mounting has advantages, but it has additional complexity of how do you reliably solder a chip to the board when the connections are underneath a chip of that size. We're looking at an inch square, and judging by the schematics, at least 250-300 connections. [I don't have a pin-out for the DM320, not that one would be much use, for reasons that should be obvious by now!]
Enter JTAG.
JTAG started as a way to perform a boundary scan automatically, that is, to push a specific known state on the pins of one device, and then read back this state from the pins of another device. For example, if we were to set the data bus on device X to be %11111111 and on device Y we read back %11011111 then we'd know that fifth bit on the data bus was a possible non-connect.
This isn't quite how it works on the ARM. I guess it was seen as not being terribly useful to set the ARM to fiddle its I/O. Perhaps the main reason for this is because of the unweildly complexities in making this work. It isn't a flaw in the ARM, but rather a side effect of the fact that you can rarely buy "an ARM". Take the TMS320DM320 as a example. It contains an ARM core, but rather a lot of other stuff. Likewise the ARM powered Beagleboard. This runs an OMAP processor, which is a later faster sexier version of the DM320.
There is an answer. A simple and blindingly obvious answer. An answer easy to implement that would grant access to all parts of the chip, pretty much regardless of the specifics.
The ARM JTAG provides a means to halt the processor core and to push data into processor registers and the ARM's instruction pipeline. It is a cumbersome fiddly process, but you are essentially able to hijack the processor. Instead of saying "set GPIO pins 16 and 17 high" (turn on red/green on LED = orangish), you look up the datasheet to see where in the chip this is... Bits 0 and 1 of Bit Direction Register #1 at 0003:0582, set to zero to set GIO as an output. Then push both bits set to the Bit Set Register #1 at 0003:058E.
You can extend this to poke around the device to perform automated testing. Rather than looking at the values on drop-in pins, it is performed programmatically...
But, wait, we can take this a step further. We can mess with registers, right? And we can store values of registers to memory, right?
This is what we plan to do here. To debrick a non-functional OSD by pushing data into memory and then executing it. Said data will be a recovery image to store in FlashROM, and a small program to put it there.
But it doesn't end there! The ARM core contains something called "Embedded-ICE" which provides debugging facilities such as breakpoints and watchpoints - implemented in hardware. We won't be delving into this, but if the information I intend to write up sparks a deeper interest in on-the-metal ARM hacking, go grab yourself a copy of the ARM datasheets for the core you'll be working with.
I intend to document, in detail, every step of the way to get this project working. It will be, necessarily, highly specific to the Neuros OSD, though I hope the description of operation will be clear enough that it can be easily customised to other ARM cores, and perhaps ported to non-ARM devices.
If you're reading my blog and hoping for more blathering about Japan(ese) and less hardcore geek - sorry, this is more a return to form than a diversion. I am a geek, y'see. But worry not - Katakana lesson #2 will be along real soon after something of an absence, and who knows what other weird and wonderful things might turn up here? Hopefully not another baby duck on hunger strike...
JTAG explained
I am not able to build the JTAG interface right now, no spare cash for the (inexpensive) components and the (rather pricier) postage.
This can be done by pushing the required values into R0, an address into R1, and then pushing STR R0, [R1]
to store the value in R0 at the address pointed to by R1.
Okay, it is a little more complicated than that as the registers set up a fair few other things which you should take care not to disturb, but the DM320's Bit Set and Bit Clear registers make it easier to toggle individual bits without needing to maintain a lot of state or read a lot prior to doing anything.
Surely this would imply we can load up the registers to write data to system memory?
Yes.
So can we mess with all registers?
Pretty much.
And we can push instructions into the ARM's pipeline?
Yes.
Such as a B
(ranch) to a memory location?
Uh-hu.
To execute the data we've just pushed into memory?
Bingo!
No comments yet...
© 2011 Rick Murray |
This web page is licenced for your personal, private, non-commercial use only. No automated processing by advertising systems is permitted. RIPA notice: No consent is given for interception of page transmission. |