I'm not sure I see a case where you'd want to boot from SD when you have an SPI flash chip present.
Think I'd just reserve 4 pins for either SD or SPI. After serial, try to boot as SPI flash first. If that doesn't work then try those pins as SD (which is also being interfaced in SPI mode, BTW).
Overriding SPI boot feature needs to be there, a button/jumper that pulls one of the SPI pins low (and wait until you release)
As a way of bootstrap-loading new firmware that writes itself to SPI flash,
in case the previous firmware no longer function, as normally it would look for a newer reversion on SD to update itself, but it's corrupt or you need downgrading.
Overriding SPI boot feature needs to be there, a button/jumper that pulls one of the SPI pins low (and wait until you release)
As a way of bootstrap-loading new firmware that writes itself to SPI flash,
in case the previous firmware no longer function, as normally it would look for a newer reversion on SD to update itself, but it's corrupt or you need downgrading.
Right.
Turn off system. Plug in SD card. Turn it back on. SD card updates SPI flash. Turn off system. Remove SD card. Turn system back on. Now running updated code in SPI flash. Simple field upgrade.
An SD card without a signed booter would never cause an SD boot.
I guess that's a scenario that makes sense.
I might have it erase the file or change the filename when done so that could leave SD card there.
There might be a lot of resources on the SD card...
As long as we're pretty sure that the start of the MBR will continue to be reserved for bootstrap code, I think this is a good solution. Is there anything that needs to be done to make sure that another system won't try to boot our code? What if I plug the card into a PC and then power on the PC? Will it attempt to boot since there is code in those first bytes of the MBR? I guess I'm asking how a system knows if the code found there is intended for it.
I'm pretty sure it will always continue to be bootstrap code, and if it doesn't then other things will break. You do have a point that we should probably leave space for a simple x86 "boot" routine that prints "This disk is not bootable." (a lot of floppies and such already have this).
OTOH I missed the requirement that the boot code be signed, which adds some complexity (we now need room for the signature as well). I like the simplicity and flexibility of re-using the traditional PC booting path, but we almost certainly will need more space than the MBR provides. So other options are:
(1) Require that there be some unused, unallocated sectors between the MBR and the first partition. A lot of PC disks are already formatted this way, and it's a traditional spot to stick second stage bootloaders in. We could just always boot from, say, sectors 2-32 or something like that.
(2) Use a reserved boot partition, as you had suggested earlier. I didn't like that because I wanted to be able to put the boot code on a FAT file system, but I've since realized that the reserved partition could itself contain the FAT reading code and could load and verify an arbitrary FAT file, so it works either way.
One potential issue with all of these schemes is that we might want there to be *two* authorized keys to verify boot signatures: a standard Parallax one (for the basic, first stage boot code) and the user's own key (for the application specific code that's finally booted). This would make formatting the disks a lot easier -- the P2 disk formatter could write a generic first stage boot code that would read from FAT or whatever, and that would in turn verify the final boot code with the user's key. It's not a big deal -- obviously the user could sign their own first stage boot code, and users that want signed boot probably are sophisticated enough to handle the extra complication.
Turn off system. Plug in SD card. Turn it back on. SD card updates SPI flash. Turn off system. Remove SD card. Turn system back on. Now running updated code in SPI flash. Simple field upgrade.
An SD card without a signed booter would never cause an SD boot.
So... if you still want to use SD as a non-boot device, this means that every time you boot the ROM code will:
1. Load from the SD
2. Determine that the loaded block is not signed code.
3. Load from flash
In other words, just to support the ability to auto-program flash from an SD card, you are going to hobble every other use of flash+SD with those first two steps? And add the restriction that they be absolutely sure they never put signed code where it would be accidentally read in step 1?
If you are going to insist on including SD boot, here's a suggestion (which may have already been suggested): allow only one method to be used. In the boot ROM, attempt to detect flash first. If found, boot off of it. If boot fails, fall back to serial. If not found, attempt to detect SD (on the same pins). If found, boot off it. If boot fails, fall back to serial.
Here's the reasoning:
* If you only have flash, then things just work as they do right now.
* If you already have an SD, why bother with flash at all? Just boot from SD always.
* If you want both, you do as we do on P1: boot from flash, then access SD.
Now, I suppose you might be able to do a slight variation on this. If you had both flash and SD, but separate CS lines for the two, then you could allow the SD card to boot by temporarity keeping the flash disabled (CS high). For instance, suppose you were to have a "program" switch that would add a pull-up resistor parallel to standard resistor on the flash CS line. During boot, the test pulse period would not be long enough to pull CS low. Next, the SD boots and loads the "flash auto-programmer". The programmer would just pull CS low and delay long enough to ensure that the flash chip is active. This approach has the advantage of supporting just about all boot variations, as well as prevents accidental boot from SD when you have bootable flash.
[In other words, just to support the ability to auto-program flash from an SD card, you are going to hobble every other use of flash+SD with those first two steps?
Someone recently asked that we consider the target audience for the P2. I think we're now seeing that the target audience is people who want to use it as a standalone development system.
But if the SD card has no signed boot program, it doesn't boot. Whichever has the proper signature would be the one to boot. In the case where they BOTH have good signatures, one of them needs priority, and it seems the SD card should have it, so that it can possibly update the SPI flash.
The key word here is "possibly update the SPI flash"
I'd agree this should be possible, but it also should be included in the Pin-Over-Ride table, so it can be prevented, for speed and/or security reasons.
So... if you still want to use SD as a non-boot device, this means that every time you boot the ROM code will:
1. Load from the SD
2. Determine that the loaded block is not signed code.
3. Load from flash
In other words, just to support the ability to auto-program flash from an SD card, you are going to hobble every other use of flash+SD with those first two steps?
No, I think the Pin-Over-Ride is still there, and it becomes a question of what that Pin-Over-Ride table looks like.
Certainly, you do NOT want to make Fastest-Possible-Boot, slower. Fast boot will be very important.
>I suggested boot SPI FLASH first. If not found, then try SD Card.
But if found there still should be a pin-over ride at boot-up as the firmware may be corrupt, so corrupt it does not allow to read the SD card later on it's own.
The override pin is so you load firmware from SD first, and it's up to this firmware to write itself to SPI flash if that is the system your created.
>I suggested boot SPI FLASH first. If not found, then try SD Card.
But if found there still should be a pin-over ride at boot-up as the firmware may be corrupt, so corrupt it does not allow to read the SD card later on it's own.
The override pin is so you load firmware from SD first, and it's up to this firmware to write itself to SPI flash if that is the system your created.
None yet, but as to not waste any pins, one of the spi lines that is normally pulled-up to 22K, is shorted to ground at boot-up by user with a switch/jumper.
Booting from SD (and skipping FLASH) happens after the short-to-ground is removed.
Unless you want to go with strong and weak pull-up and A/D the answer, as then you can leave the jumper in place.
Some pages back, Chip gave a list of the Pin-Over-Rule table for
* Faster SPI boot, (skips UART stage) and
* Serial boot with and without timeouts (or similar).
This was before the SD discussion, but there are 6 Pins involved in SPI Boot (for safe subset of QuadSPI devices), so there is room for a number of config pullups/pulldowns there.
What happens if you want to use the serial TX? Won't the pullup or down interfere?
IIRC, Chip used Pullups on SPI_CLK and SPI_MOSI, and there is also SPI_CS, SPI_MISO, HOLD#, WP#
that can be used.
Pullup can be light, with a optional stronger pulldown resistor (this avoids needing jumper changes - a solder bridge can define the Pin-Over-Rule choice ),
or you can detect between Pullup present / floating without needing an ADC, with some timing rules on a Digital pin.
So, the MOSI lines and the TX out line are driven by the Prop. I don't think a resistor bigger than say 100 Ohms would have any effect, right?
Strictly, around there is probably correct as a limit, but that represents a 30mA load, so I'd estimate around 1k~3k would be a more practical stronger pull down, with a weak pullup in the 33k~220k region.
No point in wasting energy.
The ratio is chosen to get you safely to a logic low level, also clear of buffer current effects (< 0.5V?)
The weak pull-up just needs to be enough to define the pin, on worst case PVT pin leakage.
The TX line would be best avoided, as that would cause Config choices to change the UART watchdog behaviour, as during all of reset and until the load and run is done, the pins are not under user-control, so are best in a recognized idle state (for TXD that is usually Hi)
As you can engage P2 internal pull-up/pull-down even just temporary before you start SPI, many possibilities for detection some with A/D help.
example two 22K pull-up in parallel, that is solder bridged to 11K when to skip FLASH boot etc.
Through for SD card standard I would like to just use P2 internal pull-up for the lines that need it as to save on BOM.
Through for SD card standard I would like to just use P2 internal pull-up for the lines that need it as to save on BOM.
The P2 pullups are disabled during reset, startup-timers, loading, and right until the user code runs, so that means a zero pullup design is not that practical.
Floating pins are not a great idea on any part that can write.
Perhaps use the 10 or 100uA current sources (available on both the high and low sides) to drive a small current into whatever external pullup or pulldown resistor has been attached. 100uA into 20kohm gives 2 volts, which will be above the input threshold, so you'd just read the pin as normal. Also that small a current isn't likely to damage anything
I say this because using the sigma delta A/D may involve a bit of sequencing to return a result
So I'm flip-flopping maybe, but perhaps SPI flash and serial only is best way...
SPI flash boot is so fast compared to SD boot.
Update from SD could be included in the SPI flash code, if desired.
Just makes things more flexible and simple...
>Update from SD could be included in the SPI flash code, if desired.
What if you made a mistake in that firmware and it no longer reads SD right?
Having things in ROM is brick-prof.
I say this because using the sigma delta A/D may involve a bit of sequencing to return a result
and it may not work...
Not to put a hex on things, but the boot-decisions should use as little of the die as possible, as there may be a case where portions do not work as-expected.
Should that ever occur, you want to be able to test and hopefully ship a rev-A die...
Simple Logic level testing should be enough, and a timed Drive-then-check will detect both 2 part and single part (BOM frugal) pin-over-ride.
A properly formatted SD card vs a hard drive is optimized on 4MB boundaries which is why a preformatted card has 4MB unallocated at the start to give priority to FAT32 clusters. Why not make sure it is properly formatted and put our images there? But for speed nothing beats a pointer to the image which may be a file or not.
I'd rather not rely on weak resistive- or current-drive pin modes for boot up, because we can't emulate those well on the FPGA. Detecting external pull-up or pull-down resistors digitally is easy, though.
If it takes 3ms to check for an SD card, that is negligible. It will take another 14ms to load and validate a signed loader, which is still not a big deal.
I finally got PNut.exe working with the new loader. I had forgotten to use a # on a constant in the ROM loader and it took me two days to figure out what the problem was. I hope to get a new release out tomorrow.
I'd rather not rely on weak resistive- or current-drive pin modes for boot up, because we can't emulate those well on the FPGA. Detecting external pull-up or pull-down resistors digitally is easy, though.
If it takes 3ms to check for an SD card, that is negligible. It will take another 14ms to load and validate a signed loader, which is still not a big deal.
Chip,
It only takes 48us to check if the SD Card exists by sending >74 clocks then get the reply to the first command CMD0.
To initialise the whole SD Card and read the first sector (MBR) takes 3ms.
And in this timing there is debug info to hub going on as well.
Comments
Think I'd just reserve 4 pins for either SD or SPI. After serial, try to boot as SPI flash first. If that doesn't work then try those pins as SD (which is also being interfaced in SPI mode, BTW).
As a way of bootstrap-loading new firmware that writes itself to SPI flash,
in case the previous firmware no longer function, as normally it would look for a newer reversion on SD to update itself, but it's corrupt or you need downgrading.
Right.
Turn off system. Plug in SD card. Turn it back on. SD card updates SPI flash. Turn off system. Remove SD card. Turn system back on. Now running updated code in SPI flash. Simple field upgrade.
An SD card without a signed booter would never cause an SD boot.
I might have it erase the file or change the filename when done so that could leave SD card there.
There might be a lot of resources on the SD card...
It'd have to check for the boot file every time...
I'm pretty sure it will always continue to be bootstrap code, and if it doesn't then other things will break. You do have a point that we should probably leave space for a simple x86 "boot" routine that prints "This disk is not bootable." (a lot of floppies and such already have this).
OTOH I missed the requirement that the boot code be signed, which adds some complexity (we now need room for the signature as well). I like the simplicity and flexibility of re-using the traditional PC booting path, but we almost certainly will need more space than the MBR provides. So other options are:
(1) Require that there be some unused, unallocated sectors between the MBR and the first partition. A lot of PC disks are already formatted this way, and it's a traditional spot to stick second stage bootloaders in. We could just always boot from, say, sectors 2-32 or something like that.
(2) Use a reserved boot partition, as you had suggested earlier. I didn't like that because I wanted to be able to put the boot code on a FAT file system, but I've since realized that the reserved partition could itself contain the FAT reading code and could load and verify an arbitrary FAT file, so it works either way.
One potential issue with all of these schemes is that we might want there to be *two* authorized keys to verify boot signatures: a standard Parallax one (for the basic, first stage boot code) and the user's own key (for the application specific code that's finally booted). This would make formatting the disks a lot easier -- the P2 disk formatter could write a generic first stage boot code that would read from FAT or whatever, and that would in turn verify the final boot code with the user's key. It's not a big deal -- obviously the user could sign their own first stage boot code, and users that want signed boot probably are sophisticated enough to handle the extra complication.
So... if you still want to use SD as a non-boot device, this means that every time you boot the ROM code will:
1. Load from the SD
2. Determine that the loaded block is not signed code.
3. Load from flash
In other words, just to support the ability to auto-program flash from an SD card, you are going to hobble every other use of flash+SD with those first two steps? And add the restriction that they be absolutely sure they never put signed code where it would be accidentally read in step 1?
If you are going to insist on including SD boot, here's a suggestion (which may have already been suggested): allow only one method to be used. In the boot ROM, attempt to detect flash first. If found, boot off of it. If boot fails, fall back to serial. If not found, attempt to detect SD (on the same pins). If found, boot off it. If boot fails, fall back to serial.
Here's the reasoning:
* If you only have flash, then things just work as they do right now.
* If you already have an SD, why bother with flash at all? Just boot from SD always.
* If you want both, you do as we do on P1: boot from flash, then access SD.
Now, I suppose you might be able to do a slight variation on this. If you had both flash and SD, but separate CS lines for the two, then you could allow the SD card to boot by temporarity keeping the flash disabled (CS high). For instance, suppose you were to have a "program" switch that would add a pull-up resistor parallel to standard resistor on the flash CS line. During boot, the test pulse period would not be long enough to pull CS low. Next, the SD boots and loads the "flash auto-programmer". The programmer would just pull CS low and delay long enough to ensure that the flash chip is active. This approach has the advantage of supporting just about all boot variations, as well as prevents accidental boot from SD when you have bootable flash.
No, the Pin-Over-Ride feature is always there, so fast SPI load can always be selected.
This skips even the UART poll, for fastest-possible-boot.
The key word here is "possibly update the SPI flash"
I'd agree this should be possible, but it also should be included in the Pin-Over-Ride table, so it can be prevented, for speed and/or security reasons.
No, I think the Pin-Over-Ride is still there, and it becomes a question of what that Pin-Over-Ride table looks like.
Certainly, you do NOT want to make Fastest-Possible-Boot, slower. Fast boot will be very important.
It takes ~48us to determine that an SD Card exists (a valid reply to software reset command)
It takes ~3ms to validate the SD Card and read the MBR sector 0
A number of posts ago I suggested a pinout for connecting SPI FLASH orSD. This was an either/or, not both!
I suggested boot SPI FLASH first. If not found, then try SD Card.
If you have a FLASH chip, then that can take are of any SD card software - pinouts will vary as not all can be shared.
But if found there still should be a pin-over ride at boot-up as the firmware may be corrupt, so corrupt it does not allow to read the SD card later on it's own.
The override pin is so you load firmware from SD first, and it's up to this firmware to write itself to SPI flash if that is the system your created.
None yet, but as to not waste any pins, one of the spi lines that is normally pulled-up to 22K, is shorted to ground at boot-up by user with a switch/jumper.
Booting from SD (and skipping FLASH) happens after the short-to-ground is removed.
Unless you want to go with strong and weak pull-up and A/D the answer, as then you can leave the jumper in place.
Also one on the serial TX out
Then, have control over boot...
Some pages back, Chip gave a list of the Pin-Over-Rule table for
* Faster SPI boot, (skips UART stage) and
* Serial boot with and without timeouts (or similar).
This was before the SD discussion, but there are 6 Pins involved in SPI Boot (for safe subset of QuadSPI devices), so there is room for a number of config pullups/pulldowns there.
IIRC, Chip used Pullups on SPI_CLK and SPI_MOSI, and there is also SPI_CS, SPI_MISO, HOLD#, WP#
that can be used.
Pullup can be light, with a optional stronger pulldown resistor (this avoids needing jumper changes - a solder bridge can define the Pin-Over-Rule choice ),
or you can detect between Pullup present / floating without needing an ADC, with some timing rules on a Digital pin.
No point in wasting energy.
The ratio is chosen to get you safely to a logic low level, also clear of buffer current effects (< 0.5V?)
The weak pull-up just needs to be enough to define the pin, on worst case PVT pin leakage.
The TX line would be best avoided, as that would cause Config choices to change the UART watchdog behaviour, as during all of reset and until the load and run is done, the pins are not under user-control, so are best in a recognized idle state (for TXD that is usually Hi)
example two 22K pull-up in parallel, that is solder bridged to 11K when to skip FLASH boot etc.
Through for SD card standard I would like to just use P2 internal pull-up for the lines that need it as to save on BOM.
Floating pins are not a great idea on any part that can write.
I say this because using the sigma delta A/D may involve a bit of sequencing to return a result
SPI flash boot is so fast compared to SD boot.
Update from SD could be included in the SPI flash code, if desired.
Just makes things more flexible and simple...
What if you made a mistake in that firmware and it no longer reads SD right?
Having things in ROM is brick-prof.
and it may not work...
Not to put a hex on things, but the boot-decisions should use as little of the die as possible, as there may be a case where portions do not work as-expected.
Should that ever occur, you want to be able to test and hopefully ship a rev-A die...
Simple Logic level testing should be enough, and a timed Drive-then-check will detect both 2 part and single part (BOM frugal) pin-over-ride.
If it takes 3ms to check for an SD card, that is negligible. It will take another 14ms to load and validate a signed loader, which is still not a big deal.
Chip,
It only takes 48us to check if the SD Card exists by sending >74 clocks then get the reply to the first command CMD0.
To initialise the whole SD Card and read the first sector (MBR) takes 3ms.
And in this timing there is debug info to hub going on as well.