commit | 971899af77a9da487e7fa520f81e1b239aae767d | [log] [tgz] |
---|---|---|
author | Patrick Venture <venture@google.com> | Fri Nov 02 09:48:15 2018 -0700 |
committer | Patrick Venture <venture@google.com> | Fri Nov 02 11:22:57 2018 -0700 |
tree | 76aa928dabb1ab6b7a7aa010d94bb7fc56f11e4e | |
parent | 001aba13a0306bb29ef0dae8ebcb4b4d63abbcd7 [diff] |
Revert original implementation in favor of blob-based approach Revert original implementation of the in-band firmware update to pivot to using a blob-based implementation. Blob-based design is under review here: https://gerrit.openbmc-project.xyz/14444 Revert "tools: starting burn_my_bmc host utility" This reverts commit 7dc4670d4be4884e0c6486ca4f0e799116935096. Revert "phosphor-ipmi-flash: main: move to iana header" This reverts commit e39f2b3a9a19b8e788a7225a0d291716325b77ee. Revert "update clang-format" This reverts commit 1aedab2391cd883e95ebde0129fcaf88d7f16233. Revert "Build as c++17" This reverts commit 004fb909202e39b34cb72d31390facd525b04c9b. Revert "clang-format: always break template declarations" This reverts commit ff0ee70f0fb8e0c2173f826f4d96fbfced09ca14. Revert "clang-format-6.0 bump fixes" This reverts commit 8f378c927a5789f30ba625595153bc1422d511dc. Revert "flash-ipmi: implement flashAbort" This reverts commit 605f75f7c026b5c2f454de155f6f211b2c3b187f. Revert "flash-ipmi: implement flashDataVerify" This reverts commit 9c6baad43fe7d1db8e449766eed35865ce6a2e4b. Revert "flash-ipmi: implement flashVerifyCheck" This reverts commit 7fc66de0d5465f4d25033d6baf48b6489f843331. Revert "ipmi: start implementing flashVerifyCheck" This reverts commit fdc65b2524bee544d35a6e2cbeef4c2f68aeb8fd. Revert "flash-ipmi: implement flashHashFinish" This reverts commit d5f590f955a67715e7903a04c3a8028f1d4f2664. Revert "flash-ipmi: implement flashHashData" This reverts commit cbe51498953d7bd29f516cdfcdb654706b463d2e. Revert "flash-ipmi: implement flashStartHash" This reverts commit 6f17bd2220d723fd349077ccd96845a5652403e0. Revert "flash-ipmi: implement flashDataFinish" This reverts commit 57703664cd76c2744adf4c5fa504388909efa824. Revert "flash-ipmi: implement flashDataBlock" This reverts commit 3c086f2f649d1c4cc7926cbd9375a39dd23e6997. Revert "update copyright year" This reverts commit 514f648b76c1a855a356e5a4ca83fd5bf6c53b3f. Revert "flash-ipmi: implement flashStartTransfer" This reverts commit 8ec019fdc15cb021f2c7d4cefb85a8ccd3581159. Revert "ipmi: start implementing flashAbort" This reverts commit 5c251ca550f56722280dcf17b8c48832ace07142. Revert "ipmi: start implementing flashDataVerify" This reverts commit 1cb87d25f79cfb905611b81348fbccb362f5e29a. Revert "main: cleanup command handling" This reverts commit 9a5a79a0797294ba9f5c7b2ab79e4dcbacac0c44. Revert "test: rework ipmi validate test as table" This reverts commit 39b3a82609511e2d855a2182f22361cc1332bb25. Revert "ipmi: start implementing flashHashFinish" This reverts commit fbc7d191eb6d49ff93379e90f372960b799b25c4. Revert "ipmi: start implementing flashHashData" This reverts commit cfe66877a5d7cc64bcce5c8789ca164edf9f1c56. Revert "ipmi: start implementing flashStartHash" This reverts commit 8d9f7322f46afaab81e32d1999f5bc000f1ba9a6. Revert "ipmi: start implementing flashDataFinish" This reverts commit 2c1205db94647c196c154bae0e106933b9ff526e. Revert "ipmi: promote min length check to earlier" This reverts commit a53a7b35085ddd41ef3cc47b084d29a1f413e818. Revert "ipmi: start implementing flashDataBlock" This reverts commit 79e131fce6e308f7e0f96bc71b07a7f0ebeeffcd. Revert "ipmi: start implementing flashStartTransfer" This reverts commit 54c3b53c0d0c7991469ab1be97bdf4e3f301e8f5. Revert "add flash-ipmi header defining sub-commands" This reverts commit 3d1786bcd038e4d042d268737a9b874fd667bf84. Revert "main: start with no-op handler" This reverts commit accc91799d6a1de4726313b907e5dfa7555bf919. Change-Id: I1c4dc9dcd2bf7d110240a028a329fcb1e01a4e5b Signed-off-by: Patrick Venture <venture@google.com>
This document describes the OpenBmc software implementing the secure flash update mechanism.
This supports two methods of providing the image to stage. You can send the file over IPMI packets, which is a very slow process. A 32-MiB image can take ~3 hours to send via this method. This can be done in <1 minutes via the PCI bridge, or just a few minutes via LPC depending on the size of the mapped area.
This is implemented in the Google OEM number space: 11129. This is also implemented under the Firmware netfn.
It is command: 127
The OpenBmc tool, not yet upstreamed, supports this approach.
The image must be signed via the production or development keys, the former being required for production builds. The image itself and the image signature are separately sent to the BMC for verification. The verification package source is beyond the scope of this design.
Basically the IPMI OEM handler receives the image in one fashion or another and then triggers the verify_image
service. Then, the user polls until the result is reported. This is because the image verification process can exceed 10 seconds.
The image flashing mechanism itself is the initramfs stage during reboot. It will check for files named "image-*
" and flash them appropriately for each name to section. The IPMI command creates a file /run/initramfs/bmc-image
and writes the contents there. It was found that writing it in /tmp could cause OOM errors moving it on low memory systems, whereas renaming a file within the same folder seems to only update the directory inode's contents.
The staging file path can be controlled via software configuration. The image is assumed to be the tarball contents and is written into /tmp/{tarball_name}.gz
TODO: Flesh out the UBI approach.
To determine if the bridge sequence is supported you can send the FlashRequestRegion
subcommand and see if it returns success with an address. However, for the sake of sanity, there is also a FlashVersion
subcommand that'll return the version of the protocol.
If you're updating the image entirely over IPMI, then you should expect to send the following sequence of commands:
FlashStartTransfer
FlashDataBlock
(for each piece of the image)FlashDataFinish
FlashStartHash
FlashHashData
(for each piece of the hash)FlashHashFinish
FlashDataVerify
FlashVerifyCheck
(repeatedly until it results with 3-5s sleeps)If you're using some region to send the image and hash, you should expect to send the following sequences of commands:
FlashStartTransfer
FlashMapRegionLpc
(if necessary)FlashRequestRegion
FlashDataExtBlock
(for each piece of the image)FlashDataFinish
FlashStartHash
FlashHashExtData
(for each piece of the hash)FlashHashFinish
FlashDataVerify
FlashVerifyCheck
(repeatedly until it results with 3-5s sleeps)The PCI-to-AHB bridge is only available on some systems, and provides a 64-KiB region that can be pointed anywhere in BMC memory space.
It is controlled by two PCIe MMIO addresses that are based on BAR1. Further specifics can be found in the ASPEED data sheet. However, the way it works in this instance is that the BMC has configured a region of physical memory it plans to use as this buffer region. The BMC returns the address to host program so it can configure the PCIe MMIO registers properly for that address.
As an example, a 64-KiB region a platform can use for this approach is the last 64-KiB of the VGA reserved region: 0x47ff0000
.
Like the P2A mechanism, the BMC must have already allocated a memory region with a platform-defined size. This region is mapped to LPC space at the request of the host, which also specifies the LPC address and region size in the mapping request subcommand. The host can then read the actual LPC address at which the BMC was able to map, checking that it's usable.
As future work, USB should be considered an option for staging the image to be copied to the BMC.
The following details each subcommand with which you'll lead the body of the command. Unlike some designs, the responses don't necessarily include the corresponding sub-command, partially because this protocol is meant to be used by one user at a time and trying to use otherwise can have negative effects and is not supported.
In the following, any reference to the command body starts after the 3 bytes of OEM header, and the 1-byte subcommand.
This will now also go after the firmware function.
The FlashStartTransfer command expects to receive a body of:
struct StartTx { uint32_t length; /* Maximum image length is 4GiB */ };
However, this data is presently ignored.
This command will first close out and abort any previous attempt at updating the flash.
On success it will return 1 byte of 0x00
, in the body, after the 3-byte OEM portion.
This command expects to receive a body of:
struct ChunkHdr { uint32_t offset; /* The byte sequence start, (0 based). */ };
However, this data is presently ignored.
Immediately following this structure are the bytes to write. The length of the entire packet is variable and handled at a higher level, therefore the number of bytes to write is the size of the command body less the sub-command (1 byte) and less the structure size (4 bytes).
On success it will return 1 byte of 0x00
, in the body, after the 3-byte OEM portion.
This command expects the body to be empty.
On success it will return 1 byte of 0x00
, in the body, after the 3-byte OEM portion.
The FlashStartHash command expects to receive a body of:
struct StartTx { uint32_t length; /* Maximum image length is 4GiB */ };
This is used! But it's only checked to see that it's non-zero.
On success it will return 1 byte of 0x00
, in the body, after the 3-byte OEM portion.
This command expects to receive a body of:
struct ChunkHdr { uint32_t offset; /* The byte sequence start, (0 based). */ };
However, this data is presently ignored.
Immediately following this structure are the bytes to write. The length of the entire packet is variable and handled at a higher level, therefore the number of bytes to write is the size of the command body less the sub-command (1 byte) and less the structure size (4 bytes).
On success it will return 1 byte of 0x00
, in the body, after the 3-byte OEM portion.
This command expects the body to be empty.
On success it will return 1 byte of 0x00
, in the body, after the 3-byte OEM portion.
This command expects the body to be empty.
This will start the verify_image
systemd service.
On success it will return 1 byte of 0x00
, in the body, after the 3-byte OEM portion.
This command expects the body to be empty.
This command deletes any temporary files or flash image, hashes, etc.
On success it will return 1 byte of 0x00
, in the body, after the 3-byte OEM portion.
This command expects the body to be empty.
This command opens the verification result file and checks to see if it contains: "running
", "success
" or "failed
". This then packs that as a 1 byte of result of:
enum VerifyCheckResponses { VerifyRunning = 0x00, VerifySuccess = 0x01, VerifyFailed = 0x02, VerifyOther = 0x03, };
This command expects the body to be empty.
Returns 16-bit version sequence (little endian), in the body, after the 3-byte OEM portion.
Should return type string "LPC" or "P2A" but does not yet. We need to add this into another command, such as FlashRegionSupportedType
returns 32-bit address (little endian) of either the BMC's memory buffer in BAR space (P2A bridge) or in LPC FW space (LPC bridge).
This command expects to receive:
struct ExtChunkHdr { uint32_t length; /* Length of the data queued (little endian). */ };
A design limitation of this is that it expects to be able to copy and write the data before the IPMI command times out, which should be completely possible.
On success it will return 1 byte of 0x00
, in the body, after the 3-byte OEM portion.
This command expects to receive:
struct ExtChunkHdr { uint32_t length; /* Length of the data queued (little endian). */ };
A design limitation of this is that it expects to be able to copy and write the data before the IPMI command times out, which should be completely possible.
On success it will return 1 byte of 0x00
, in the body, after the 3-byte OEM portion.
This command maps a chunk (size specified by host) of the BMC memory into LPC space at a specified address. It expects to receive:
struct LpcRegion { uint32_t address; /* Host LPC address where the chunk is to be mapped. */ uint32_t length; /* Size of the chunk to be mapped. */ };
The command will return 1 byte in the response body with value:
After a success map to LPC space, the host can use FlashRequestRegion to read the LPC address of the chunk mapped, which should match that requested.