serialice lets you get very far in the debug process. At some point, one needs to take the plunge and try "the real thing".
But, on a board with soldered-on flash, this is a one-way trip.
Or maybe not.
What if we could do this: put serialice in the boot block, i.e. as the "fallback", and put a test bios in as the "normal". Serialice could have the capability to flash the "normal". Serialice could also be directed to start the "normal" bios for testing purposes.
Then, I could on my 1580s do test bios images, secure in knowing that I can always fall back to serialice and recover. Possibly we could have serialice be an "external programmer" for flashrom!
Comments?
ron
On 26.11.2009 05:55, ron minnich wrote:
Then, I could on my 1580s do test bios images, secure in knowing that I can always fall back to serialice and recover. Possibly we could have serialice be an "external programmer" for flashrom!
As a flashrom developer, here's my take on the issue.
There are two ways to do this: 1. Link flashrom with libpayload and have it stored in the ROM. Needs working RAM to be useful. 2. Add serialice support to flashrom via an external programmer driver. Will not work reliably for parallel and LPC flash due to timing constraints: we have a few timeouts in the order of 50 µs (microseconds) during programming and I doubt we can reach a sustained data rate of 5 bytes (1 command, 3 addr, 1 data) per 50 µs (100 kByte/s, 800 kbit/s) over serial.
Variant 1 has no problems with timing and can be solved with libflashrom (TBD) and some new interface. Variant 2 has no problems on SPI hosts and can be implemented right now.
Both variants require partial erase/write which needs acks for pending flashrom patches.
Regards, Carl-Daniel
On Thu, Nov 26, 2009 at 7:16 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
There are two ways to do this:
- Link flashrom with libpayload and have it stored in the ROM. Needs
working RAM to be useful.
So that option is out.
- Add serialice support to flashrom via an external programmer driver.
Will not work reliably for parallel and LPC flash due to timing constraints: we have a few timeouts in the order of 50 盜 (microseconds) during programming and I doubt we can reach a sustained data rate of 5 bytes (1 command, 3 addr, 1 data) per 50 盜 (100 kByte/s, 800 kbit/s) over serial.
OK IIRC many of the parts we use can do bytewise programming, or is that memory wrong? If they can do bytewise programming, then there are no timing constraints between data bytes sent over serial, and we can have large inter-data-byte delays, and need only deal with the short delays between the sequence of FLASH writes for the commands and one byte of data to program each byte [did that make sense?].
I think this says we may need some minor changes to operators for the external interface that could match serialice? In SerialICE we have no memory but we have a few register variables -- certainly enough to hold base address, length, and byte of data.
Can we have something like: 1. erase block command 2. set programming base address command 3. set programming length command 4. "streaming program" given (2) and (3), accept "length" bytes and do bytewise programming for each one. You'll have to tell me if this can even work.
This is obviously not a production interface but it would make my life a lot easier. I would no longer need to sacrifice a 1580 for each test run. I just got told I'm going to have 2048 1580s handed to me and dedicated to the botnet stuff, so the BIOS issue just became important to me again. At the same time something along these lines *could* become incredibly useful in many real-life situations: a very simple API, *primarily designed to be computer controlled*, which can be used to recover from almost any bad thing that happens. The key is *primarily designed to be computer controlled*: not some kludgy keyboard/mouse/display interface like current BIOSes do, but rather a system designed for automated error detection and recovery, up to and including reflashing the BIOS. I think this could be a really Big Deal. In fact it could be a huge value-add for coreboot (There! I Just used Market-droid language!)
Another very useful thing to do with SerialICE would be a "test harness" mode where we run the memory enable sequence and return control to SerialICE, and then test memory.
I think the uses of SerialICE are really just becoming apparent. It certainly wins the Cool Hack of The Year Award for this project, if not all projects :-)
ron
On Thu, 26 Nov 2009, ron minnich wrote:
On Thu, Nov 26, 2009 at 7:16 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
- Add serialice support to flashrom via an external programmer driver.
Will not work reliably for parallel and LPC flash due to timing constraints: we have a few timeouts in the order of 50 ??? (microseconds) during programming and I doubt we can reach a sustained data rate of 5 bytes (1 command, 3 addr, 1 data) per 50 ??? (100 kByte/s, 800 kbit/s) over serial.
OK IIRC many of the parts we use can do bytewise programming, or is that memory wrong? If they can do bytewise programming, then there are no timing constraints between data bytes sent over serial, and we can have large inter-data-byte delays, and need only deal with the short delays between the sequence of FLASH writes for the commands and one byte of data to program each byte [did that make sense?].
If serialice connection between hardware and qemu host with 8029 will be ever ready then part of pio rw-able memory buffer on chip can be used without any dma/irq as buffer for flashing, it isnt big, but 256bytes page will fit.
I am not sure but maybe cache can be abused as buffer in case when above is not possible and we need writing whole page not per byte?
best regards Maciej
On 26.11.2009 23:36, Maciej Pijanka wrote:
On Thu, 26 Nov 2009, ron minnich wrote:
On Thu, Nov 26, 2009 at 7:16 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
- Add serialice support to flashrom via an external programmer driver.
Will not work reliably for parallel and LPC flash due to timing constraints: we have a few timeouts in the order of 50 ??? (microseconds) during programming and I doubt we can reach a sustained data rate of 5 bytes (1 command, 3 addr, 1 data) per 50 ??? (100 kByte/s, 800 kbit/s) over serial.
OK IIRC many of the parts we use can do bytewise programming, or is that memory wrong? If they can do bytewise programming, then there are no timing constraints between data bytes sent over serial, and we can have large inter-data-byte delays, and need only deal with the short delays between the sequence of FLASH writes for the commands and one byte of data to program each byte [did that make sense?].
If serialice connection between hardware and qemu host with 8029 will be ever ready then part of pio rw-able memory buffer on chip can be used without any dma/irq as buffer for flashing, it isnt big, but 256bytes page will fit.
I am not sure but maybe cache can be abused as buffer in case when above is not possible and we need writing whole page not per byte?
Maybe. Needs buffer management on the broken machine, but sounds usable.
Regards, Carl-Daniel
On 26.11.2009 19:46, ron minnich wrote:
On Thu, Nov 26, 2009 at 7:16 AM, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
There are two ways to do this:
- Link flashrom with libpayload and have it stored in the ROM. Needs
working RAM to be useful.
So that option is out.
Well, with some careful changes, I think flashrom can get by with maybe 2 kB of RAM or CAR. I know what to change, but I can't make 100% correct RAM requirement estimates. And we'll need boatloads of const keywords. Patches welcome, especially for the const stuff. The biggest writable object is the flashchip array. We can make it const, but then we have to copy each chip to a temporary variable during probe. Not really ideal. Hm.
- Add serialice support to flashrom via an external programmer driver.
Will not work reliably for parallel and LPC flash due to timing constraints: we have a few timeouts in the order of 50 µs (microseconds) during programming and I doubt we can reach a sustained data rate of 5 bytes (1 command, 3 addr, 1 data) per 50 µs (100 kByte/s, 800 kbit/s) over serial.
OK IIRC many of the parts we use can do bytewise programming, or is that memory wrong? If they can do bytewise programming, then there are no timing constraints between data bytes sent over serial, and we can have large inter-data-byte delays, and need only deal with the short delays between the sequence of FLASH writes for the commands and one byte of data to program each byte [did that make sense?].
It does make sense until you think about what needs to go over the wire. Take the simplest example: JEDEC 1-byte write (3 byte write for starting the program mode, 1 byte write actual data): chip_writeb(0xAA, bios + 0x5555); chip_writeb(0x55, bios + 0x2AAA); chip_writeb(0xA0, bios + 0x5555); chip_writeb(*src, dst);
Per write, you have to transfer 4 one-byte writes. For each write, you have to submit the address (4 bytes, reduced with some tricks to 3 bytes) and the data (1 byte). Even if you have a zero-overhead protocol (no byte needed to tell SerialICE whether to read or write), you have to shove 4 bytes (single-byte write) over the wire in 50 microseconds. That assumes you are allowed a 50 microsecond delay for each chip_writeb.
I'd love to be proven wrong because that would make the task at hand a lot easier.
Now about SPI flash: All of the SPI interfaces I saw so far have no timeouts. You could punch in the values by hand (literally) and it would still work fine. That's one of the reasons why I suggested this model for SPI.
I think this says we may need some minor changes to operators for the external interface that could match serialice? In SerialICE we have no memory but we have a few register variables -- certainly enough to hold base address, length, and byte of data.
Can we have something like:
- erase block command
- set programming base address command
- set programming length command
- "streaming program" given (2) and (3), accept "length" bytes and do bytewise
programming for each one. You'll have to tell me if this can even work.
Each command (if we completely ignore the data we want to program) is at least 3x (3 bytes address, 1 byte data), totaling 12 bytes. After that, you need 3 bytes start address for streaming write, and can theoretically stream 1 byte per byte over the serial line. The streaming is impossible if your chip only supports 1-byte write because you have to enter the "start program mode" command before each single byte write to the chip. To make this feasible, you need at least 12 bytes buffer space for the command and 3 bytes for the first data address. Total is 15 bytes. No idea if you can spare 15 bytes in registers besides the register holding the current data byte. You tell me.
This is obviously not a production interface but it would make my life a lot easier. I would no longer need to sacrifice a 1580 for each test run. I just got told I'm going to have 2048 1580s handed to me and dedicated to the botnet stuff, so the BIOS issue just became important to me again. At the same time something along these lines *could* become incredibly useful in many real-life situations: a very simple API, *primarily designed to be computer controlled*, which can be used to recover from almost any bad thing that happens. The key is *primarily designed to be computer controlled*: not some kludgy keyboard/mouse/display interface like current BIOSes do, but rather a system designed for automated error detection and recovery, up to and including reflashing the BIOS. I think this could be a really Big Deal. In fact it could be a huge value-add for coreboot (There! I Just used Market-droid language!)
Give me 16 bytes of CAR/RAM and some registers (32bit reg for address, 8bit reg for data) to work with, and I can give you an interface that can do byte writes. Twice the RAM if you want to be able to erase anything. It will be anything but fast, however it will work with existing flashrom. For SPI, the CAR/RAM requirements are lower, but you need working PCI (or at least config space access to the LPC bridge) and you need to activate one memory BAR of the LPC bridge.
I think the uses of SerialICE are really just becoming apparent. It certainly wins the Cool Hack of The Year Award for this project, if not all projects :-)
Are there any contests for that? Nobody knows about SerialICE if we don't promote it.
Regards, Carl-Daniel
On 27.11.2009 00:24, Carl-Daniel Hailfinger wrote:
Give me 16 bytes of CAR/RAM and some registers (32bit reg for address, 8bit reg for data) to work with, and I can give you an interface that can do byte writes.
I think I should clarify this. If a chip requires n bytes to be written at once (some chips absolutely require 128 bytes (known), some others may require 256 bytes (not so sure)), and we can use standard JEDEC sequences, we need n+15 bytes of CAR/RAM for the write. A FIFO or other scratchpad (in-chipset "BIOS RAM") will do, but it has to reach a sustained data rate of 80 kByte/s at the very minimum (and that may result in flaky writes, so let's be conservative and require 200 kByte/s).
Regards, Carl-Daniel
FYI, I don't know if this helps but on the RM4100 original bios there is a small flash utility built in. We have discovered that we can access this through the memory hole and flash the bios via serial (but the bios image still needs to be on the drive).
Another very useful thing to do with SerialICE would be a "test harness" mode where we run the memory enable sequence and return control to SerialICE, and then test memory.
This would be very cool indeed. So you mean, it would stop at raminit, hand control over to user to manually enter raminit, and then continue on?
I think the uses of SerialICE are really just becoming apparent. It certainly wins the Cool Hack of The Year Award for this project, if not all projects :-)
BY FAR, the best bios unvaler I have ever seen :-)
ron minnich wrote:
Serialice could have the capability to flash the "normal".
Yes, but I say forget about using flashrom as-is for this. The code is still pretty much a mess.
The *actual* code needed to reprogram (parts of) a flash chip is not very many instructions. Maybe 500. *Maybe*. Just include a minimal flash driver in the serialice shell instead.
Our experience from flashrom will be valuable. Some parts of the erase and write routines in flashrom could probably be reused in part.
KISS. It's one system. No need to shoehorn a big clunky generic program into the box.
//Peter
[CC flashrom because this is a flashrom topic. Please don't drop it from CC.]
On 27.11.2009 01:04, Peter Stuge wrote:
ron minnich wrote:
Serialice could have the capability to flash the "normal".
Yes, but I say forget about using flashrom as-is for this. The code is still pretty much a mess.
Really? The code has changed a lot in the last 6 months. I won't debate that main() is ugly, but the rest of the code is abstracted well enough to support SerialICE as external flasher right now with ~21 LOC (given a fast enough serial line, but timing constraints are not the fault of flashrom).
Detailed size estimate for a SerialICE external programmer driver (supporting Parallel/LPC/FWH) in flashrom: Functions for programming are exactly 13 LOC (including function headers, unless SerialICE requires more than 1 write overhead for each read/write). Function for init is ~4 LOC (1 line function header, 1 line opening serial port, 1 line setting buses_supported, 1 line return). Adding required functions to flash.h is 0 LOC (pure cut-n-paste of 3 lines from the new driver). Hooking up the new driver is 4 LOC (copy-n-paste programmer_table it87spi entry, change name/init/writeb/readb). We can even use dummyflasher.c as basis and run s/dummy/serialice/ on 3 functions which saves us 3 LOC and a similar search/replace in programmer_table which saves us writing another 4 LOC, reducing the total to 14 LOC.
Writing 14 LOC can't be that hard.
Regards, Carl-Daniel
P.S. The makefile one-liner and the man page entry are not included in above calculations.