Switch to full style
In-depth technology research: finding new ways to recover data, accessing firmware, writing programs, reading bits off the platter, recovering data from dust.

Forum rules

Please do not post questions about data recovery cases here (use this forum instead). This forum is for topics on finding new ways to recover data. Accessing firmware, writing programs, reading bits off the platter, recovering data from dust...
Post a reply

Seagate Boot Rom DS protocol

October 30th, 2019, 18:45

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.

Re: Seagate Boot Rom DS protocol

October 30th, 2019, 19:15

Many thanks!

Would Ctrl-J suffice as a newline character?

Re: Seagate Boot Rom DS protocol

October 31st, 2019, 7:30

afuna wrote: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'


Oops... the checksum should be 00 not F9 because we want to send a bad checksum.

Re: Seagate Boot Rom DS protocol

October 31st, 2019, 7:32

I hope to write a tool over the weekend that will accept a binary file and a memory offset and write it to the terminal using the DS command.

(Basically, it needs to send 'DS', break the file into packets of ~250 bytes, and send all the packets, plus a bad packet and the terminating packet.)

Re: Seagate Boot Rom DS protocol

November 22nd, 2019, 8:03

I've since discovered that this format is a known protocal see https://en.wikipedia.org/wiki/SREC_(file_format)

Re: Seagate Boot Rom DS protocol

November 22nd, 2019, 15:31

afuna wrote:I've since discovered that this format is a known protocal see https://en.wikipedia.org/wiki/SREC_(file_format)

Can you tell us what info is sent in the S0 Header?

Can you tell us whether the address field requires an absolute or relative address? That is, would an address of 0 refer to the first byte in the ROM or the first location in the MCU's address space?

Re: Seagate Boot Rom DS protocol

November 22nd, 2019, 18:41

the address does not matter as far as i remember.
the content will be written to offset 0

Re: Seagate Boot Rom DS protocol

November 22nd, 2019, 19:49

In retrospect, my question doesn't make sense for a serial flash memory.

Am I to understand that the DS command automatically programs the specified address in the SPI flash, without uploading any extra code?

Re: Seagate Boot Rom DS protocol

November 23rd, 2019, 5:33

no, it does not program the flash, just stores the data in ram.

Re: Seagate Boot Rom DS protocol

March 30th, 2020, 6:53

Great share!

Re: Seagate Boot Rom DS protocol

June 18th, 2020, 23:42

any progress at this topic (Rom writing)?
Post a reply