AbSupportLib: Align with Android Boot Control Block 1.1

Boot Control Block (BCB) is stored at the "misc" partition which is
used for implementing A/B boot in bootloader. This patch updates
AB_SLOT_DATA and AB_BOOT_INFO struct to align it with Android[1] and
kernelflinger[2] of project celadon.

[1] https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/main/boot/1.1/default/boot_control/include/private/boot_control_definition.h
[2] https://github.com/projectceladon/kernelflinger/blob/master/avb/libavb_ab/avb_ab_flow.h

Signed-off-by: jizhenlo <zhenlong.z.ji@intel.com>
Signed-off-by: Jiaqing Zhao <jiaqing.zhao@intel.com>
This commit is contained in:
jizhenlo 2023-09-18 10:23:47 +08:00 committed by Guo Dong
parent 259908c8de
commit 4e3cfe8eb9
2 changed files with 37 additions and 28 deletions

View File

@ -18,39 +18,47 @@
#include <Guid/OsBootOptionGuid.h> #include <Guid/OsBootOptionGuid.h>
#include <BlockDevice.h> #include <BlockDevice.h>
// Magic for the A/B struct // Magic for the A/B struct, 0x42414342
#define AB_MAGIC_SIGNATURE SIGNATURE_32 ('\0', 'A', 'B', '0') #define AB_MAGIC_SIGNATURE SIGNATURE_32('B', 'C', 'A', 'B')
typedef struct { typedef struct {
/// // Slot priority with 15 meaning highest priority, 1 lowest
/// Slot priority. Range from 0 to AB_MAX_PRIORITY // priority and 0 the slot is unbootable.
/// 0 indicates this slot is unbootable. UINT8 Priority:4;
/// 1 is the lowest priority and AB_MAX_PRIORITY is highest // Number of times left attempting to boot this slot.
/// UINT8 TriesRemaining:3;
UINT8 Priority; // 1 if this slot has booted successfully, 0 otherwise.
UINT8 SuccessBoot:1;
/// // 1 if this slot is corrupted from a dm-verity corruption, 0
/// number of times left to attempting to boot this slot. // otherwise.
/// Range from 0 to AB_MAX_TRIES UINT8 VerityCorrupted:1;
/// // Reserved for further use.
UINT8 TriesRemaining; UINT8 Reserved:7;
} __attribute__((packed)) AB_SLOT_DATA;
///
/// 0 indicates successful boot, other values means boot failure
///
UINT8 SuccessBoot;
UINT8 Reserved;
} AB_SLOT_DATA;
typedef struct { typedef struct {
// NUL terminated active slot suffix.
UINT8 SlotSuffix[4];
// Bootloader Control AB magic number (see AB_MAGIC_SIGNATURE).
UINT32 Magic; UINT32 Magic;
// Version of struct being used (see AB_VERSION).
UINT8 Major; UINT8 Major;
UINT8 Minor; // Number of slots being managed.
UINT8 Reserved1[2]; UINT8 NbSlot:3;
AB_SLOT_DATA SlotData[2]; // Number of times left attempting to boot recovery.
UINT8 Reserved2[12]; UINT8 RecoveryTriesRemaining:3;
// Status of any pending snapshot merge of dynamic partitions.
UINT8 MergeStatus:3;
// Ensure 4-bytes alignment for slot_info field.
UINT8 Reserved1[1];
// Per-slot information. Up to 4 slots.
AB_SLOT_DATA SlotData[4];
// Reserved for further use.
UINT8 Reserved2[8];
// CRC32 of all 28 bytes preceding this field (little endian
// format).
UINT32 Crc32; UINT32 Crc32;
} AB_BOOT_INFO; } __attribute__((packed)) AB_BOOT_INFO;
typedef struct { typedef struct {
UINT8 LegacyData[2048]; UINT8 LegacyData[2048];

View File

@ -49,13 +49,14 @@ ParseBootSlot (
UINTN DataSize; UINTN DataSize;
if (AbBootInfo->Magic != AB_MAGIC_SIGNATURE) { if (AbBootInfo->Magic != AB_MAGIC_SIGNATURE) {
DEBUG ((DEBUG_INFO, "AB magic error: 0x%x\n", AbBootInfo->Magic));
return -1; return -1;
} }
DataSize = sizeof (AB_BOOT_INFO) - sizeof (UINT32); DataSize = sizeof (AB_BOOT_INFO) - sizeof (UINT32);
Status = CalculateCrc32WithType ((UINT8 *)AbBootInfo, DataSize, Crc32TypeDefault, &CrcOut); Status = CalculateCrc32WithType ((UINT8 *)AbBootInfo, DataSize, Crc32TypeDefault, &CrcOut);
if (EFI_ERROR (Status) || (SwapBytes32 (CrcOut) != AbBootInfo->Crc32)) { if (EFI_ERROR (Status) || (CrcOut != AbBootInfo->Crc32)) {
DEBUG ((DEBUG_INFO, "BootSlot CRC error: 0x%x !=0x%x\n", SwapBytes32 (CrcOut), AbBootInfo->Crc32)); DEBUG ((DEBUG_INFO, "BootSlot CRC error: 0x%x !=0x%x\n", CrcOut, AbBootInfo->Crc32));
return -2; return -2;
} }