The Seagate boot rom allows writing memory efficiently using the DS (Data Send) command, but I haven't found it documented anywhere. By reverse engineering the rom, I've worked out the protocol.
After you enter 'DS' the prompt says send file. You can begin typing characters immediately (or paste a file like in minicom Ctrl-A Z Y).
At any time you can send character 0x53 ('S') and it will be echoed and ignored.
The protocol is line based i.e. each packet is terminated by a newline (0x0A). If you are entering the text manually you'll have to figure out a way to send a newline character - most terminals send an \r character instead.
The packet layout is a follows:
All values are given as hex characters: to signify the byte 0x18 you would actually type '18', except for the newline character at the end.
Each '?' below represents on ascii character between '0' and 'F'.
- Code:
# | PACKET | CHECKSUM | TERMINATOR
a | size| start addr | data
? | ?? | ????........ | .... | ??.. | \n
Explanation is as follows:
a = the number of bytes that will be given in the address field minus 1
i.e. if you specify an address of 4 bytes (like 0x1F301100) you would pass the character '3'
(if you pass '0' I think it will always use 2 bytes anyway)
passing 4, 5 or 6 means the data will not be written. passing 6+ ends transmission after the next newline.
size = the number of bytes (pairs of characters) in PACKET; this means 1 (for the size field) + number of bytes for address + number of bytes of data
this is a max of FF (255 bytes = 510 characters)
start addr = the address to begin writing at, BIG ENDIAN. No leading '0x' just write 1F301100 etc.
data = the bytes to write, two characters per byte
checksum = (0xFF - (the lowest byte of the sum of all bytes in packet)
You can send as many packets as you want. Terminate each with a newline. To end the transmission, send an empty packet starting with a number higher than 6 (e.g. send the two characters '7\n'.
If the checksum passes, the firmware will try to run some code. The will probably fail. The best thing to do is send a packet with a bad checksum. Every packet with a bad checksum will cause a '*' to be written to the terminal. If any packets fail, the firmware will return you to the prompt instead of executing code.
Here's an example
type (don't forget the newlines):
- Code:
104000019e4
7
Let's break it down:
- Code:
1 (means 2 bytes for address)
04 (4 bytes in packet including this byte = 8 chars)
0000 (address 0x0000)
19 (byte value 0x19)
e4 ( = 0xFF minus (04 + 00 + 00 + 19))
\n newline
7 signals end of transmission
\n newline
To prevent code execution an empty bad packet would look like this:
- Code:
4060000000000F9
4 = 2 bytes for address (4 and up means data won't be written)
06 = 6 bytes (this byte + 5 address bytes. 12 chars in packet - there's no data payload)
0000000000 = address
F9 = checksum: 0xFF - (0x06 + 00 + .. )
\n newline
Send such a packet before the final '7\n'
I haven't tested this extensively, but preliminary results look good.