Shop OBEX P1 Docs P2 Docs Learn Events
Some thoughts on the booting and flash layout of Prop 2 — Parallax Forums

Some thoughts on the booting and flash layout of Prop 2

pedwardpedward Posts: 1,642
edited 2014-03-21 12:19 in Propeller 2
I've been giving some thought to the P2 boot and flash layout.

There are 2 concerns which balance equally: security and robustness.

Security is important to prevent unauthorized code from executing on a product, secondary to that is protecting the IP. Robustness is the ability to recover from a botched field upgrade and still work properly.

I feel the latter is simply addresses with ping-pong software upgrades.

The notion is that the user programs have a version number associated with them and the chip is able to load the version with the higher number. In this way you have a fallback path for failed upgrades.

The primary problem with robustness is that it can also preclude proper security. You need some way to prevent tampering of the ping-pong recovery method, which could facilitate attacks by using older code that contains vulnerabilities.

The way handset makers do this is with e-fuses. The P2 will have 172 e-fuses, of which only 128 are used by the authentication code. This leaves 44 fuse bits for user purposes.

I would like to have ping-pong 1st stage bootloaders with version checking, but I think that defines things too tightly. The 1st stage bootloader should be so simple that it won't change from one release to another and it shouldn't contain software bugs that are so gross as to require a lockout.

However, I think the scheme I'm about to layout will preclude a ping-pong bootloader upgrade because only authenticated code can run, and if your authenticated code respects lock bits, you have effectively tied a firmware release to a bootloader, and if the user program has lock bits turned on, the bootloader will not load older code that is of a different algorithm.

What I wrote above might not make sense, but let me explain further.

We have 44 user fuses, we can set aside a few of those for "lock bits", or bits which are fused in the chip and must match the user firmware. When you distribute major releases of firmware, you could blow fuses as part of the update (after verification of course). If the bootloader doesn't have a match between the firmware in the flash and the fuses, it will refuse to run it.

This strategy *does* break ping-pong loads at major updates because if you blow a fuse, you can't fallback to a previous firmware rev. In this case, perhaps your 1st stage loader goes into a monitor mode and allows you to write to the flash a new image, which is totally fine because your firmware can't run unless authenticated.

So, in practice, here's the steps/logic:
  • ROM loads 1st stage bootloader
  • ROM authenticates 1st stage and runs if it passes auth
  • 1st stage does auth of data at address XXXXX and validates good/bad
  • 1st stage does auth of data at address XXXXX+256KB and validates good/bad
  • If one of the firmwares does not pass the auth, it is ignored
  • If both images are good, it then looks at a version number in the first block of both images
  • The block with the higher version number is checked to see if it's lock-bit/fuse map matches the chip
  • If the higher version firmware matches the fuse map, it is loaded into RAM and 2nd stage bootloading begins (described later)
  • If the remaining firmware does not pass lock-bit test, then drop into flash loading monitor mode, or halt, depending on the whim of the developer
  • If both firmwares pass auth and the higher version does not pass lock-bit test, but lower version does, run the lower version firmware

2nd stage bootloading is a multi-step process:

The 1st stage has validated the code, but the code may still be encrypted.
The typical place for HEAP on the Propeller is at the end of RAM, so this place is used to store a 2nd stage bootloader.
The 2nd stage bootloader needs to decrypt the code, or if not encrypted, just jump to the start of code.

I have laid out the details of the 2nd stage in post #5860

Comments

  • cgraceycgracey Posts: 14,151
    edited 2014-03-20 16:40
    I like this idea of loading another authenticated block into the flash, and the booter always checks to how many such blocks there are, and picks by version number.
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-03-20 17:01
    Chip,

    Would there be room in the monitor for a flash read command?

    ie

    flashread flashaddr hubaddr numlongs

    (does not matter what single letter command code you assign flashread)

    Basically I think this would be useful for loading code saved in the flash *without authentication* for testing boot loaders etc.

    p.s.

    I quickly read over the monitor code... nice & clean!
  • cgraceycgracey Posts: 14,151
    edited 2014-03-20 17:41
    Chip,

    Would there be room in the monitor for a flash read command?

    ie

    flashread flashaddr hubaddr numlongs

    (does not matter what single letter command code you assign flashread)

    Basically I think this would be useful for loading code saved in the flash *without authentication* for testing boot loaders etc.

    p.s.

    I quickly read over the monitor code... nice & clean!


    There's not much room for anything else. I thought it would be good to have monitor commands for loading some of the flash, too, and even signing it with HMAC (key=0) and writing it back.

    The problem with doing anything more than reading the flash sequentially from address zero, is that different chips can have different commands. Flash chips are uniform enough to allow for simple reads from start of memory, but after that they vary.
  • potatoheadpotatohead Posts: 10,261
    edited 2014-03-20 17:45
    The next best thing is to just have a small bit of PASM ready to upload through the monitor. Once it's there, it can be launched easily enough.

    Since the Monitor has a HUBEX command, just make a package, upload it all, and run it. The package sends to flash, verifies, whatever.
  • cgraceycgracey Posts: 14,151
    edited 2014-03-20 18:12
    potatohead wrote: »
    The next best thing is to just have a small bit of PASM ready to upload through the monitor. Once it's there, it can be launched easily enough.

    Since the Monitor has a HUBEX command, just make a package, upload it all, and run it. The package sends to flash, verifies, whatever.


    Yes, you could just paste some lines into the monitor and accomplish this.
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-03-20 18:16
    True. Works for me.
    potatohead wrote: »
    The next best thing is to just have a small bit of PASM ready to upload through the monitor. Once it's there, it can be launched easily enough.

    Since the Monitor has a HUBEX command, just make a package, upload it all, and run it. The package sends to flash, verifies, whatever.
  • pedwardpedward Posts: 1,642
    edited 2014-03-21 08:52
    For bootstrapping through the monitor, you can just twiddle bits remotely with commands. You could stream the instructions to the monitor and support any flash chip.

    I was expecting there would be multiple booters that would be written to support different flash chips and sources (SD booter for example).
  • jmgjmg Posts: 15,173
    edited 2014-03-21 12:19
    pedward wrote: »
    For bootstrapping through the monitor, you can just twiddle bits remotely with commands. You could stream the instructions to the monitor and support any flash chip.

    That sounds like quite a good idea, and removes the management and multi-step issues of dual-loaders.
    All that is needed is complete access to all IO controls, and I would include the SerDes in this.

    If the commands can set any Ctr and SerDes mode, on any pins, and also wiggle pins in SW as needed, that covers 99% of any Loader schemes.
    Older devices needed timed pulses as part of programming, I'm not sure of any modern ones that do.
    (Some of the suggested Counter modes would support this accurate timing, even with poorly elastic serial links )
Sign In or Register to comment.