Skip to main content
Topic: Adding Bus Pirate support to flashrom? (Read 62509 times) previous topic - next topic

Adding Bus Pirate support to flashrom?

Hi,

I noticed that the Bus Pirate is being used by some people to read/write BIOS flash chips (the SPI variant). It seems that everyone is writing their own code to support these flash chips, and the incompatibilities between various chips on the market make reusing the code difficult.

The flashrom project has support for quite a few programmers and hundreds of flash chips and runs under Linux/OSX/*BSD/Solaris/Windows. It seems quite a natural fit to add Bus Pirate support to flashrom. The FT2232H-based SPI support in flashrom may provide a good starting point for Bus Pirate support. flashrom is open source (GPL). The flashrom developers are friendly, and patches are merged pretty rapidly.

flashrom is a command-line utility, but it is non-interactive, so anyone wanting to wrap a flashrom + Bus Pirate instance with a GUI (or some script) can do so easily.

What do you think? Anyone up for such a project?
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.

Re: Adding Bus Pirate support to flashrom?

Reply #1
Coreboot and flashrom was one of the reasons I got a Bus Pirate. I would welcome it if someone would start work on this.

Re: Adding Bus Pirate support to flashrom?

Reply #2
That sounds great. Let me know if I can help.

There's also support for the Bus Pirate in AVRdude SVN, I think AVRdude programs several different EEPROMs too.

Here's the binary mode documentation:
http://dangerousprototypes.com/2009/10/ ... bang-mode/
Got a question? Please ask in the forum for the fastest answers.

Re: Adding Bus Pirate support to flashrom?

Reply #3
Hm. The binary SPI mode has a few possible limitations which could result in unreliable flashing due to timing issues. I'm sorry if I just misunderstood the protocol. The issues and my questions are listed below.

  • CS has to be toggled manually before and after each command. Depending on host OS scheduling, delays up to 10 ms could happen between enabling CS and sending data, and between finishing the data send and disabling CS. Automatic CS handling would be really cool and improve reliability (though we may need a separate setting if CS is active high or active low).
  • Many SPI flash chips have a HOLD pin which can be used to suspend communication, allowing transmission of longer commands than supported by the master (Bus Pirate). I don't see a way to implement this except changing between SPI mode and raw bitbang mode (which destroys timing and renders any usage moot).  HOLD is also somewhat conflicting with automatic CS handling (CS at the beginning of a command is OK, but should we toggle HOLD or CS at the end of the command?).
  • A clarification is required about bulk SPI transfer. Will the transfer start once the first byte arrives at the Bus Pirate, or once the last byte arrives?
  • Is there a batch mode? That is, can I send a command stream like "enable CS, send bulk n bytes, disable CS" and it will be executed without delays in between, regardless of the host OS scheduler? If yes, point 1 (and to some extent, point 2) becomes irrelevant.
  • Some of the functionality may need new commands. Does it make sense to bump the Raw SPI mode version for that, or will new commands be added to SPI1? If the latter, how can one detect that they are supported?

The general command structure used by flashrom is basically:
Simplest case, if you can guarantee absence of delays and if command length doesn't exceed one bulk transfer size: Enable CS, Send bulk (and read result), Disable CS.
If you can guarantee there are no delays: Enable CS, Send bulk (and read result), Send bulk (and read result), Disable CS.
If there may be delays: Enable CS, Send bulk (and read result), Enable HOLD, (delay), Disable HOLD, Send bulk (and read result), Disable CS.

Typical command lengths are 1, 2, 4, 5, 6, 12, 20, 68, 132, 260 bytes. Command lengths above 6 are usually not essential, but given the overhead of some of these commands, flashrom uses as large command lengths as possible. With the current Bus Pirate protocol, it seems there is a sweet spot at command length 12 (which is the length of e.g. an 8-byte flash write or an 8-byte flash read).

Oh, and is there some bounty for this? :-D
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.

Re: Adding Bus Pirate support to flashrom?

Reply #4
1. Don't know about auto CS handling. Can you give me a datasheet link for a chip with timing issues so I can see what we're up against?

2. Hold can be done with the AUX pin, which can be toggled in any raw mode.

3. Yes, it sends the bytes as they arrive and responds with a bus read for each byte sent.

4. Could probably add a batch mode using the ring buffer.

5. Unsupported commands get reply 0x00, supported commands respond 0x01. What extra commands would you need?

Quote
If you can guarantee there are no delays: Enable CS, Send bulk (and read result), Send bulk (and read result), Disable CS.
If there may be delays: Enable CS, Send bulk (and read result), Enable HOLD, (delay), Disable HOLD, Send bulk (and read result), Disable CS.

How much of a delay is too much? The next send bulk begins one UART byte period after the previous SPI byte (eg bulk command + data, bulk command + data). There's not other SPI bus activity during that period. Do flashrom chips have a timeout? You should be able to send any command length using multiple bulk transfers. I think I'm missing some key part of the way that these eeproms work.

If you get it implemented and compiled I'll send you this months project ;)
Got a question? Please ask in the forum for the fastest answers.

Re: Adding Bus Pirate support to flashrom?

Reply #5
[quote author="ian"]
1. Don't know about auto CS handling. Can you give me a datasheet link for a chip with timing issues so I can see what we're up against?[/quote]

Sorry, I don't remember the chip which had such problems. According to the datasheets, there is no max time between enabling CS and the first clock, but I am pretty sure I saw problems in practice. It was a SST25VF or MX25L chip IIRC. Then again, it could have been an interaction with other timing issues.

Some chips (e.g. the MX25L512) have a minimum clock frequency of 1 kHz, and usually these chips have 40%/60% min/max duty cycle, so you could deduce from these constraints that the time between CS enabled and the first clock should be no more than 0.6 ms. Datasheet: http://www.syncmos.com.hk/PDF/MXIC/MX25L512ver13.pdf

[quote author="ian"]
2. Hold can be done with the AUX pin, which can be toggled in any raw mode.
[/quote]

Neat, I thought AUX would be reserved for something else.

[quote author="ian"]
3. Yes, it sends the bytes as they arrive and responds with a bus read for each byte sent.
[/quote]

Ah hm. Well, then I misunderstood some part of the Bus Pirate protocol. Or do I still not get it? I thought it would be possible to at least send the bulk transfer in one USB packet so there are no delays between bytes, and get one bulk packet with the answer back. If even the bulk transfers are one-USB-packet-per-byte, the host scheduler may kick in in the middle of a transfer, cause a >0.6 ms delay (the delay will likely be in the >4 ms range for a Linux machine with HZ=250), and chip behaviour will be unpredictable.

[quote author="ian"]
4. Could probably add a batch mode using the ring buffer.
[/quote]

That would be awesome. How big is the ring buffer?

[quote author="ian"]
5. Unsupported commands get reply 0x00, supported commands respond 0x01. What extra commands would you need?
[/quote]

Ring buffer management:
  • start stransaction (which starts filling the ring buffer)
  • end transaction (which executed the commands in the ring buffer)

With ring buffer management, and the already existing AUX functionality (which I'd use for HOLD), I don't need anything else (no auto-CS stuff, no auto-HOLD stuff, nothing).

I could test ring buffer management presence before using it. The great thing in your protocol design is that unsupported commands are defined to do nothing (and return 0x00). I'm used to "unsupported/undocumented commands will result in undefined behaviour, which may not even be fixable with reset" from too many datasheets. That's why I asked.

[quote author="ian"]
Quote
If you can guarantee there are no delays: Enable CS, Send bulk (and read result), Send bulk (and read result), Disable CS.
If there may be delays: Enable CS, Send bulk (and read result), Enable HOLD, (delay), Disable HOLD, Send bulk (and read result), Disable CS.

How much of a delay is too much? The next send bulk begins one UART byte period after the previous SPI byte (eg bulk command + data, bulk command + data). There's not other SPI bus activity during that period. Do flashrom chips have a timeout? You should be able to send any command length using multiple bulk transfers. I think I'm missing some key part of the way that these eeproms work.
[/quote]

Yes, the 0.6 ms delay mentioned above. Not all chips are affected, and not all chips really exhibit worst-case behaviour. That's the reason why we rarely see it in practice.

[quote author="ian"]
If you get it implemented and compiled I'll send you this months project ;)
[/quote]

The populated christmas tree? Deal.

I will need someone to test this on hardware, though, as I don't have a Bus Pirate (yet). AFAICS audiohacked has both such serial chips and a Bus Pirate, plus he's interested in getting this going.
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.

Re: Adding Bus Pirate support to flashrom?

Reply #6
Quote
I thought it would be possible to at least send the bulk transfer in one USB packet

That's all driver level stuff, I'd say don't depend on it to be consistent because of versions, user settings, OS differences, etc.

The ring buffer is 4096bytes.

Let me look at the command sets and see if there's a consistent command we can use throughout for start buffer, end buffer.

Do you have Bus Pirate hardware on the way?
Got a question? Please ask in the forum for the fastest answers.

Re: Adding Bus Pirate support to flashrom?

Reply #7
[quote author="ian"]
Quote
I thought it would be possible to at least send the bulk transfer in one USB packet

That's all driver level stuff, I'd say don't depend on it to be consistent because of versions, user settings, OS differences, etc.
[/quote]

Even more reasons to be able to batch a few commands in the ring buffer. That essentially eliminates all those hardware/software differences.

[quote author="ian"]
The ring buffer is 4096bytes.
[/quote]

Woah. 20 on-the-SPI-wire bytes in the ring buffer (plus two CS changes) would already be enough for me. 260 on-the-SPI-wire bytes is maximum useful for writing classic NOR flash, <300 for classic NAND flash. Reading has no max size, almost every SPI flash chip (25L series) can do full-chip read in one single stream. So if buffer length management gets easier by restricting the number of commands/bytes in a transaction to an 8-bit (or even 7-bit) quantity, that's still way more than what I hoped for and definitely good enough.

[quote author="ian"]
Do you have Bus Pirate hardware on the way?
[/quote]

Not yet. I'm currently working on final university exam preparation, so I thought I'd postpone buying to a time when I have time+money to play with this.
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.

Re: Adding Bus Pirate support to flashrom?

Reply #8
biosflasher, have you been in contact with the Coreboot/Flashrom developers?

Depending on what you want to do, you can submit the patches directly to the Coreboot/Flashrom people, or send them to me and I can test and sign off on the patches and hopefully get them into the flashrom repository.

I've actually contributed to flashrom and coreboot previously.

Re: Adding Bus Pirate support to flashrom?

Reply #9
[quote author="audiohacked"]
biosflasher, have you been in contact with the Coreboot/Flashrom developers?
[/quote]

Yes.

[quote author="audiohacked"]
Depending on what you want to do, you can submit the patches directly to the Coreboot/Flashrom people, or send them to me and I can test and sign off on the patches and hopefully get them into the flashrom repository.

I've actually contributed to flashrom and coreboot previously.
[/quote]

Great. I'll send them directly to the flashrom mailing list. Are you subscribed there or should I CC you? I'd appreciate reviews/tests (and if everything is OK, an ack) from you.
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.

Re: Adding Bus Pirate support to flashrom?

Reply #10
Status update:
Completed:
  • Command infrastructure code hooked up in flashrom
  • Stub for init/communication
Missing is:
  • Serial/USBserial communication
  • Bus Pirate initialization

275 line patch so far.

Does anyone know if someone else already wrote C code for Bus Pirate Raw SPI mode initialization (and for establishing a connection to the Bus Pirate)?
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.

Re: Adding Bus Pirate support to flashrom?

Reply #11
Audiohacked's GUI has C++ code:
http://code.google.com/p/the-bus-pirate ... sPirateGUI

There's also Jame's I2C EEPROM in plain C:
http://code.google.com/p/the-bus-pirate ... EPROMWIN.c

I can also help you with any initialization stuff you need.
Got a question? Please ask in the forum for the fastest answers.

Re: Adding Bus Pirate support to flashrom?

Reply #12
[quote author="ian"]
Audiohacked's GUI has C++ code:
http://code.google.com/p/the-bus-pirate ... sPirateGUI

There's also Jame's I2C EEPROM in plain C:
http://code.google.com/p/the-bus-pirate ... EPROMWIN.c
[/quote]

Thanks, I took a look. It seems that the C implementation is specific to Windows and the C++ implementation uses a rather largeish library mostly specific to Linux/Unix. Still, the code was valuable for deciding on the best abstraction model (or rather a model that does not suck).

I noticed that the C/C++ implementations always send 20 times 0x00 to enter binmode, but the Perl implementations send 0x00 and check the response. If there was a response they enter raw SPI mode, if there was no response they repeat the process up to 19 times.

[quote author="ian"]
I can also help you with any initialization stuff you need.
[/quote]

Thanks for the offer, I may get back to it later. Right now I'm trying to finish a patch which looks not totally stupid, and I'll post my progress here.
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.

Re: Adding Bus Pirate support to flashrom?

Reply #13
OK, I have a patch which compiles and should work. http://patchwork.coreboot.org/patch/572/
audiohacked is in CC of that mail in case he isn't subscribed to the flashrom list.

Usage:
flashrom -p buspiratespi:dev=/dev/ttyUSB0 -V
Replace /dev/ttyUSB0 with the device node of your Bus Pirate.
-V means verbose output, very useful to debug if something goes wrong.

P.S. Yes, the code sucks in some areas, but it should be good enough for testing.
If you have any flashrom problems, please mail flashrom@flashrom.org and include "Bus Pirate" in the subject line. As an alternative, you can send me a private message.
It is recommended to use at least flashrom 0.9.2 or later, and latest flashrom from svn if you want a 3x speedup.

Re: Adding Bus Pirate support to flashrom?

Reply #14
Quote
I noticed that the C/C++ implementations always send 20 times 0x00 to enter binmode, but the Perl implementations send 0x00 and check the response. If there was a response they enter raw SPI mode, if there was no response they repeat the process up to 19 times.

I may take 1 or 20 0x00 to enter bin mode. If you're already in binmode you'll get BBIO1 after 1 x 0x00, if you're in user terminal mode then it'll take 20 x 0x00. There's a lot of ways to handle this, but I usually just blast 20 0x00 and then read the first 5 chars for BBIO1, and flush the serial buffer to get rid of any extra data (see the fast entry function in my newer Perl examples like the self test script).
Got a question? Please ask in the forum for the fastest answers.