pebble/platform/snowy/boot/src/util/version.h
2025-01-27 11:38:16 -08:00

97 lines
4.2 KiB
C

/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define FW_METADATA_CURRENT_STRUCT_VERSION 0x1
#define FW_METADATA_VERSION_SHORT_BYTES 8
#define FW_METADATA_VERSION_TAG_BYTES 32
typedef enum {
FirmwareMetadataPlatformUnknown = 0,
FirmwareMetadataPlatformPebbleOneEV1 = 1,
FirmwareMetadataPlatformPebbleOneEV2 = 2,
FirmwareMetadataPlatformPebbleOneEV2_3 = 3,
FirmwareMetadataPlatformPebbleOneEV2_4 = 4,
FirmwareMetadataPlatformPebbleOnePointFive = 5,
FirmwareMetadataPlatformPebbleTwoPointZero = 6,
FirmwareMetadataPlatformPebbleOneBigboard = 0xff,
FirmwareMetadataPlatformPebbleOneBigboard2 = 0xfe,
} FirmwareMetadataPlatform;
// WARNING: changes in this struct must be reflected in:
// - iOS/PebblePrivateKit/PebblePrivateKit/PBBundle.m
struct FirmwareMetadata {
uint32_t version_timestamp;
char version_tag[FW_METADATA_VERSION_TAG_BYTES];
char version_short[FW_METADATA_VERSION_SHORT_BYTES];
const bool is_recovery_firmware;
const uint8_t hw_platform;
const uint8_t metadata_version; //!< This should be the last field, since we put the meta data struct at the end of the fw binary.
} __attribute__((__packed__));
typedef struct FirmwareMetadata FirmwareMetadata;
extern const FirmwareMetadata TINTIN_METADATA;
//! Copies the version metadata of the running firmware in the provided struct.
//! @param[out] out_metadata pointer to a FirmwareMetadata to which to copy the version metadata
//! @returns true if it successfully copied the version metadata.
bool version_copy_running_fw_metadata(FirmwareMetadata *out_metadata);
//! Copies the version metadata of the recovery firmware in the provided struct.
//! If there is no valid metadata available, the struct will be wiped to be all zeroes.
//! @param[out] out_metadata pointer to a FirmwareMetadata to which to copy the version metadata
//! @returns true if it successfully copied the version metadata.
bool version_copy_recovery_fw_metadata(FirmwareMetadata *out_metadata);
//! Copies the version metadata of the update firmware located in
//! FLASH_REGION_FIRMWARE_SCRATCH_BEGIN into the provided struct.
//! If there is no valid metadata available, the struct will be wiped to be all zeroes.
//! @param[out] out_metadata pointer to a FirmwareMetadata to which to copy the version metadata
//! @returns true if it successfully copied the version metadata.
bool version_copy_update_fw_metadata(FirmwareMetadata *out_metadata);
//! Read recovery version_short from flash and copy to dest; copy at most
//! dest_len_bytes - 1 before being null-terminated via strncpy()
//!
//! @param dest: char[dest_len_bytes]
//! @returns true on success, false otherwise
bool version_copy_recovery_fw_version(char* dest, const int dest_len_bytes);
//! Checks to see if a valid PRF is installed with a correct checksum.
//! @return true if a PRF is installed, false otherwise.
bool version_is_prf_installed(void);
//! @return Pointer to the GNU build id data. This is a hash of the firmware
//! that is generated by the linker and uniquely identifies the binary.
//! @param[out] out_len The length of the build id in bytes.
const uint8_t * version_get_build_id(size_t *out_len);
//! Copies a hex C-string of the build id into the supplied buffer.
//! Get the build id from an elf, using `arm-none-eabi-readelf -n tintin_fw.elf`
//! @param[out] buffer The buffer into which the string should be copied.
//! @param max_length The length of buffer.
void version_copy_build_id_hex_string(char *buffer, size_t max_length);
//! Checks the firmware stored in FLASH_REGION_FIRMWARE_SCRATCH_BEGIN and compares it to the
//! currently running firmware.
//! @returns true if a downgrade is detected.
bool version_fw_downgrade_detected(void);