Support static and constant firmware update instances.

Refactored the update handler to make firmware header support and initialization-time parameter.  This allows this flag to be part of the constant structure.
This commit is contained in:
Christopher Weimer 2022-10-17 16:49:31 +00:00
Родитель ed5f1c245c
Коммит 2db1528c5f
25 изменённых файлов: 2814 добавлений и 539 удалений

Просмотреть файл

@ -593,7 +593,7 @@ static int pcr_get_measurement_data_internal (struct pcr_bank *pcr, uint8_t meas
break;
case PCR_DATA_TYPE_FLASH: {
struct flash *flash_device = measured_data->data.flash.flash;
const struct flash *flash_device = measured_data->data.flash.flash;
size_t read_addr = measured_data->data.flash.addr + offset;
if (offset > (measured_data->data.flash.length - 1)) {

Просмотреть файл

@ -55,7 +55,7 @@ struct pcr_measured_data {
} memory; /**< Container for measured data stored in memory */
struct {
struct flash *flash; /**< Flash device containing the measured data */
const struct flash *flash; /**< Flash device containing the measured data */
uint32_t addr; /**< Address in flash */
size_t length; /**< Measured data length */
} flash; /**< Container for measured data stored in flash */

Просмотреть файл

@ -17,7 +17,7 @@
*
* @return 0 if the header information was successfully loaded from flash or an error code.
*/
int image_header_init (struct image_header *header, struct flash *flash, uint32_t addr,
int image_header_init (struct image_header *header, const struct flash *flash, uint32_t addr,
uint32_t magic_num, size_t max_len)
{
int status;
@ -52,7 +52,7 @@ int image_header_init (struct image_header *header, struct flash *flash, uint32_
* Release the recovery image header data.
*
* @param header The header instance to release.
*/
*/
void image_header_release (struct image_header *header)
{
if (header) {
@ -68,9 +68,9 @@ void image_header_release (struct image_header *header)
* @param flash The flash that contains the image header.
* @param addr The base address of the header.
*
* @return 0 if header data was successfully loaded from flash or an error code.
* @return 0 if header data was successfully loaded from flash or an error code.
*/
int image_header_load_data (struct image_header *header, struct flash *flash, uint32_t addr)
int image_header_load_data (struct image_header *header, const struct flash *flash, uint32_t addr)
{
size_t length;
int status;
@ -102,7 +102,7 @@ int image_header_load_data (struct image_header *header, struct flash *flash, ui
*
* @return The total number of bytes in the header.
*/
int image_header_get_length (struct image_header *header)
int image_header_get_length (const struct image_header *header)
{
if (header) {
return header->info.length;

Просмотреть файл

@ -29,12 +29,13 @@ struct image_header {
};
int image_header_init (struct image_header *header, struct flash *flash, uint32_t addr,
int image_header_init (struct image_header *header, const struct flash *flash, uint32_t addr,
uint32_t magic_num, size_t max_len);
void image_header_release (struct image_header *header);
int image_header_load_data (struct image_header *header, struct flash *flash, uint32_t addr);
int image_header_get_length (struct image_header *header);
int image_header_load_data (struct image_header *header, const struct flash *flash, uint32_t addr);
int image_header_get_length (const struct image_header *header);
#define IMAGE_HEADER_ERROR(code) ROT_ERROR (ROT_MODULE_IMAGE_HEADER, code)

Просмотреть файл

@ -19,7 +19,7 @@ struct app_context {
*
* @return 0 if the application context has been saved or an error code.
*/
int (*save) (struct app_context *context);
int (*save) (const struct app_context *context);
};

Просмотреть файл

@ -22,9 +22,9 @@
*
* @return 0 if the application image is valid or an error code.
*/
int app_image_verification (struct flash *flash, uint32_t start_addr, struct hash_engine *hash,
struct rsa_engine *rsa, const struct rsa_public_key *pub_key, uint8_t *hash_out,
size_t hash_length)
int app_image_verification (const struct flash *flash, uint32_t start_addr,
struct hash_engine *hash, struct rsa_engine *rsa, const struct rsa_public_key *pub_key,
uint8_t *hash_out, size_t hash_length)
{
return app_image_verification_with_header (flash, start_addr, 0, hash, rsa, pub_key,
hash_out, hash_length);
@ -45,7 +45,7 @@ int app_image_verification (struct flash *flash, uint32_t start_addr, struct has
*
* @return 0 if the application image and the additional header are valid or an error code.
*/
int app_image_verification_with_header (struct flash *flash, uint32_t start_addr,
int app_image_verification_with_header (const struct flash *flash, uint32_t start_addr,
size_t header_length, struct hash_engine *hash, struct rsa_engine *rsa,
const struct rsa_public_key *pub_key, uint8_t *hash_out, size_t hash_legnth)
{
@ -88,8 +88,8 @@ int app_image_verification_with_header (struct flash *flash, uint32_t start_addr
*
* @return 0 if the entire application image was successfully loaded into memory or an error code.
*/
int app_image_load (struct flash *flash, uint32_t start_addr, uint8_t *load_addr, size_t max_length,
size_t *load_length)
int app_image_load (const struct flash *flash, uint32_t start_addr, uint8_t *load_addr,
size_t max_length, size_t *load_length)
{
uint32_t length;
int status;
@ -136,7 +136,7 @@ int app_image_load (struct flash *flash, uint32_t start_addr, uint8_t *load_addr
*
* @return 0 if the application image was loaded to memory and verified as good or an error code.
*/
int app_image_load_and_verify (struct flash *flash, uint32_t start_addr, uint8_t *load_addr,
int app_image_load_and_verify (const struct flash *flash, uint32_t start_addr, uint8_t *load_addr,
size_t max_length, struct hash_engine *hash, struct rsa_engine *rsa,
const struct rsa_public_key *pub_key, uint8_t *hash_out, size_t hash_length,
size_t *load_length)
@ -165,7 +165,7 @@ int app_image_load_and_verify (struct flash *flash, uint32_t start_addr, uint8_t
*
* @return 0 if the application image was loaded to memory and verified as good or an error code.
*/
int app_image_load_and_verify_with_header (struct flash *flash, uint32_t start_addr,
int app_image_load_and_verify_with_header (const struct flash *flash, uint32_t start_addr,
size_t header_length, uint8_t *load_addr, size_t max_length, struct hash_engine *hash,
struct rsa_engine *rsa, const struct rsa_public_key *pub_key, uint8_t *hash_out,
size_t hash_length, size_t *load_length)
@ -265,7 +265,7 @@ hash_fail:
*
* @return 0 if the image signature was successfully retrieved or an error code.
*/
int app_image_get_signature (struct flash *flash, uint32_t start_addr, uint8_t *sig_out,
int app_image_get_signature (const struct flash *flash, uint32_t start_addr, uint8_t *sig_out,
size_t sig_length)
{
uint32_t length;
@ -299,7 +299,7 @@ int app_image_get_signature (struct flash *flash, uint32_t start_addr, uint8_t *
*
* @return 0 if the image hash was successfully calculated or an error code.
*/
int app_image_get_hash (struct flash *flash, uint32_t start_addr, struct hash_engine *hash,
int app_image_get_hash (const struct flash *flash, uint32_t start_addr, struct hash_engine *hash,
uint8_t *hash_out, size_t hash_length)
{
return app_image_get_hash_with_header (flash, start_addr, 0, hash, hash_out, hash_length);
@ -319,8 +319,8 @@ int app_image_get_hash (struct flash *flash, uint32_t start_addr, struct hash_en
*
* @return 0 if the image hash was successfully calculated or an error code.
*/
int app_image_get_hash_with_header (struct flash *flash, uint32_t start_addr, size_t header_length,
struct hash_engine *hash, uint8_t *hash_out, size_t hash_length)
int app_image_get_hash_with_header (const struct flash *flash, uint32_t start_addr,
size_t header_length, struct hash_engine *hash, uint8_t *hash_out, size_t hash_length)
{
uint32_t length;
int status;
@ -351,7 +351,7 @@ int app_image_get_hash_with_header (struct flash *flash, uint32_t start_addr, si
*
* @return 0 if the data address was successfully retrieved or an error code.
*/
int app_image_get_data_addr (struct flash *flash, uint32_t start_addr, uint32_t *data_addr)
int app_image_get_data_addr (const struct flash *flash, uint32_t start_addr, uint32_t *data_addr)
{
if ((flash == NULL) || (data_addr == NULL)) {
return APP_IMAGE_INVALID_ARGUMENT;
@ -372,7 +372,7 @@ int app_image_get_data_addr (struct flash *flash, uint32_t start_addr, uint32_t
*
* @return 0 if the image length was successfully retrieved or an error code.
*/
int app_image_get_length (struct flash *flash, uint32_t start_addr, uint32_t *img_length)
int app_image_get_length (const struct flash *flash, uint32_t start_addr, uint32_t *img_length)
{
if ((flash == NULL) || (img_length == NULL)) {
return APP_IMAGE_INVALID_ARGUMENT;
@ -392,7 +392,7 @@ int app_image_get_length (struct flash *flash, uint32_t start_addr, uint32_t *im
*
* @return 0 if the image ending was successfully retrieved or an error code.
*/
int app_image_get_image_end (struct flash *flash, uint32_t start_addr, uint32_t *end_addr)
int app_image_get_image_end (const struct flash *flash, uint32_t start_addr, uint32_t *end_addr)
{
uint32_t length;
int status;

Просмотреть файл

@ -21,34 +21,34 @@
#define APP_IMAGE_SIG_LENGTH 256
int app_image_verification (struct flash *flash, uint32_t start_addr, struct hash_engine *hash,
struct rsa_engine *rsa, const struct rsa_public_key *pub_key, uint8_t *hash_out,
size_t hash_length);
int app_image_verification_with_header (struct flash *flash, uint32_t start_addr,
int app_image_verification (const struct flash *flash, uint32_t start_addr,
struct hash_engine *hash, struct rsa_engine *rsa, const struct rsa_public_key *pub_key,
uint8_t *hash_out, size_t hash_length);
int app_image_verification_with_header (const struct flash *flash, uint32_t start_addr,
size_t header_length, struct hash_engine *hash, struct rsa_engine *rsa,
const struct rsa_public_key *pub_key, uint8_t *hash_out, size_t hash_length);
int app_image_load (struct flash *flash, uint32_t start_addr, uint8_t *load_addr, size_t max_length,
size_t *load_length);
int app_image_load_and_verify (struct flash *flash, uint32_t start_addr, uint8_t *load_addr,
int app_image_load (const struct flash *flash, uint32_t start_addr, uint8_t *load_addr,
size_t max_length, size_t *load_length);
int app_image_load_and_verify (const struct flash *flash, uint32_t start_addr, uint8_t *load_addr,
size_t max_length, struct hash_engine *hash, struct rsa_engine *rsa,
const struct rsa_public_key *pub_key, uint8_t *hash_out, size_t hash_length,
size_t *load_length);
int app_image_load_and_verify_with_header (struct flash *flash, uint32_t start_addr,
int app_image_load_and_verify_with_header (const struct flash *flash, uint32_t start_addr,
size_t header_length, uint8_t *load_addr, size_t max_length, struct hash_engine *hash,
struct rsa_engine *rsa, const struct rsa_public_key *pub_key, uint8_t *hash_out,
size_t hash_length, size_t *load_length);
int app_image_get_signature (struct flash *flash, uint32_t start_addr, uint8_t *sig_out,
int app_image_get_signature (const struct flash *flash, uint32_t start_addr, uint8_t *sig_out,
size_t sig_length);
int app_image_get_hash (struct flash *flash, uint32_t start_addr, struct hash_engine *hash,
int app_image_get_hash (const struct flash *flash, uint32_t start_addr, struct hash_engine *hash,
uint8_t *hash_out, size_t hash_length);
int app_image_get_hash_with_header (struct flash *flash, uint32_t start_addr, size_t header_length,
struct hash_engine *hash, uint8_t *hash_out, size_t hash_length);
int app_image_get_hash_with_header (const struct flash *flash, uint32_t start_addr,
size_t header_length, struct hash_engine *hash, uint8_t *hash_out, size_t hash_length);
int app_image_get_data_addr (struct flash *flash, uint32_t start_addr, uint32_t *data_addr);
int app_image_get_length (struct flash *flash, uint32_t start_addr, uint32_t *img_length);
int app_image_get_image_end (struct flash *flash, uint32_t start_addr, uint32_t *end_addr);
int app_image_get_data_addr (const struct flash *flash, uint32_t start_addr, uint32_t *data_addr);
int app_image_get_length (const struct flash *flash, uint32_t start_addr, uint32_t *img_length);
int app_image_get_image_end (const struct flash *flash, uint32_t start_addr, uint32_t *end_addr);
#define APP_IMAGE_ERROR(code) ROT_ERROR (ROT_MODULE_APP_IMAGE, code)

Просмотреть файл

@ -50,7 +50,7 @@ union firmware_component_header_format {
*
* @return 0 if the component was successfully initialize or an error code.
*/
int firmware_component_init (struct firmware_component *image, struct flash *flash,
int firmware_component_init (struct firmware_component *image, const struct flash *flash,
uint32_t start_addr, uint32_t marker)
{
int status;
@ -103,8 +103,8 @@ int firmware_component_init (struct firmware_component *image, struct flash *fla
*
* @return 0 if the component was successfully initialized or an error code.
*/
int firmware_component_init_with_header (struct firmware_component *image, struct flash *flash,
uint32_t start_addr, uint32_t marker, size_t header_length)
int firmware_component_init_with_header (struct firmware_component *image,
const struct flash *flash, uint32_t start_addr, uint32_t marker, size_t header_length)
{
int status;
@ -138,7 +138,7 @@ void firmware_component_release (struct firmware_component *image)
*
* @return The size of the component image.
*/
static size_t firmware_component_get_image_length (struct firmware_component *image)
static size_t firmware_component_get_image_length (const struct firmware_component *image)
{
return image->header.info.length + FW_COMPONENT_HDR (image, 0).length + image->offset;
}
@ -152,7 +152,7 @@ static size_t firmware_component_get_image_length (struct firmware_component *im
*
* @return 0 if the signature was read or an error code.
*/
static int firmware_component_read_signature_data (struct firmware_component *image,
static int firmware_component_read_signature_data (const struct firmware_component *image,
uint8_t **signature, size_t *sig_length)
{
int status;
@ -187,8 +187,9 @@ static int firmware_component_read_signature_data (struct firmware_component *im
*
* @return 0 if the component image is valid or an error code.
*/
int firmware_component_verification (struct firmware_component *image, struct hash_engine *hash,
struct signature_verification *verification, uint8_t *hash_out, size_t hash_length)
int firmware_component_verification (const struct firmware_component *image,
struct hash_engine *hash, struct signature_verification *verification, uint8_t *hash_out,
size_t hash_length)
{
uint8_t *signature;
size_t sig_length;
@ -228,7 +229,7 @@ int firmware_component_verification (struct firmware_component *image, struct ha
*
* @return 0 if the component was loaded into memory or an error code.
*/
int firmware_component_load (struct firmware_component *image, uint8_t *load_addr,
int firmware_component_load (const struct firmware_component *image, uint8_t *load_addr,
size_t max_length, size_t *load_length)
{
int status;
@ -270,7 +271,7 @@ int firmware_component_load (struct firmware_component *image, uint8_t *load_add
*
* @return 0 if the component was loaded to memory and verified as good or an error code.
*/
int firmware_component_load_and_verify (struct firmware_component *image, uint8_t *load_addr,
int firmware_component_load_and_verify (const struct firmware_component *image, uint8_t *load_addr,
size_t max_length, struct hash_engine *hash, struct signature_verification *verification,
uint8_t *hash_out, size_t hash_length, size_t *load_length)
{
@ -383,8 +384,9 @@ hash_fail:
*
* @return 0 if the component data is contained on the destination flash or an error code.
*/
static int firmware_component_copy_to_flash (struct firmware_component *image, struct flash *flash,
uint32_t dest_addr, size_t max_length, size_t *copy_length, bool force_copy)
static int firmware_component_copy_to_flash (const struct firmware_component *image,
const struct flash *flash, uint32_t dest_addr, size_t max_length, size_t *copy_length,
bool force_copy)
{
int status;
@ -444,10 +446,11 @@ exit:
*
* @return 0 if the component was successfully copied to flash or an error code.
*/
int firmware_component_copy (struct firmware_component *image, struct flash *flash,
int firmware_component_copy (const struct firmware_component *image, const struct flash *flash,
uint32_t dest_addr, size_t max_length, size_t *copy_length)
{
return firmware_component_copy_to_flash (image, flash, dest_addr, max_length, copy_length, true);
return firmware_component_copy_to_flash (image, flash, dest_addr, max_length, copy_length,
true);
}
/**
@ -465,10 +468,11 @@ int firmware_component_copy (struct firmware_component *image, struct flash *fla
*
* @return 0 if the component data is contained on the destination flash or an error code.
*/
int firmware_component_compare_and_copy (struct firmware_component *image, struct flash *flash,
uint32_t dest_addr, size_t max_length, size_t *copy_length)
int firmware_component_compare_and_copy (const struct firmware_component *image,
const struct flash *flash, uint32_t dest_addr, size_t max_length, size_t *copy_length)
{
return firmware_component_copy_to_flash (image, flash, dest_addr, max_length, copy_length, false);
return firmware_component_copy_to_flash (image, flash, dest_addr, max_length, copy_length,
false);
}
/**
@ -478,7 +482,7 @@ int firmware_component_compare_and_copy (struct firmware_component *image, struc
*
* @return The length of the image signature.
*/
size_t firmware_component_get_signature_length (struct firmware_component *image)
size_t firmware_component_get_signature_length (const struct firmware_component *image)
{
if (image) {
return FW_COMPONENT_HDR (image, 0).sig_length;
@ -498,7 +502,7 @@ size_t firmware_component_get_signature_length (struct firmware_component *image
* @return The length of the signature in the buffer or an error code. Use ROT_IS_ERROR to check
* the return for an error.
*/
int firmware_component_get_signature (struct firmware_component *image, uint8_t *sig_out,
int firmware_component_get_signature (const struct firmware_component *image, uint8_t *sig_out,
size_t sig_length)
{
size_t length;
@ -534,7 +538,7 @@ int firmware_component_get_signature (struct firmware_component *image, uint8_t
*
* @return 0 if the hash was calculated successfully or an error code.
*/
int firmware_component_get_hash (struct firmware_component *image, struct hash_engine *hash,
int firmware_component_get_hash (const struct firmware_component *image, struct hash_engine *hash,
uint8_t *hash_out, size_t hash_length)
{
size_t length;
@ -560,7 +564,7 @@ int firmware_component_get_hash (struct firmware_component *image, struct hash_e
*
* @return The flash address for the start of firmware data.
*/
uint32_t firmware_component_get_data_addr (struct firmware_component *image)
uint32_t firmware_component_get_data_addr (const struct firmware_component *image)
{
if (image) {
return image->start_addr + image->offset + image->header.info.length;
@ -578,7 +582,7 @@ uint32_t firmware_component_get_data_addr (struct firmware_component *image)
*
* @return The size of the component image.
*/
size_t firmware_component_get_length (struct firmware_component *image)
size_t firmware_component_get_length (const struct firmware_component *image)
{
if (image) {
return FW_COMPONENT_HDR (image, 0).length;
@ -597,7 +601,7 @@ size_t firmware_component_get_length (struct firmware_component *image)
*
* @return The address at the end of the image.
*/
uint32_t firmware_component_get_image_end (struct firmware_component *image)
uint32_t firmware_component_get_image_end (const struct firmware_component *image)
{
if (image) {
return image->start_addr + firmware_component_get_image_length (image) +

Просмотреть файл

@ -17,42 +17,43 @@
* Handler for a single application component within a firmware image.
*/
struct firmware_component {
struct flash *flash; /**< Flash device containing the component. */
const struct flash *flash; /**< Flash device containing the component. */
uint32_t start_addr; /**< Base address on flash of the component. */
size_t offset; /**< Offset to the start of the component image. */
struct image_header header; /**< Header for the component. */
};
int firmware_component_init (struct firmware_component *image, struct flash *flash,
int firmware_component_init (struct firmware_component *image, const struct flash *flash,
uint32_t start_addr, uint32_t marker);
int firmware_component_init_with_header (struct firmware_component *image, struct flash *flash,
uint32_t start_addr, uint32_t marker, size_t header_length);
int firmware_component_init_with_header (struct firmware_component *image,
const struct flash *flash, uint32_t start_addr, uint32_t marker, size_t header_length);
void firmware_component_release (struct firmware_component *image);
int firmware_component_verification (struct firmware_component *image, struct hash_engine *hash,
struct signature_verification *verification, uint8_t *hash_out, size_t hash_length);
int firmware_component_verification (const struct firmware_component *image,
struct hash_engine *hash, struct signature_verification *verification, uint8_t *hash_out,
size_t hash_length);
int firmware_component_load (struct firmware_component *image, uint8_t *load_addr,
int firmware_component_load (const struct firmware_component *image, uint8_t *load_addr,
size_t max_length, size_t *load_length);
int firmware_component_load_and_verify (struct firmware_component *image, uint8_t *load_addr,
int firmware_component_load_and_verify (const struct firmware_component *image, uint8_t *load_addr,
size_t max_length, struct hash_engine *hash, struct signature_verification *verification,
uint8_t *hash_out, size_t hash_length, size_t *load_length);
int firmware_component_copy (struct firmware_component *image, struct flash *flash,
uint32_t dest_addr, size_t max_length, size_t *copy_length);
int firmware_component_compare_and_copy (struct firmware_component *image, struct flash *flash,
int firmware_component_copy (const struct firmware_component *image, const struct flash *flash,
uint32_t dest_addr, size_t max_length, size_t *copy_length);
int firmware_component_compare_and_copy (const struct firmware_component *image,
const struct flash *flash, uint32_t dest_addr, size_t max_length, size_t *copy_length);
size_t firmware_component_get_signature_length (struct firmware_component *image);
int firmware_component_get_signature (struct firmware_component *image, uint8_t *sig_out,
size_t firmware_component_get_signature_length (const struct firmware_component *image);
int firmware_component_get_signature (const struct firmware_component *image, uint8_t *sig_out,
size_t sig_length);
int firmware_component_get_hash (struct firmware_component *image, struct hash_engine *hash,
int firmware_component_get_hash (const struct firmware_component *image, struct hash_engine *hash,
uint8_t *hash_out, size_t hash_length);
uint32_t firmware_component_get_data_addr (struct firmware_component *image);
size_t firmware_component_get_length (struct firmware_component *image);
uint32_t firmware_component_get_image_end (struct firmware_component *image);
uint32_t firmware_component_get_data_addr (const struct firmware_component *image);
size_t firmware_component_get_length (const struct firmware_component *image);
uint32_t firmware_component_get_image_end (const struct firmware_component *image);
#define FIRMWARE_COMPONENT_ERROR(code) ROT_ERROR (ROT_MODULE_FIRMWARE_COMPONENT, code)

Просмотреть файл

@ -51,7 +51,7 @@ union firmware_header_format {
*
* @return 0 if the header was successfully loaded from flash or an error code.
*/
int firmware_header_init (struct firmware_header *header, struct flash *flash, uint32_t addr)
int firmware_header_init (struct firmware_header *header, const struct flash *flash, uint32_t addr)
{
size_t length;
int status;
@ -118,7 +118,7 @@ void firmware_header_release (struct firmware_header *header)
*
* @return 0 if the revision was available in the header or an error code.
*/
int firmware_header_get_recovery_revision (struct firmware_header *header, int *revision)
int firmware_header_get_recovery_revision (const struct firmware_header *header, int *revision)
{
if ((header == NULL) || (revision == NULL)) {
return FIRMWARE_HEADER_INVALID_ARGUMENT;
@ -137,7 +137,7 @@ int firmware_header_get_recovery_revision (struct firmware_header *header, int *
*
* @return The number of extra images or an error code.
*/
int firmware_header_get_extra_images (struct firmware_header *header)
int firmware_header_get_extra_images (const struct firmware_header *header)
{
if (header == NULL) {
return FIRMWARE_HEADER_INVALID_ARGUMENT;
@ -158,7 +158,8 @@ int firmware_header_get_extra_images (struct firmware_header *header)
*
* @return 0 if the revision was available in the header or an error code.
*/
int firmware_header_get_earliest_allowed_revision (struct firmware_header *header, int *revision)
int firmware_header_get_earliest_allowed_revision (const struct firmware_header *header,
int *revision)
{
if ((header == NULL) || (revision == NULL)) {
return FIRMWARE_HEADER_INVALID_ARGUMENT;
@ -187,7 +188,7 @@ int firmware_header_get_earliest_allowed_revision (struct firmware_header *heade
*
* @return 0 if the signature information was available in the header or an error code.
*/
int firmware_header_get_signature_info (struct firmware_header *header, size_t *signed_length,
int firmware_header_get_signature_info (const struct firmware_header *header, size_t *signed_length,
size_t *sig_length)
{
if ((header == NULL) || (signed_length == NULL) || (sig_length == NULL)) {

Просмотреть файл

@ -22,13 +22,14 @@ struct firmware_header {
};
int firmware_header_init (struct firmware_header *header, struct flash *flash, uint32_t addr);
int firmware_header_init (struct firmware_header *header, const struct flash *flash, uint32_t addr);
void firmware_header_release (struct firmware_header *header);
int firmware_header_get_recovery_revision (struct firmware_header *header, int *revision);
int firmware_header_get_extra_images (struct firmware_header *header);
int firmware_header_get_earliest_allowed_revision (struct firmware_header *header, int *revision);
int firmware_header_get_signature_info (struct firmware_header *header, size_t *signed_length,
int firmware_header_get_recovery_revision (const struct firmware_header *header, int *revision);
int firmware_header_get_extra_images (const struct firmware_header *header);
int firmware_header_get_earliest_allowed_revision (const struct firmware_header *header,
int *revision);
int firmware_header_get_signature_info (const struct firmware_header *header, size_t *signed_length,
size_t *sig_length);

Просмотреть файл

@ -29,7 +29,7 @@ struct firmware_image {
*
* @return 0 if the image reference was updated successfully or an error code.
*/
int (*load) (struct firmware_image *fw, struct flash *flash, uint32_t base_addr);
int (*load) (const struct firmware_image *fw, const struct flash *flash, uint32_t base_addr);
/**
* Verify the complete firmware image. All components in the image will be fully validated.
@ -46,7 +46,7 @@ struct firmware_image {
* incorrect signature, FIRMWARE_IMAGE_BAD_SIGNATURE will be returned, regardless of the
* underlying signature verification algorithm.
*/
int (*verify) (struct firmware_image *fw, struct hash_engine *hash);
int (*verify) (const struct firmware_image *fw, struct hash_engine *hash);
/**
* Get the total size of the firmware image.
@ -56,7 +56,7 @@ struct firmware_image {
* @return The size of the firmware image or an error code. Use ROT_IS_ERROR to check the
* return value.
*/
int (*get_image_size) (struct firmware_image *fw);
int (*get_image_size) (const struct firmware_image *fw);
/**
* Get the key manifest for the current firmware image.
@ -67,7 +67,7 @@ struct firmware_image {
* manifest is managed by the firmware image instance and is only guaranteed to be valid until
* the next call to firmware_image.load.
*/
struct key_manifest* (*get_key_manifest) (struct firmware_image *fw);
const struct key_manifest* (*get_key_manifest) (const struct firmware_image *fw);
/**
* Get the main image header for the current firmware image.
@ -78,7 +78,7 @@ struct firmware_image {
* is managed by the firmware image instance and is only guaranteed to be valid until the next
* call to firmware_image.load.
*/
struct firmware_header* (*get_firmware_header) (struct firmware_image *fw);
const struct firmware_header* (*get_firmware_header) (const struct firmware_image *fw);
};

Просмотреть файл

@ -14,6 +14,7 @@
* Initialize the platform firmware updater.
*
* @param updater The updater to initialize.
* @param state Variable context for the updater. This must be uninitialized.
* @param flash The device and address mapping for firmware images.
* @param context The application context API.
* @param fw The platform handler for firmware images.
@ -22,45 +23,102 @@
*
* @return 0 if the updater was successfully initialized or an error code.
*/
int firmware_update_init (struct firmware_update *updater, const struct firmware_flash_map *flash,
struct app_context *context, struct firmware_image *fw, struct hash_engine *hash,
int allowed_revision)
int firmware_update_init (struct firmware_update *updater, struct firmware_update_state *state,
const struct firmware_flash_map *flash, const struct app_context *context,
const struct firmware_image *fw, struct hash_engine *hash, int allowed_revision)
{
int status;
if ((updater == NULL) || (flash == NULL) || (context == NULL) || (fw == NULL) ||
(hash == NULL)) {
if (updater == NULL) {
return FIRMWARE_UPDATE_INVALID_ARGUMENT;
}
if ((flash->active_flash == NULL) || (flash->staging_flash == NULL)) {
return FIRMWARE_UPDATE_INVALID_FLASH_MAP;
}
if ((flash->backup_flash == NULL) && (flash->recovery_flash == NULL)) {
return FIRMWARE_UPDATE_INVALID_FLASH_MAP;
}
memset (updater, 0, sizeof (struct firmware_update));
status = flash_updater_init (&updater->update_mgr, flash->staging_flash, flash->staging_addr,
flash->staging_size);
if (status != 0) {
return status;
}
status = observable_init (&updater->observable);
if (status != 0) {
flash_updater_release (&updater->update_mgr);
return status;
}
updater->state = state;
updater->flash = flash;
updater->fw = fw;
updater->context = context;
updater->hash = hash;
updater->recovery_rev = -1;
updater->min_rev = allowed_revision;
return firmware_update_init_state (updater, allowed_revision);
}
/**
* Initialize the platform firmware updater.
*
* Firmware images processed by the updater are not required to contain a firmware header. If the
* firmware header is present, it will be processed. If the firmware header is not present, the
* update will proceed without it and any workflows that require information from the header will
* be skipped.
*
* @param updater The updater to initialize.
* @param state Variable context for the updater. This must be uninitialized.
* @param flash The device and address mapping for firmware images.
* @param context The application context API.
* @param fw The platform handler for firmware images.
* @param hash The hash engine to use during updates.
* @param allowed_revision The lowest image ID that will be allowed for firmware updates.
*
* @return 0 if the updater was successfully initialized or an error code.
*/
int firmware_update_init_no_firmware_header (struct firmware_update *updater,
struct firmware_update_state *state, const struct firmware_flash_map *flash,
const struct app_context *context, const struct firmware_image *fw, struct hash_engine *hash,
int allowed_revision)
{
int status;
status = firmware_update_init (updater, state, flash, context, fw, hash, allowed_revision);
if (status == 0) {
updater->no_fw_header = true;
}
return status;
}
/**
* Initialize only the variable state for a firmware update handler. The rest of the firmware
* update instance is assumed to have already been initialized.
*
* This would generally be used with a statically initialized instance.
*
* @param updater The updater instance that contains the state to initialize.
* @param allowed_revision The lowest image ID that will be allowed for firmware updates.
*
* @return 0 if the state was successfully initialized or an error code.
*/
int firmware_update_init_state (const struct firmware_update *updater, int allowed_revision)
{
int status;
if ((updater == NULL) || (updater->state == NULL) || (updater->flash == NULL) ||
(updater->context == NULL) || (updater->fw == NULL) || (updater->hash == NULL)) {
return FIRMWARE_UPDATE_INVALID_ARGUMENT;
}
if ((updater->flash->active_flash == NULL) || (updater->flash->staging_flash == NULL)) {
return FIRMWARE_UPDATE_INVALID_FLASH_MAP;
}
if ((updater->flash->backup_flash == NULL) && (updater->flash->recovery_flash == NULL)) {
return FIRMWARE_UPDATE_INVALID_FLASH_MAP;
}
memset (updater->state, 0, sizeof (struct firmware_update_state));
status = flash_updater_init (&updater->state->update_mgr, updater->flash->staging_flash,
updater->flash->staging_addr, updater->flash->staging_size);
if (status != 0) {
return status;
}
status = observable_init (&updater->state->observable);
if (status != 0) {
flash_updater_release (&updater->state->update_mgr);
return status;
}
updater->state->recovery_rev = -1;
updater->state->min_rev = allowed_revision;
return 0;
}
@ -70,11 +128,11 @@ int firmware_update_init (struct firmware_update *updater, const struct firmware
*
* @param updater The updater to release.
*/
void firmware_update_release (struct firmware_update *updater)
void firmware_update_release (const struct firmware_update *updater)
{
if (updater) {
observable_release (&updater->observable);
flash_updater_release (&updater->update_mgr);
observable_release (&updater->state->observable);
flash_updater_release (&updater->state->update_mgr);
}
}
@ -86,31 +144,11 @@ void firmware_update_release (struct firmware_update *updater)
* @param updater The firmware updater to configure.
* @param offset The offset to apply to images.
*/
void firmware_update_set_image_offset (struct firmware_update *updater, int offset)
void firmware_update_set_image_offset (const struct firmware_update *updater, int offset)
{
if (updater != NULL) {
updater->img_offset = offset;
flash_updater_apply_update_offset (&updater->update_mgr, offset);
}
}
/**
* Indicate to the updater if the firmware image is required to contain a firmware header or not.
* When a firmware header is required, images that fail to provide one will result in failure to
* apply that image.
*
* It is expected that this would be configured during initialization based on the firmware image
* expectations for a particular system.
*
* By default, the updater requires a firmware header on the image.
*
* @param updater The firmware updater to configure.
* @param has_fw_header Flag indicating if a firmware header is required for the update to succeed.
*/
void firmware_update_require_firmware_header (struct firmware_update *updater, bool has_fw_header)
{
if (updater != NULL) {
updater->no_fw_header = !has_fw_header;
updater->state->img_offset = offset;
flash_updater_apply_update_offset (&updater->state->update_mgr, offset);
}
}
@ -124,10 +162,10 @@ void firmware_update_require_firmware_header (struct firmware_update *updater, b
* @param updater The firmware updater to configure.
* @param img_good Flag indicating if the current recovery image is good.
*/
void firmware_update_set_recovery_good (struct firmware_update *updater, bool img_good)
void firmware_update_set_recovery_good (const struct firmware_update *updater, bool img_good)
{
if (updater != NULL) {
updater->recovery_bad = !img_good;
updater->state->recovery_bad = !img_good;
}
}
@ -138,10 +176,10 @@ void firmware_update_set_recovery_good (struct firmware_update *updater, bool im
* @param updater The firmware updater to configure.
* @param revision The revision ID of the recovery image.
*/
void firmware_update_set_recovery_revision (struct firmware_update *updater, int revision)
void firmware_update_set_recovery_revision (const struct firmware_update *updater, int revision)
{
if (updater != NULL) {
updater->recovery_rev = revision;
updater->state->recovery_rev = revision;
}
}
@ -155,7 +193,7 @@ void firmware_update_set_recovery_revision (struct firmware_update *updater, int
*
* @param updater The updater to configure.
*/
void firmware_update_validate_recovery_image (struct firmware_update *updater)
void firmware_update_validate_recovery_image (const struct firmware_update *updater)
{
int status;
@ -165,7 +203,7 @@ void firmware_update_validate_recovery_image (struct firmware_update *updater)
if (updater->flash->recovery_flash) {
status = updater->fw->load (updater->fw, updater->flash->recovery_flash,
updater->flash->recovery_addr + updater->img_offset);
updater->flash->recovery_addr + updater->state->img_offset);
if (status == 0) {
status = updater->fw->verify (updater->fw, updater->hash);
@ -176,11 +214,12 @@ void firmware_update_validate_recovery_image (struct firmware_update *updater)
}
if (status == 0) {
struct firmware_header *header;
const struct firmware_header *header;
header = updater->fw->get_firmware_header (updater->fw);
if (header != NULL) {
status = firmware_header_get_recovery_revision (header, &updater->recovery_rev);
status = firmware_header_get_recovery_revision (header,
&updater->state->recovery_rev);
}
else if (!updater->no_fw_header) {
status = FIRMWARE_UPDATE_NO_FIRMWARE_HEADER;
@ -188,11 +227,11 @@ void firmware_update_validate_recovery_image (struct firmware_update *updater)
}
}
updater->recovery_bad = (status != 0);
updater->state->recovery_bad = (status != 0);
debug_log_create_entry (
(updater->recovery_bad) ? DEBUG_LOG_SEVERITY_WARNING : DEBUG_LOG_SEVERITY_INFO,
DEBUG_LOG_COMPONENT_CERBERUS_FW, FIRMWARE_LOGGING_RECOVERY_IMAGE, updater->recovery_bad,
status);
(updater->state->recovery_bad) ? DEBUG_LOG_SEVERITY_WARNING : DEBUG_LOG_SEVERITY_INFO,
DEBUG_LOG_COMPONENT_CERBERUS_FW, FIRMWARE_LOGGING_RECOVERY_IMAGE,
updater->state->recovery_bad, status);
}
}
@ -209,8 +248,9 @@ void firmware_update_validate_recovery_image (struct firmware_update *updater)
*
* @return 0 if the new image was copied successfully to the active region or an error code.
*/
static int firmware_update_program_bootable (struct firmware_update *updater, struct flash *dest,
uint32_t dest_addr, struct flash *src, uint32_t src_addr, size_t length, uint32_t page)
static int firmware_update_program_bootable (const struct firmware_update *updater,
const struct flash *dest, uint32_t dest_addr, const struct flash *src, uint32_t src_addr,
size_t length, uint32_t page)
{
int status;
@ -237,8 +277,8 @@ static int firmware_update_program_bootable (struct firmware_update *updater, st
*
* @return 0 if the image was successfully finalized or an error code.
*/
static int firmware_update_finalize_image (struct firmware_update *updater, struct flash *flash,
uint32_t address)
static int firmware_update_finalize_image (const struct firmware_update *updater,
const struct flash *flash, uint32_t address)
{
if (updater->internal.finalize_image) {
return updater->internal.finalize_image (updater, flash, address);
@ -258,14 +298,14 @@ static int firmware_update_finalize_image (struct firmware_update *updater, stru
*
* @return 0 if image was successfully restored or an error code.
*/
static int firmware_update_restore_image (struct firmware_update *updater, struct flash *dest,
uint32_t dest_addr, struct flash *src, uint32_t src_addr)
static int firmware_update_restore_image (const struct firmware_update *updater,
const struct flash *dest, uint32_t dest_addr, const struct flash *src, uint32_t src_addr)
{
int img_len;
uint32_t page;
int status;
status = updater->fw->load (updater->fw, src, src_addr + updater->img_offset);
status = updater->fw->load (updater->fw, src, src_addr + updater->state->img_offset);
if (status != 0) {
return status;
}
@ -285,13 +325,14 @@ static int firmware_update_restore_image (struct firmware_update *updater, struc
return status;
}
status = flash_erase_region_and_verify (dest, dest_addr, img_len + updater->img_offset);
status = flash_erase_region_and_verify (dest, dest_addr, img_len + updater->state->img_offset);
if (status != 0) {
return status;
}
status = firmware_update_program_bootable (updater, dest, dest_addr + updater->img_offset, src,
src_addr + updater->img_offset, img_len, page);
status = firmware_update_program_bootable (updater, dest,
dest_addr + updater->state->img_offset, src, src_addr + updater->state->img_offset, img_len,
page);
if (status != 0) {
return status;
}
@ -308,17 +349,17 @@ static int firmware_update_restore_image (struct firmware_update *updater, struc
* @return 0 if the recovery image was restored successfully or an error code. If the recovery
* image is already good, FIRMWARE_UPDATE_RESTORE_NOT_NEEDED will be returned.
*/
int firmware_update_restore_recovery_image (struct firmware_update *updater)
int firmware_update_restore_recovery_image (const struct firmware_update *updater)
{
int status = FIRMWARE_UPDATE_NO_RECOVERY_IMAGE;
struct firmware_header *header = NULL;
const struct firmware_header *header = NULL;
if (updater == NULL) {
return FIRMWARE_UPDATE_INVALID_ARGUMENT;
}
if (updater->flash->recovery_flash) {
if (updater->recovery_bad) {
if (updater->state->recovery_bad) {
debug_log_create_entry (DEBUG_LOG_SEVERITY_INFO, DEBUG_LOG_COMPONENT_CERBERUS_FW,
FIRMWARE_LOGGING_RECOVERY_RESTORE_START, 0, 0);
@ -326,14 +367,14 @@ int firmware_update_restore_recovery_image (struct firmware_update *updater)
updater->flash->recovery_addr, updater->flash->active_flash,
updater->flash->active_addr);
if (status == 0) {
updater->recovery_bad = false;
updater->state->recovery_bad = false;
header = updater->fw->get_firmware_header (updater->fw);
if (header == NULL) {
firmware_update_set_recovery_revision (updater, -1);
}
else {
firmware_header_get_recovery_revision (header, &updater->recovery_rev);
firmware_header_get_recovery_revision (header, &updater->state->recovery_rev);
}
}
}
@ -353,7 +394,7 @@ int firmware_update_restore_recovery_image (struct firmware_update *updater)
*
* @return 0 if the active image was restored successfully or an error code.
*/
int firmware_update_restore_active_image (struct firmware_update *updater)
int firmware_update_restore_active_image (const struct firmware_update *updater)
{
int status = FIRMWARE_UPDATE_NO_RECOVERY_IMAGE;
@ -377,13 +418,13 @@ int firmware_update_restore_active_image (struct firmware_update *updater)
*
* @return 1 if the recovery image is good, 0 if the recovery image is bad, or an error code.
*/
int firmware_update_is_recovery_good (struct firmware_update *updater)
int firmware_update_is_recovery_good (const struct firmware_update *updater)
{
if (updater == NULL) {
return FIRMWARE_UPDATE_INVALID_ARGUMENT;
}
return updater->recovery_bad ? 0 : 1;
return updater->state->recovery_bad ? 0 : 1;
}
/**
@ -394,14 +435,14 @@ int firmware_update_is_recovery_good (struct firmware_update *updater)
*
* @return 0 if the observer was successfully added or an error code.
*/
int firmware_update_add_observer (struct firmware_update *updater,
int firmware_update_add_observer (const struct firmware_update *updater,
struct firmware_update_observer *observer)
{
if (updater == NULL) {
return FIRMWARE_UPDATE_INVALID_ARGUMENT;
}
return observable_add_observer (&updater->observable, observer);
return observable_add_observer (&updater->state->observable, observer);
}
/**
@ -412,14 +453,14 @@ int firmware_update_add_observer (struct firmware_update *updater,
*
* @return 0 if the observer was successfully removed or an error code.
*/
int firmware_update_remove_observer (struct firmware_update *updater,
int firmware_update_remove_observer (const struct firmware_update *updater,
struct firmware_update_observer *observer)
{
if (updater == NULL) {
return FIRMWARE_UPDATE_INVALID_ARGUMENT;
}
return observable_remove_observer (&updater->observable, observer);
return observable_remove_observer (&updater->state->observable, observer);
}
/**
@ -428,7 +469,7 @@ int firmware_update_remove_observer (struct firmware_update *updater,
* @param callback The notification callback to trigger.
* @param status The status to notify.
*/
static void firmware_update_status_change (struct firmware_update_notification *callback,
static void firmware_update_status_change (const struct firmware_update_notification *callback,
enum firmware_update_status status)
{
if ((callback != NULL) && (callback->status_change != NULL)) {
@ -459,9 +500,9 @@ static void firmware_update_status_change (struct firmware_update_notification *
*
* @return 0 if the new firmware image was successfully written or an error code.
*/
static int firmware_update_write_image (struct firmware_update *updater,
struct firmware_update_notification *callback, struct flash *dest, uint32_t dest_addr,
struct flash *backup, uint32_t backup_addr, size_t update_len,
static int firmware_update_write_image (const struct firmware_update *updater,
const struct firmware_update_notification *callback, const struct flash *dest,
uint32_t dest_addr, const struct flash *backup, uint32_t backup_addr, size_t update_len,
enum firmware_update_status backup_start, enum firmware_update_status backup_fail,
enum firmware_update_status update_start, enum firmware_update_status update_fail,
bool *img_good)
@ -474,7 +515,7 @@ static int firmware_update_write_image (struct firmware_update *updater,
if (backup) {
/* Backup the current image. */
firmware_update_status_change (callback, backup_start);
status = updater->fw->load (updater->fw, dest, dest_addr + updater->img_offset);
status = updater->fw->load (updater->fw, dest, dest_addr + updater->state->img_offset);
if (status != 0) {
firmware_update_status_change (callback, backup_fail);
return status;
@ -486,8 +527,8 @@ static int firmware_update_write_image (struct firmware_update *updater,
return backup_len;
}
status = flash_copy_ext_and_verify (backup, backup_addr + updater->img_offset, dest,
dest_addr + updater->img_offset, backup_len);
status = flash_copy_ext_and_verify (backup, backup_addr + updater->state->img_offset, dest,
dest_addr + updater->state->img_offset, backup_len);
if (status != 0) {
firmware_update_status_change (callback, backup_fail);
return status;
@ -504,15 +545,16 @@ static int firmware_update_write_image (struct firmware_update *updater,
}
*img_good = false;
status = flash_erase_region_and_verify (dest, dest_addr, update_len + updater->img_offset);
status = flash_erase_region_and_verify (dest, dest_addr,
update_len + updater->state->img_offset);
if (status != 0) {
firmware_update_status_change (callback, update_fail);
return status;
}
status = firmware_update_program_bootable (updater, dest, dest_addr + updater->img_offset,
updater->flash->staging_flash, updater->flash->staging_addr + updater->img_offset,
update_len, page);
status = firmware_update_program_bootable (updater, dest,
dest_addr + updater->state->img_offset, updater->flash->staging_flash,
updater->flash->staging_addr + updater->state->img_offset, update_len, page);
if (status == 0) {
status = firmware_update_finalize_image (updater, dest, dest_addr);
}
@ -521,10 +563,10 @@ static int firmware_update_write_image (struct firmware_update *updater,
if (backup) {
/* Try to restore the image that was backed up. */
if (flash_erase_region_and_verify (dest, dest_addr,
backup_len + updater->img_offset) == 0) {
backup_len + updater->state->img_offset) == 0) {
if (firmware_update_program_bootable (updater, dest,
dest_addr + updater->img_offset, backup, backup_addr + updater->img_offset,
backup_len, page) == 0) {
dest_addr + updater->state->img_offset, backup,
backup_addr + updater->state->img_offset, backup_len, page) == 0) {
if (firmware_update_finalize_image (updater, dest, dest_addr) == 0) {
*img_good = true;
}
@ -546,7 +588,7 @@ static int firmware_update_write_image (struct firmware_update *updater,
* - Save the application state that should be restored after the update.
* - Copy the image in staging flash to active flash.
* - Copy the image in staging flash to recovery flash, if the recovery manifest has been
* revoked.
* revoked or the recovery revision has changed.
* - Update manifest revocation information in the device.
*
* @param updater The updater that should run.
@ -556,12 +598,12 @@ static int firmware_update_write_image (struct firmware_update *updater,
*
* @return 0 if the update completed successfully or an error code.
*/
int firmware_update_run_update (struct firmware_update *updater,
struct firmware_update_notification *callback)
int firmware_update_run_update (const struct firmware_update *updater,
const struct firmware_update_notification *callback)
{
int new_len;
struct key_manifest *manifest;
struct firmware_header *header = NULL;
const struct key_manifest *manifest;
const struct firmware_header *header = NULL;
bool recovery_updated = false;
bool img_good;
int manifest_revoked;
@ -577,13 +619,13 @@ int firmware_update_run_update (struct firmware_update *updater,
/* Verify image in staging flash. */
firmware_update_status_change (callback, UPDATE_STATUS_VERIFYING_IMAGE);
if (flash_updater_get_remaining_bytes (&updater->update_mgr) > 0) {
if (flash_updater_get_remaining_bytes (&updater->state->update_mgr) > 0) {
firmware_update_status_change (callback, UPDATE_STATUS_INCOMPLETE_IMAGE);
return FIRMWARE_UPDATE_INCOMPLETE_IMAGE;
}
status = updater->fw->load (updater->fw, updater->flash->staging_flash,
updater->flash->staging_addr + updater->img_offset);
updater->flash->staging_addr + updater->state->img_offset);
if (status != 0) {
firmware_update_status_change (callback, UPDATE_STATUS_VERIFY_FAILURE);
return status;
@ -609,7 +651,7 @@ int firmware_update_run_update (struct firmware_update *updater,
return status;
}
if (new_revision < updater->min_rev) {
if (new_revision < updater->state->min_rev) {
firmware_update_status_change (callback, UPDATE_STATUS_INVALID_IMAGE);
return FIRMWARE_UPDATE_REJECTED_ROLLBACK;
}
@ -622,7 +664,7 @@ int firmware_update_run_update (struct firmware_update *updater,
/* There is no FW header on the image, so just apply the updater's recovery revision to the
* new image. Without a FW header, the recovery image will only get updated during
* manifest revocation flows. */
new_revision = updater->recovery_rev;
new_revision = updater->state->recovery_rev;
}
new_len = updater->fw->get_image_size (updater->fw);
@ -633,7 +675,7 @@ int firmware_update_run_update (struct firmware_update *updater,
/* Notify the system of an update and see if it should be allowed. */
allow_update = 0;
observable_notify_observers_with_ptr (&updater->observable,
observable_notify_observers_with_ptr (&updater->state->observable,
offsetof (struct firmware_update_observer, on_update_start), &allow_update);
if (allow_update != 0) {
firmware_update_status_change (callback, UPDATE_STATUS_SYSTEM_PREREQ_FAIL);
@ -649,7 +691,7 @@ int firmware_update_run_update (struct firmware_update *updater,
}
/* Don't allow the active image to be erased until we have a good recovery image. */
if (updater->flash->recovery_flash && updater->recovery_bad) {
if (updater->flash->recovery_flash && updater->state->recovery_bad) {
debug_log_create_entry (DEBUG_LOG_SEVERITY_INFO, DEBUG_LOG_COMPONENT_CERBERUS_FW,
FIRMWARE_LOGGING_RECOVERY_UPDATE, 0, 0);
debug_log_flush ();
@ -662,7 +704,7 @@ int firmware_update_run_update (struct firmware_update *updater,
return status;
}
updater->recovery_bad = !img_good;
updater->state->recovery_bad = !img_good;
recovery_updated = true;
}
@ -678,7 +720,7 @@ int firmware_update_run_update (struct firmware_update *updater,
/* Check for manifest revocation. */
firmware_update_status_change (callback, UPDATE_STATUS_CHECK_REVOCATION);
status = updater->fw->load (updater->fw, updater->flash->active_flash,
updater->flash->active_addr + updater->img_offset);
updater->flash->active_addr + updater->state->img_offset);
if (status != 0) {
firmware_update_status_change (callback, UPDATE_STATUS_REVOKE_CHK_FAIL);
return status;
@ -698,9 +740,9 @@ int firmware_update_run_update (struct firmware_update *updater,
/* Check if recovery update is necessary. */
firmware_update_status_change (callback, UPDATE_STATUS_CHECK_RECOVERY);
if (manifest_revoked || (updater->recovery_rev != new_revision)) {
if (manifest_revoked || (updater->state->recovery_rev != new_revision)) {
if (updater->flash->recovery_flash && !recovery_updated) {
struct flash *backup;
const struct flash *backup;
uint32_t backup_addr;
if (updater->flash->rec_backup_flash) {
@ -722,13 +764,13 @@ int firmware_update_run_update (struct firmware_update *updater,
UPDATE_STATUS_BACKUP_RECOVERY, UPDATE_STATUS_BACKUP_REC_FAIL,
UPDATE_STATUS_UPDATE_RECOVERY, UPDATE_STATUS_UPDATE_REC_FAIL, &img_good);
updater->recovery_bad = !img_good;
updater->state->recovery_bad = !img_good;
if (status != 0) {
return status;
}
}
updater->recovery_rev = new_revision;
updater->state->recovery_rev = new_revision;
if (manifest_revoked) {
/* Revoke the old manifest. */
@ -756,8 +798,8 @@ int firmware_update_run_update (struct firmware_update *updater,
*
* @return Preparation status, 0 if success or an error code.
*/
int firmware_update_prepare_staging (struct firmware_update *updater,
struct firmware_update_notification *callback, size_t size)
int firmware_update_prepare_staging (const struct firmware_update *updater,
const struct firmware_update_notification *callback, size_t size)
{
int status;
@ -768,7 +810,7 @@ int firmware_update_prepare_staging (struct firmware_update *updater,
firmware_update_status_change (callback, UPDATE_STATUS_STAGING_PREP);
status = flash_updater_prepare_for_update (&updater->update_mgr, size);
status = flash_updater_prepare_for_update (&updater->state->update_mgr, size);
if (status != 0) {
firmware_update_status_change (callback, UPDATE_STATUS_STAGING_PREP_FAIL);
}
@ -788,8 +830,8 @@ int firmware_update_prepare_staging (struct firmware_update *updater,
*
* @return Programming status, 0 if success or an error code.
*/
int firmware_update_write_to_staging (struct firmware_update *updater,
struct firmware_update_notification *callback, uint8_t *buf, size_t buf_len)
int firmware_update_write_to_staging (const struct firmware_update *updater,
const struct firmware_update_notification *callback, uint8_t *buf, size_t buf_len)
{
int status;
@ -800,7 +842,7 @@ int firmware_update_write_to_staging (struct firmware_update *updater,
firmware_update_status_change (callback, UPDATE_STATUS_STAGING_WRITE);
status = flash_updater_write_update_data (&updater->update_mgr, buf, buf_len);
status = flash_updater_write_update_data (&updater->state->update_mgr, buf, buf_len);
if (status != 0) {
firmware_update_status_change (callback, UPDATE_STATUS_STAGING_WRITE_FAIL);
}
@ -816,7 +858,7 @@ int firmware_update_write_to_staging (struct firmware_update *updater,
* @return The number of bytes remaining in the current update. This can be negative if more bytes
* have been received than expected.
*/
int firmware_update_get_update_remaining (struct firmware_update *updater)
int firmware_update_get_update_remaining (const struct firmware_update *updater)
{
return flash_updater_get_remaining_bytes (&updater->update_mgr);
return flash_updater_get_remaining_bytes (&updater->state->update_mgr);
}

Просмотреть файл

@ -21,21 +21,21 @@
* The flash addresses and devices to use for different firmware regions.
*/
struct firmware_flash_map {
struct flash *active_flash; /**< The flash device that contains the active region. */
uint32_t active_addr; /**< The base address for the active flash region. */
size_t active_size; /**< The size of the active flash region. */
struct flash *backup_flash; /**< The flash device that contains the backup region. */
uint32_t backup_addr; /**< The base address for the backup flash region. */
size_t backup_size; /**< The size of the backup flash region. */
struct flash *staging_flash; /**< The flash device that contains the staging region. */
uint32_t staging_addr; /**< The base address for the staging flash region. */
size_t staging_size; /**< The size of the staging flash region. */
struct flash *recovery_flash; /**< The flash device that contains the recovery region. */
uint32_t recovery_addr; /**< The base address for the recovery flash region. */
size_t recovery_size; /**< The size of the recovery flash region. */
struct flash *rec_backup_flash; /**< The flash device for the recovery backup region. */
uint32_t rec_backup_addr; /**< The base address for the recovery backup region. */
size_t rec_backup_size; /**< The size of the recovery backup flash region. */
const struct flash *active_flash; /**< The flash device that contains the active region. */
uint32_t active_addr; /**< The base address for the active flash region. */
size_t active_size; /**< The size of the active flash region. */
const struct flash *backup_flash; /**< The flash device that contains the backup region. */
uint32_t backup_addr; /**< The base address for the backup flash region. */
size_t backup_size; /**< The size of the backup flash region. */
const struct flash *staging_flash; /**< The flash device that contains the staging region. */
uint32_t staging_addr; /**< The base address for the staging flash region. */
size_t staging_size; /**< The size of the staging flash region. */
const struct flash *recovery_flash; /**< The flash device that contains the recovery region. */
uint32_t recovery_addr; /**< The base address for the recovery flash region. */
size_t recovery_size; /**< The size of the recovery flash region. */
const struct flash *rec_backup_flash; /**< The flash device for the recovery backup region. */
uint32_t rec_backup_addr; /**< The base address for the recovery backup region. */
size_t rec_backup_size; /**< The size of the recovery backup flash region. */
};
/**
@ -95,7 +95,8 @@ struct firmware_update_hooks {
*
* @return 0 if the image was successfully finalized or an error code.
*/
int (*finalize_image) (struct firmware_update *updater, struct flash *flash, uint32_t address);
int (*finalize_image) (const struct firmware_update *updater, const struct flash *flash,
uint32_t address);
/**
* Run additional verification on a boot image stored on flash. This will be called after
@ -110,26 +111,33 @@ struct firmware_update_hooks {
* @return 0 if the image is valid or an error code. If the boot image is not valid,
* FIRMWARE_UPDATE_INVALID_BOOT_IMAGE will be returned.
*/
int (*verify_boot_image) (struct firmware_update *updater, struct flash *flash,
int (*verify_boot_image) (const struct firmware_update *updater, const struct flash *flash,
uint32_t address);
};
/**
* Variable context for a firmware update handler.
*/
struct firmware_update_state {
struct flash_updater update_mgr; /**< Update manager for writing data to flash. */
struct observable observable; /**< Observer manager for the updater. */
bool recovery_bad; /**< Indication if the recovery image on flash is bad. */
int recovery_rev; /**< Revision ID of the current recovery image. */
int min_rev; /**< Minimum revision ID allowed for update. */
int img_offset; /**< Offset to apply to FW image regions. */
};
/**
* The meta-data and other dependencies necessary to run firmware update operations.
*/
struct firmware_update {
struct firmware_update_hooks internal; /**< Internal interface to customize the update process. */
struct firmware_update_state *state; /**< Variable context for the update context. */
const struct firmware_flash_map *flash; /**< The flash address mapping to use for the update. */
struct firmware_image *fw; /**< The platform driver for handling firmware images. */
struct hash_engine *hash; /**< The hash engine to use during update .*/
struct app_context *context; /**< The platform application context API. */
struct flash_updater update_mgr; /**< Update manager for writing data to flash. */
const struct firmware_image *fw; /**< The platform driver for handling firmware images. */
struct hash_engine *hash; /**< The hash engine to use during update. */
const struct app_context *context; /**< The platform application context API. */
bool no_fw_header; /**< Indication that a firmware header is not required. */
bool recovery_bad; /**< Indication if the recovery image on flash is bad. */
int recovery_rev; /**< Revision ID of the current recovery image. */
int min_rev; /**< Minimum revision ID allowed for update. */
int img_offset; /**< Offset to apply to FW image regions. */
struct observable observable; /**< Observer manager for the updater. */
};
/**
@ -142,39 +150,43 @@ struct firmware_update_notification {
* @param context The context of the notification handler.
* @param status The new status of the active firmware update.
*/
void (*status_change) (struct firmware_update_notification *context,
void (*status_change) (const struct firmware_update_notification *context,
enum firmware_update_status status);
};
int firmware_update_init (struct firmware_update *updater, const struct firmware_flash_map *flash,
struct app_context *context, struct firmware_image *fw, struct hash_engine *hash,
int firmware_update_init (struct firmware_update *updater, struct firmware_update_state *state,
const struct firmware_flash_map *flash, const struct app_context *context,
const struct firmware_image *fw, struct hash_engine *hash, int allowed_revision);
int firmware_update_init_no_firmware_header (struct firmware_update *updater,
struct firmware_update_state *state, const struct firmware_flash_map *flash,
const struct app_context *context, const struct firmware_image *fw, struct hash_engine *hash,
int allowed_revision);
void firmware_update_release (struct firmware_update *updater);
int firmware_update_init_state (const struct firmware_update *updater, int allowed_revision);
void firmware_update_release (const struct firmware_update *updater);
void firmware_update_set_image_offset (struct firmware_update *updater, int offset);
void firmware_update_require_firmware_header (struct firmware_update *updater, bool has_fw_header);
void firmware_update_set_image_offset (const struct firmware_update *updater, int offset);
void firmware_update_set_recovery_revision (struct firmware_update *updater, int revision);
void firmware_update_set_recovery_good (struct firmware_update *updater, bool img_good);
void firmware_update_validate_recovery_image (struct firmware_update *updater);
int firmware_update_is_recovery_good (struct firmware_update *updater);
void firmware_update_set_recovery_revision (const struct firmware_update *updater, int revision);
void firmware_update_set_recovery_good (const struct firmware_update *updater, bool img_good);
void firmware_update_validate_recovery_image (const struct firmware_update *updater);
int firmware_update_is_recovery_good (const struct firmware_update *updater);
int firmware_update_restore_recovery_image (struct firmware_update *updater);
int firmware_update_restore_active_image (struct firmware_update *updater);
int firmware_update_restore_recovery_image (const struct firmware_update *updater);
int firmware_update_restore_active_image (const struct firmware_update *updater);
int firmware_update_add_observer (struct firmware_update *updater,
int firmware_update_add_observer (const struct firmware_update *updater,
struct firmware_update_observer *observer);
int firmware_update_remove_observer (struct firmware_update *updater,
int firmware_update_remove_observer (const struct firmware_update *updater,
struct firmware_update_observer *observer);
int firmware_update_run_update (struct firmware_update *updater,
struct firmware_update_notification *callback);
int firmware_update_prepare_staging (struct firmware_update *updater,
struct firmware_update_notification *callback, size_t size);
int firmware_update_write_to_staging (struct firmware_update *updater,
struct firmware_update_notification *callback, uint8_t *buf, size_t buf_len);
int firmware_update_get_update_remaining (struct firmware_update *updater);
int firmware_update_run_update (const struct firmware_update *updater,
const struct firmware_update_notification *callback);
int firmware_update_prepare_staging (const struct firmware_update *updater,
const struct firmware_update_notification *callback, size_t size);
int firmware_update_write_to_staging (const struct firmware_update *updater,
const struct firmware_update_notification *callback, uint8_t *buf, size_t buf_len);
int firmware_update_get_update_remaining (const struct firmware_update *updater);
#define FIRMWARE_UPDATE_ERROR(code) ROT_ERROR (ROT_MODULE_FIRMWARE_UPDATE, code)

Просмотреть файл

@ -0,0 +1,70 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef FIRMWARE_UPDATE_STATIC_H_
#define FIRMWARE_UPDATE_STATIC_H_
#include "firmware/firmware_update.h"
/**
* Constant initializer for the internal update customization hooks.
*/
#define FIRMWARE_UPDATE_INTERNAL_API_INIT { \
.finalize_image = NULL, \
.verify_boot_image = NULL \
}
/**
* Initialize a static instance of a firmware update handler. This does not initialize the updater
* state. This can be a constant instance.
*
* There is no validation done on the arguments.
*
* @param state_ptr Variable context for the updater.
* @param flash_ptr The device and address mapping for firmware images.
* @param context_ptr The application context API.
* @param fw_ptr The platform handler for firmware images.
* @param hash_ptr The hash engine to use during updates.
*/
#define firmware_update_static_init(state_ptr, flash_ptr, context_ptr, fw_ptr, hash_ptr) { \
.internal = FIRMWARE_UPDATE_INTERNAL_API_INIT, \
.state = state_ptr, \
.flash = flash_ptr, \
.fw = fw_ptr, \
.hash = hash_ptr, \
.context = context_ptr, \
.no_fw_header = false \
}
/**
* Initialize a static instance of a firmware update handler. This does not initialize the updater
* state. This can be a constant instance.
*
* Firmware images processed by the updater are not required to contain a firmware header. If the
* firmware header is present, it will be processed. If the firmware header is not present, the
* update will proceed without it and any workflows that required information from the header will
* be skipped.
*
* There is no validation done on the arguments.
*
* @param state_ptr Variable context for the updater.
* @param flash_ptr The device and address mapping for firmware images.
* @param context_ptr The application context API.
* @param fw_ptr The platform handler for firmware images.
* @param hash_ptr The hash engine to use during updates.
*/
#define firmware_update_static_init_no_firmware_header(state_ptr, flash_ptr, context_ptr, fw_ptr, \
hash_ptr) { \
.internal = FIRMWARE_UPDATE_INTERNAL_API_INIT, \
.state = state_ptr, \
.flash = flash_ptr, \
.fw = fw_ptr, \
.hash = hash_ptr, \
.context = context_ptr, \
.no_fw_header = true \
}
#endif /* FIRMWARE_UPDATE_STATIC_H_ */

Просмотреть файл

@ -19,7 +19,7 @@
*
* @return 0 if the update manager was initialized successfully or an error code.
*/
static int flash_updater_init_common (struct flash_updater *updater, struct flash *flash,
static int flash_updater_init_common (struct flash_updater *updater, const struct flash *flash,
uint32_t base_addr, size_t max_size, int (*erase) (const struct flash*, uint32_t, size_t))
{
if ((updater == NULL) || (flash == NULL)) {
@ -48,8 +48,8 @@ static int flash_updater_init_common (struct flash_updater *updater, struct flas
*
* @return 0 if the update manager was initialized successfully or an error code.
*/
int flash_updater_init (struct flash_updater *updater, struct flash *flash, uint32_t base_addr,
size_t max_size)
int flash_updater_init (struct flash_updater *updater, const struct flash *flash,
uint32_t base_addr, size_t max_size)
{
return flash_updater_init_common (updater, flash, base_addr, max_size,
flash_erase_region_and_verify);
@ -67,7 +67,7 @@ int flash_updater_init (struct flash_updater *updater, struct flash *flash, uint
*
* @return 0 if the update manager was initialized successfully or an error code.
*/
int flash_updater_init_sector (struct flash_updater *updater, struct flash *flash,
int flash_updater_init_sector (struct flash_updater *updater, const struct flash *flash,
uint32_t base_addr, size_t max_size)
{
return flash_updater_init_common (updater, flash, base_addr, max_size,

Просмотреть файл

@ -15,7 +15,7 @@
* to sequential locations in flash.
*/
struct flash_updater {
struct flash *flash; /**< The flash to manage for updates. */
const struct flash *flash; /**< The flash to manage for updates. */
uint32_t base_addr; /**< The start of the update region. */
size_t max_size; /**< The maximum size of an update. */
int update_size; /**< Expected size of the current update. */
@ -24,9 +24,9 @@ struct flash_updater {
};
int flash_updater_init (struct flash_updater *updater, struct flash *flash, uint32_t base_addr,
size_t max_size);
int flash_updater_init_sector (struct flash_updater *updater, struct flash *flash,
int flash_updater_init (struct flash_updater *updater, const struct flash *flash,
uint32_t base_addr, size_t max_size);
int flash_updater_init_sector (struct flash_updater *updater, const struct flash *flash,
uint32_t base_addr, size_t max_size);
void flash_updater_release (struct flash_updater *updater);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -7,7 +7,7 @@
#include "app_context_mock.h"
static int app_context_mock_save (struct app_context *context)
static int app_context_mock_save (const struct app_context *context)
{
struct app_context_mock *mock = (struct app_context_mock*) context;

Просмотреть файл

@ -7,7 +7,7 @@
#include "firmware_image_mock.h"
static int firmware_image_mock_load (struct firmware_image *fw, struct flash *flash,
static int firmware_image_mock_load (const struct firmware_image *fw, const struct flash *flash,
uint32_t base_addr)
{
struct firmware_image_mock *mock = (struct firmware_image_mock*) fw;
@ -20,7 +20,7 @@ static int firmware_image_mock_load (struct firmware_image *fw, struct flash *fl
MOCK_ARG_CALL (base_addr));
}
static int firmware_image_mock_verify (struct firmware_image *fw, struct hash_engine *hash)
static int firmware_image_mock_verify (const struct firmware_image *fw, struct hash_engine *hash)
{
struct firmware_image_mock *mock = (struct firmware_image_mock*) fw;
@ -31,7 +31,7 @@ static int firmware_image_mock_verify (struct firmware_image *fw, struct hash_en
MOCK_RETURN (&mock->mock, firmware_image_mock_verify, fw, MOCK_ARG_CALL (hash));
}
static int firmware_image_mock_get_image_size (struct firmware_image *fw)
static int firmware_image_mock_get_image_size (const struct firmware_image *fw)
{
struct firmware_image_mock *mock = (struct firmware_image_mock*) fw;
@ -42,7 +42,8 @@ static int firmware_image_mock_get_image_size (struct firmware_image *fw)
MOCK_RETURN_NO_ARGS (&mock->mock, firmware_image_mock_get_image_size, fw);
}
static struct key_manifest* firmware_image_mock_get_key_manifest (struct firmware_image *fw)
static const struct key_manifest* firmware_image_mock_get_key_manifest (
const struct firmware_image *fw)
{
struct firmware_image_mock *mock = (struct firmware_image_mock*) fw;
@ -54,7 +55,8 @@ static struct key_manifest* firmware_image_mock_get_key_manifest (struct firmwar
firmware_image_mock_get_key_manifest, fw);
}
static struct firmware_header* firmware_image_mock_get_firmware_header (struct firmware_image *fw)
static const struct firmware_header* firmware_image_mock_get_firmware_header (
const struct firmware_image *fw)
{
struct firmware_image_mock *mock = (struct firmware_image_mock*) fw;

Просмотреть файл

@ -7,8 +7,8 @@
#include "firmware_update_mock.h"
int firmware_update_mock_finalize_image (struct firmware_update *updater, struct flash *flash,
uint32_t address)
int firmware_update_mock_finalize_image (const struct firmware_update *updater,
const struct flash *flash, uint32_t address)
{
struct firmware_update_mock *mock = (struct firmware_update_mock*) updater;
@ -20,8 +20,8 @@ int firmware_update_mock_finalize_image (struct firmware_update *updater, struct
MOCK_ARG_CALL (address));
}
int firmware_update_mock_verify_boot_image (struct firmware_update *updater, struct flash *flash,
uint32_t address)
int firmware_update_mock_verify_boot_image (const struct firmware_update *updater,
const struct flash *flash, uint32_t address)
{
struct firmware_update_mock *mock = (struct firmware_update_mock*) updater;
@ -94,8 +94,9 @@ static const char* firmware_update_mock_arg_name_map (void *func, int arg)
* @return 0 if the mock was initialized successfully or an error code.
*/
int firmware_update_mock_init (struct firmware_update_mock *mock,
const struct firmware_flash_map *flash, struct app_context *context, struct firmware_image *fw,
struct hash_engine *hash, int allowed_revision)
struct firmware_update_state *state, const struct firmware_flash_map *flash,
struct app_context *context, struct firmware_image *fw, struct hash_engine *hash,
int allowed_revision)
{
int status;
@ -105,7 +106,7 @@ int firmware_update_mock_init (struct firmware_update_mock *mock,
memset (mock, 0, sizeof (struct firmware_update_mock));
status = firmware_update_init (&mock->base, flash, context, fw, hash, allowed_revision);
status = firmware_update_init (&mock->base, state, flash, context, fw, hash, allowed_revision);
if (status != 0) {
return status;
}

Просмотреть файл

@ -18,18 +18,19 @@ struct firmware_update_mock {
int firmware_update_mock_init (struct firmware_update_mock *mock,
const struct firmware_flash_map *flash, struct app_context *context, struct firmware_image *fw,
struct hash_engine *hash, int allowed_revision);
struct firmware_update_state *state, const struct firmware_flash_map *flash,
struct app_context *context, struct firmware_image *fw, struct hash_engine *hash,
int allowed_revision);
void firmware_update_mock_release (struct firmware_update_mock *mock);
int firmware_update_mock_validate_and_release (struct firmware_update_mock *mock);
int firmware_update_mock_finalize_image (struct firmware_update *updater, struct flash *flash,
uint32_t address);
int firmware_update_mock_finalize_image (const struct firmware_update *updater,
const struct flash *flash, uint32_t address);
void firmware_update_mock_enable_finalize_image (struct firmware_update_mock *mock);
int firmware_update_mock_verify_boot_image (struct firmware_update *updater, struct flash *flash,
uint32_t address);
int firmware_update_mock_verify_boot_image (const struct firmware_update *updater,
const struct flash *flash, uint32_t address);
void firmware_update_mock_enable_verify_boot_image (struct firmware_update_mock *mock);

Просмотреть файл

@ -8,7 +8,7 @@
static void firmware_update_notification_mock_state_change (
struct firmware_update_notification *context, enum firmware_update_status state)
const struct firmware_update_notification *context, enum firmware_update_status state)
{
struct firmware_update_notification_mock *mock =
(struct firmware_update_notification_mock*) context;

Просмотреть файл

@ -251,10 +251,10 @@ static int fw_update_task_write_staging (struct firmware_update_control *update,
return status;
}
static void fw_update_task_status_change (struct firmware_update_notification *context,
static void fw_update_task_status_change (const struct firmware_update_notification *context,
enum firmware_update_status status)
{
struct fw_update_task_notify *notify = (struct fw_update_task_notify*) context;
const struct fw_update_task_notify *notify = (const struct fw_update_task_notify*) context;
if (notify != NULL) {
xSemaphoreTake (notify->task->lock, portMAX_DELAY);
@ -272,7 +272,7 @@ static void fw_update_task_status_change (struct firmware_update_notification *c
*
* @return 0 if the task was successfully initialized or an error code.
*/
int fw_update_task_init (struct fw_update_task *task, struct firmware_update *updater,
int fw_update_task_init (struct fw_update_task *task, const struct firmware_update *updater,
struct system *system)
{
if ((task == NULL) || (updater == NULL) || (system == NULL)) {

Просмотреть файл

@ -32,7 +32,7 @@ struct fw_update_task_notify {
struct fw_update_task {
struct firmware_update_control base; /**< The base control instance. */
struct fw_update_task_notify notify; /**< The update notification interface. */
struct firmware_update *updater; /**< The firmware updater. */
const struct firmware_update *updater; /**< The firmware updater. */
struct system *system; /**< The system manager. */
int update_status; /**< The last firmware update status. */
uint8_t running; /**< Flag indicating if an update is running. */
@ -44,7 +44,7 @@ struct fw_update_task {
};
int fw_update_task_init (struct fw_update_task *task, struct firmware_update *updater,
int fw_update_task_init (struct fw_update_task *task, const struct firmware_update *updater,
struct system *system);
int fw_update_task_start (struct fw_update_task *task, uint16_t stack_words, bool running_recovery);