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:
Родитель
ed5f1c245c
Коммит
2db1528c5f
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче