1# GBL EFI AB Slot Protocol 2 3This document describes the GBL AB Slot protocol. 4The protocol defines interfaces that can be used by EFI applications 5to query and manipulate boot slots. 6 7See this [document](./gbl_ab_boot_flow.md) For details on how GBL uses this 8protocol to implement A/B flows. 9 10| **Status** | Work in progress | 11|:------------|-----------------:| 12| **Created** | 2024-9-17 | 13 14## `GBL_EFI_AB_SLOT_PROTOCOL` 15 16### Summary 17 18This protocol provides interfaces for platform specific boot slot operations, 19such as determining the number of slots and the current target slot, 20changing the current target boot slot, marking boot attempts, and more. 21 22### GUID 23 24```c 25// {9a7a7db4-614b-4a08-3df9-006f49b0d80c} 26#define GBL_EFI_AB_SLOT_PROTOCOL_GUID \ 27 { \ 28 0x9a7a7db4, 0x614b, 0x4a08, { \ 29 0x3d, 0xf9, 0x00, 0x6f, 0x49, 0xb0, 0xd8, 0x0c \ 30 } \ 31 } 32``` 33 34### Protocol Version 35```c 36#define GBL_EFI_AB_SLOT_PROTOCOL_VERSION 0x00010000 37``` 38 39### Protocol Interface Structure 40 41```c 42typedef struct GBL_EFI_AB_SLOT_PROTOCOL { 43 // Currently must contain 0x00010000 44 UINT32 Version; 45 GBL_EFI_AB_SLOT_LOAD_BOOT_DATA LoadBootData; 46 GBL_EFI_AB_SLOT_GET_SLOT_INFO GetSlotInfo; 47 GBL_EFI_AB_SLOT_GET_CURRENT_SLOT GetCurrentSlot; 48 GBL_EFI_AB_SLOT_GET_ACTIVE_SLOT GetActiveSlot; 49 GBL_EFI_AB_SLOT_SET_ACTIVE_SLOT SetActiveSlot; 50 GBL_EFI_AB_SLOT_SET_SLOT_UNBOOTABLE SetSlotUnbootable; 51 GBL_EFI_AB_SLOT_MARK_BOOT_ATTEMPT MarkBootAttempt; 52 GBL_EFI_AB_SLOT_REINITIALIZE Reinitialize; 53 GBL_EFI_AB_SLOT_GET_BOOT_REASON GetBootReason; 54 GBL_EFI_AB_SLOT_SET_BOOT_REASON SetBootReason; 55 GBL_EFI_AB_SLOT_FLUSH Flush; 56} GBL_EFI_AB_SLOT_PROTOCOL; 57``` 58 59### Parameters 60 61**Version** 62 63The revision to which the `GBL_EFI_AB_SLOT_PROTOCOL` adheres. 64All future version must be backwards compatible. 65If a future version is not backwards compatible, a different GUID must be used. 66 67**LoadBootData** 68 69Loads slot metadata from persistent storage. Other slot operations may call 70this method internally. 71See [`GBL_EFI_AB_SLOT_PROTOCOL.LoadBootData()`](#gbl_efi_ab_slot_protocolloadbootdata). 72 73**GetSlotInfo** 74 75Returns information about a slot by index. 76See [`GBL_EFI_AB_SLOT_PROTOCOL.GetSlotInfo()`](#gbl_efi_ab_slot_protocolgetslotinfo). 77 78**GetCurrentSlot** 79 80Returns the slot information of the currently booted bootloader. 81See [`GBL_EFI_AB_SLOT_PROTOCOL.GetCurrentSlot()`](#gbl_efi_ab_slot_protocolgetcurrentslot). 82 83**GetNextSlot** 84 85Returns the slot information of the next slot decision. 86See [`GBL_EFI_AB_SLOT_PROTOCOL.GetNextSlot()`](#gbl_efi_ab_slot_protocolgetcurrentslot). 87 88**SetActiveSlot** 89 90Marks the specified slot as the active boot target. 91See [`GBL_EFI_AB_SLOT_PROTOCOL.SetActiveSlot()`](#gbl_efi_ab_slot_protocolsetactiveslot). 92 93**SetSlotUnbootable** 94 95Marks the specified slot as unbootable. 96See [`GBL_EFI_AB_SLOT_PROTOCOL.SetSlotUnbootable()`](#gbl_efi_ab_slot_protocolsetslotunbootable). 97 98**Reinitialize** 99 100Resets slot metadata to a default, initial state. 101See [`GBL_EFI_AB_SLOT_PROTOCOL.Reinitialize()`](#gbl_efi_ab_slot_protocolreinitialize). 102 103**GetBootReason** 104 105Gets the boot reason. 106See [`GBL_EFI_AB_SLOT_PROTOCOL.GetBootReason()`](#gbl_efi_ab_slot_protocolgetbootreason). 107 108**SetBootReason** 109 110Sets the boot reason. 111See [`GBL_EFI_AB_SLOT_PROTOCOL.SetBootReason()`](#gbl_efi_ab_slot_protocolsetbootreason). 112 113**Flush** 114 115Synchronizes slot metadata with persistent storage. May re-establish data 116structure invariants, e.g. recalculate checksums. 117See [`GBL_EFI_AB_SLOT_PROTOCOL.Flush()`](#gbl_efi_ab_slot_protocolflush). 118 119## `GBL_EFI_AB_SLOT_PROTOCOL.LoadBootData()` 120 121### Summary 122 123Loads metadata about system boot slots. 124 125### Prototype 126 127```c 128typedef 129EFI_STATUS 130(EFIAPI * GBL_EFI_AB_SLOT_LOAD_BOOT_DATA)( 131 IN GBL_EFI_AB_SLOT_PROTOCOL* This, 132 OUT GBL_EFI_SLOT_METADATA_BLOCK* Metadata, 133); 134``` 135 136### Related Definitions 137 138```c 139typedef enum _GBL_EFI_SLOT_MERGE_STATUS { 140 GBL_EFI_SLOT_MERGE_STATUS_NONE = 0, 141 GBL_EFI_SLOT_MERGE_STATUS_UNKNOWN, 142 GBL_EFI_SLOT_MERGE_STATUS_SNAPSHOTTED, 143 GBL_EFI_SLOT_MERGE_STATUS_MERGING, 144 GBL_EFI_SLOT_MERGE_STATUS_CANCELLED, 145} GBL_EFI_SLOT_MERGE_STATUS; 146 147typedef struct _GBL_EFI_SLOT_METADATA_BLOCK { 148 // Value of 1 if persistent metadata tracks slot unbootable reasons. 149 UINT8 UnbootableMetadata; 150 UINT8 MaxRetries; 151 UINT8 SlotCount; 152 // See the definition of GBL_EFI_SLOT_MERGE_STATUS. 153 UINT8 MergeStatus; 154} GBL_EFI_SLOT_METADATA_BLOCK; 155``` 156 157### Parameters 158 159*This* 160 161A pointer to the [`GBL_EFI_AB_SLOT_PROTOCOL`](#protcol-interface-structure) 162instance. 163 164*Metadata* 165 166On return contains device-specific immutable information about the AB slot 167implementation. See [`Related Definitions`](#related-definitions) for the layout 168of the metadata structure and its fields. 169 170### Description 171 172In addition to information about individual slots, EFI applications need 173overarching metadata about AB boot slot implementations. 174In particular, implementations might not store persistent metadata detailing why 175specific slots are not bootable (i.e. unbootable metadata). Developers may want 176to know whether a device supports unbootable metadata to ease in debugging. 177 178Certain operations may be prohibited due to the device's A/B merge status. 179For more information about the *MergeStatus* field and Android Virtual A/B, see 180the documentation 181[here](https://source.android.com/docs/core/ota/virtual_ab/implement). 182 183### Status Codes Returned 184 185| Return Code | Semantics | 186|:------------------------|:--------------------------------------------------------------------------------------------------------------| 187| `EFI_SUCCESS` | Slot metadata was successfully read from persistent storage. | 188| `EFI_INVALID_PARAMETER` | One of *This* or *Metadata* is `NULL` or improperly aligned. | 189| `EFI_DEVICE_ERROR` | There was an error while performing the read operation. | 190| `EFI_VOLUME_CORRUPTED` | The metadata loaded is invalid or corrupt. The caller should call `Reinitialize` before taking other actions. | 191 192## `GBL_EFI_AB_SLOT_PROTOCOL.GetSlotInfo()` 193 194### Summary 195 196Queries info about a boot slot by index. 197 198### Prototype 199 200```c 201typedef 202EFI_STATUS 203(EFIAPI * GBL_EFI_AB_SLOT_GET_SLOT_INFO)( 204 IN GBL_EFI_AB_SLOT_PROTOCOL* This, 205 IN UINT8 Idx, 206 OUT GBL_EFI_SLOT_INFO* Info, 207) 208``` 209 210### Related Definitions 211 212```c 213typedef enum _GBL_EFI_SLOT_UNBOOTABLE_REASON { 214 UNKNOWN_REASON = 0, 215 NO_MORE_TRIES, 216 SYSTEM_UPDATE, 217 USER_REQUESTED, 218 VERIFICATION_FAILURE, 219} GBL_EFI_SLOT_UNBOOTABLE_REASON; 220 221typedef struct _GBL_EFI_SLOT_INFO { 222 // One UTF-8 encoded single character 223 UINT32 Suffix; 224 // Any value other than those explicitly enumerated in 225 // GBL_EFI_SLOT_UNBOOTABLE_REASON 226 // will be interpreted as UNKNOWN_REASON. 227 UINT32 UnbootableReason; 228 UINT8 Priority; 229 UINT8 Tries; 230 // Value of 1 if slot has successfully booted 231 UINT8 Successful; 232} GBL_EFI_SLOT_INFO; 233``` 234 235### Parameters 236 237*This* 238 239A pointer to the [`GBL_EFI_AB_SLOT_PROTOCOL`](#protcol-interface-structure) 240instance. 241 242*Idx* 243 244The index of the slot to query. 245 246*Info* 247 248On exit contains the metadata for the specified slot. 249See [Related Definitions](#related-definitions-1) 250for the layout and fields of the metadata structure. 251 252### Description 253 254Developers and EFI applications may wish to query metadata of arbitrary boot 255slots as part of debugging or logging. 256 257### Status Codes Returned 258 259| Return Code | Semantics | 260|:------------------------|:--------------------------------------------------------------------------------------------------------------| 261| `EFI_SUCCESS` | The call completed successfully. | 262| `EFI_INVALID_PARAMETER` | One of *This* or *Info* is `NULL` or improperly aligned, or the value of *Idx* invalid. | 263| `EFI_DEVICE_ERROR` | There was an error reading metadata from persistent storage. | 264| `EFI_VOLUME_CORRUPTED` | The metadata loaded is invalid or corrupt. The caller should call `Reinitialize` before taking other actions. | 265 266## `GBL_EFI_AB_SLOT_PROTOCOL.GetCurrentSlot()` 267 268### Summary 269 270Returns the slot information of the currently booted bootloader. 271 272### Prototype 273 274```c 275typedef 276EFI_STATUS 277(EFIAPI * GBL_EFI_AB_SLOT_GET_CURRENT_SLOT)( 278 IN GBL_EFI_AB_SLOT_PROTOCOL* This, 279 OUT GBL_EFI_SLOT_INFO* Info, 280); 281``` 282 283### Parameters 284 285*This* 286 287A pointer to the [`GBL_EFI_AB_SLOT_PROTOCOL`](#protcol-interface-structure) 288instance. 289 290*Info* 291 292On exit contains the metadata for the current slot. 293See the definition for [`GBL_EFI_SLOT_INFO`](#related-definitions-1) 294for the structure definition. 295 296### Description 297 298Returns the slot of the currently booted bootloader. If bootloader is not 299slotted, i.e. the device only has a single slot bootloader instead of A/B, the 300function returns `EFI_UNSUPPORTED`. 301 302This is identical to knowing the index of the current slot and calling 303`GetSlotInfo()` with that index. 304 305### Status Codes Returned 306 307| Return Code | Semantics | 308|:------------------------|:---------------------------------- | 309| `EFI_SUCCESS` | The call completed successfully. | 310| `EFI_UNSUPPORTED` | Bootloader is not slotted. | 311| `EFI_INVALID_PARAMETER` | One of *This* or *Info* is `NULL`. | 312 313## `GBL_EFI_AB_SLOT_PROTOCOL.GetNextSlot()` 314 315### Summary 316 317Returns the slot information of the next slot decision. 318 319### Prototype 320 321```c 322typedef 323EFI_STATUS 324(EFIAPI * GBL_EFI_AB_SLOT_GET_NEXT_SLOT)( 325 IN GBL_EFI_AB_SLOT_PROTOCOL* This, 326 IN BOOL MarkBootAttempt, 327 OUT GBL_EFI_SLOT_INFO* Info, 328); 329``` 330 331### Parameters 332 333*This* 334 335A pointer to the [`GBL_EFI_AB_SLOT_PROTOCOL`](#protcol-interface-structure) 336instance. 337 338*MarkBootAttempt* 339 340The parameter is set to true if caller attempts to load, verify and boot the 341returned slot. If the caller only wants to query the next slot decision and 342does not intend to cause any state change, it is set to false. 343 344*Info* 345 346On exit contains the metadata for the next slot. 347See the definition for [`GBL_EFI_SLOT_INFO`](#related-definitions-1) 348for the structure definition. 349 350### Description 351 352The function returns the highest priority bootable slot according to current 353slot state. 354 355If parameter `MarkBootAttempt` is true, implementation should updates internal 356metadata for the slot such as decrementing retry counters if slot has not been 357successful. 358 359If there are no bootable slots, the function **MUST** returns `EFI_NOT_FOUND`. 360 361### Status Codes Returned 362 363| Return Code | Semantics | 364|:------------------------|:--------------------------------------------------------------------------------------------------------------| 365| `EFI_SUCCESS` | The call completed successfully. | 366| `EFI_NOT_FOUND` | There are no bootable slots for the next decision. | 367| `EFI_INVALID_PARAMETER` | One of *This* or *Info* is `NULL` or improperly aligned. | 368| `EFI_DEVICE_ERROR` | There was an error reading metadata from persistent storage. | 369| `EFI_VOLUME_CORRUPTED` | The metadata loaded is invalid or corrupt. The caller should call `Reinitialize` before taking other actions. | 370 371## `GBL_EFI_AB_SLOT_PROTOCOL.SetActiveSlot()` 372 373### Summary 374 375Sets the active slot by index. Makes it the highest priority bootable slot. 376 377### Prototype 378 379```c 380typedef 381EFI_STATUS 382(EFIAPI * GBL_EFI_AB_SLOT_SET_ACTIVE_SLOT)( 383 IN GBL_EFI_AB_SLOT_PROTOCOL* This, 384 IN UINT8 Idx, 385); 386``` 387 388### Parameters 389 390*This* 391 392A pointer to the [`GBL_EFI_AB_SLOT_PROTOCOL`](#protcol-interface-structure) 393instance. 394 395*Idx* 396 397The index of the new active slot. 398 399### Description 400 401Explicitly sets the target boot slot to the one defined by `Idx`. 402This clears any unbootable reason metadata the slot may have, resets its tries 403remaining to a device specific default, resets its priority to a device specific 404default, sets the priority of all other slots to be lower than that of the 405target, and clears the slot's *Successful* flag. 406All these changes **MUST** be visible in subsequent calls to `GetSlotInfo()`. 407Depending on device policy, e.g. lock state, changing the target boot slot 408explicitly may be prohibited. 409 410### Status Codes Returned 411 412| Return Code | Semantics | 413|:------------------------|:--------------------------------------------------------------------------------------------------------------| 414| `EFI_SUCCESS` | The call completed successfully. | 415| `EFI_INVALID_PARAMETER` | One of *This* or *Info* is `NULL` or improperly aligned, or the value of *Idx* was invalid. | 416| `EFI_DEVICE_ERROR` | There was an error reading metadata from persistent storage. | 417| `EFI_VOLUME_CORRUPTED` | The metadata loaded is invalid or corrupt. The caller should call `Reinitialize` before taking other actions. | 418| `EFI_ACCESS_DENIED` | Device policy prohibited the boot slot target change. | 419 420## `GBL_EFI_AB_SLOT_PROTOCOL.SetSlotUnbootable()` 421 422### Summary 423 424Marks a slot as unbootable for the provided reason. 425 426### Prototype 427 428```c 429typedef 430EFI_STATUS 431(EFIAPI * GBL_EFI_AB_SLOT_SET_SLOT_UNBOOTABLE)( 432 IN GBL_EFI_AB_SLOT_PROTOCOL* This, 433 IN UINT8 Idx, 434 IN UINT32 UnbootableReason, 435); 436``` 437 438### Parameters 439 440*This* 441 442A pointer to the [`GBL_EFI_AB_SLOT_PROTOCOL`](#protcol-interface-structure) 443instance. 444 445*Idx* 446 447The index of the slot to mark unbootable. 448 449*UnbootableReason* 450 451The reason the slot is being marked unable to be booted. 452See the definition for [`GBL_EFI_SLOT_UNBOOTABLE_REASON`](#related-definitions-1) 453for valid values of *UnbootableReason*. 454 455**Note:** Unbootable reason codes are a best-effort debug and RMA helper. 456The device's persistent metadata structures may not track unbootable reasons, 457and other software that interacts with boot slots may not set unbootable reason 458codes accurately. 459 460### Description 461 462Marks a slot as not a valid boot target. 463The slot's *Priority*, *TriesRemaining*, and *Successful* fields are all set to 464`0`. 465Subsequent calls to `GetSlotInfo()` **MUST** reflect these changes to slot info. 466If the slot was the current slot, the current boot target will have changed. 467This change **MUST** be reflected in subsequent calls to `GetCurrentSlot()`. 468 469If the protocol driver supports tracking slot unbootable reasons, then 470subsequent calls to `GetSlotInfo()` **MUST** have the same *UnbootableReason* in 471the info structure. 472 473### Status Codes Returned 474 475| Return Code | Semantics | 476|:------------------------|:----------------------------------------------------------------------------------------------------------------------| 477| `EFI_SUCCESS` | The call completed successfully. | 478| `EFI_INVALID_PARAMETER` | *This* is `NULL` or improperly aligned, the value of *Idx* is invalid, or the value of *UnbootableReason* is invalid. | 479| `EFI_DEVICE_ERROR` | There was an error reading metadata from persistent storage. | 480| `EFI_VOLUME_CORRUPTED` | The metadata loaded is invalid or corrupt. The caller should call `Reinitialize` before taking other actions. | 481 482## `GBL_EFI_AB_SLOT_PROTOCOL.MarkBootAttempt()` 483 484### Summary 485 486Marks a boot attempt on the current slot. 487 488### Prototype 489 490```c 491typedef 492EFI_STATUS 493(EFIAPI * GBL_EFI_AB_SLOT_MARK_BOOT_ATTEMPT)( 494 IN GBL_EFI_AB_SLOT_PROTOCOL* This, 495); 496``` 497### Parameters 498 499*This* 500 501A pointer to the [`GBL_EFI_AB_SLOT_PROTOCOL`](#protcol-interface-structure) 502instance. 503 504### Description 505 506Updates internal metadata for the current boot target slot. 507If the current slot has registered a successful boot, its tries remaining field 508is left unchanged. 509If there are no slots with non-zero *Successful* or *Tries* fields, the call to 510`MarkBootAttempt()` **MUST** return `EFI_ACCESS_DENIED`. The bootloader then 511must decide on the next action to take. 512 513Subsequent calls to `GetSlotInfo()` and `GetCurrentSlot()` **MUST** reflect 514the decremented tries. 515 516### Status Codes Returned 517 518| Return Code | Semantics | 519|:------------------------|:--------------------------------------------------------------------------------------------------------------| 520| `EFI_SUCCESS` | The call completed successfully. | 521| `EFI_INVALID_PARAMETER` | *This* is `NULL` or improperly aligned. | 522| `EFI_DEVICE_ERROR` | There was an error reading metadata from persistent storage. | 523| `EFI_VOLUME_CORRUPTED` | The metadata loaded is invalid or corrupt. The caller should call `Reinitialize` before taking other actions. | 524| `EFI_ACCESS_DENIED` | The current slot has no more tries remaining. | 525 526## `GBL_EFI_AB_SLOT_PROTOCOL.Reinitialize()` 527 528### Summary 529 530Reinitializes all boot slot metadata to a known initial state. 531 532### Prototype 533 534```c 535typedef 536EFI_STATUS 537(EFIAPI * GBL_EFI_AB_SLOT_REINITIALIZE)( 538 IN GBL_EFI_AB_SLOT_PROTOCOL* This, 539); 540``` 541 542### Parameters 543 544*This* 545 546A pointer to the [`GBL_EFI_AB_SLOT_PROTOCOL`](#protcol-interface-structure) 547instance. 548 549### Description 550 551In particular, all slots should have the following fields cleared and set to 552device-specific defaults: 553* *Priority* 554* *Tries* 555 556and have the following fields set to `0`: 557* *UnbootableReason* 558* *Successful* 559 560This may change the next target boot slot. 561 562### Status Codes Returned 563 564| Return Code | Semantics | 565|:------------------------|:-------------------------------------------------------| 566| `EFI_SUCCESS` | The call completed successfully. | 567| `EFI_INVALID_PARAMETER` | *This* is `NULL` or improperly aligned. | 568| `EFI_ACCESS_DENIED` | Device policy prohibited resetting boot slot metadata. | 569 570## `GBL_EFI_AB_SLOT_PROTOCOL.GetBootReason()` 571 572### Summary 573 574Gets the current boot reason and subreason. 575 576### Prototype 577 578```c 579typedef 580EFI_STATUS 581(EFIAPI * GBL_EFI_AB_SLOT_GET_BOOT_REASON)( 582 IN GBL_EFI_AB_SLOT_PROTOCOL* This, 583 OUT UINT32* Reason, 584 IN OUT UINTN* SubreasonLength; 585 OUT UINT8* Subreason; 586); 587``` 588 589### Related Definitions 590 591```c 592typedef enum _GBL_EFI_AB_SLOT_BOOT_REASON { 593 EMPTY = 0, 594 UNKNOWN = 1, 595 WATCHDOG = 14, 596 KERNEL_PANIC = 15, 597 RECOVERY = 3, 598 BOOTLOADER = 55, 599 COLD = 56, 600 HARD = 57, 601 WARM = 58, 602 SHUTDOWN = 59, 603 REBOOT = 18, 604 FASTBOOTD = 196, 605} GBL_EFI_AB_SLOT_BOOT_REASON; 606``` 607 608### Parameters 609 610*This* 611 612A pointer to the [`GBL_EFI_AB_SLOT_PROTOCOL`](#protcol-interface-structure) 613instance. 614 615*Reason* 616 617On exit, the boot reason code. See [Related Definitions](#related-definitions-2) 618for the list of valid codes. 619 620*SubreasonLength* 621 622On entry, the length of *Subreason* in bytes. 623On exit, the length of the UTF-8 encoded string pointed to by *Subreason*, 624ignoring any Null-terminator. 625 626*Subreason* 627 628On exit, the boot subreason as a UTF-8 encoded, Null-terminated string. 629 630### Description 631 632The boot reason is an Android mechanism for communicating between the running 633system and the bootloader. For example, if the boot reason is 'recovery', the 634bootloader should load the recovery RAM disk and command line. This information 635is stored in a device specific location and format. 636 637### Status Codes Returned 638 639| Return Code | Semantics | 640|:------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------| 641| `EFI_SUCCESS` | The call completed successfully. | 642| `EFI_INVALID_PARAMETER` | One of *This*, *Reason*, *SubreasonLength*, or *Subreason* is `NULL` or improperly aligned. | 643| `EFI_BUFFER_TOO_SMALL` | *Subreason* is too small to store the serialized subreason string. The value of *SubreasonLength* is modified to contain the minimum necessary buffer size. | 644| `EFI_VOLUME_CORRUPTED` | The metadata loaded is invalid or corrupt. The caller should call `Reinitialize` before taking other actions. | 645 646## `GBL_EFI_AB_SLOT_PROTOCOL.SetBootReason()` 647 648### Summary 649 650Sets the current boot reason. 651 652### Prototype 653 654```c 655typedef 656EFI_STATUS 657(EFIAPI * GBL_EFI_AB_SLOT_SET_BOOT_REASON)( 658 IN GBL_EFI_AB_SLOT_PROTOCOL* This, 659 IN UINT32 Reason, 660 IN UINTN SubreasonLength, 661 IN UINT8 Subreason, 662); 663``` 664 665### Parameters 666 667*This* 668 669A pointer to the [`GBL_EFI_AB_SLOT_PROTOCOL`](#protcol-interface-structure) 670instance. 671 672*Reason* 673 674The desired boot reason to set. See [here](#related-definitions-2) for the list 675of valid boot reasons. 676 677*SubreasonLength* 678 679The length of the *Subreason* string. 680 681*Subreason* 682 683The desired boot subreason as a UTF-8 encoded, Null-terminated string. 684 685### Description 686 687Sets the Android boot reason and subreason. 688This is usually used by the bootloader to clear the boot reason. 689See [`GetBootReason()`](#gbl_efi_ab_slot_protocolgetbootreason) for more 690information about boot reasons. 691 692### Status Codes Returned 693 694| Return Code | Semantics | 695|:------------------------|:----------------------------------------------------------------------------------------| 696| `EFI_SUCCESS` | The call completed successfully. | 697| `EFI_INVALID_PARAMETER` | One of *This*, *Reason*, or *Subreason* is `NULL` or improperly aligned. | 698| `EFI_INVALID_PARAMETER` | *Reason* is not a valid reason code or *Subreason* is not a valid UTF-8 encoded string. | 699| `EFI_UNSUPPORTED` | The platform does not support setting the boot reason. | 700| `EFI_BAD_BUFFER_SIZE` | *Subreason* is too large to be written to persistent storage. | 701 702## `GBL_EFI_AB_SLOT_PROTOCOL.Flush()` 703 704### Summary 705 706Writes any slot metadata modifications to persistent storage. 707 708### Prototype 709 710```c 711typedef 712EFI_STATUS 713(EFIAPI * GBL_EFI_AB_SLOT_FLUSH)( 714 IN GBL_EFI_AB_SLOT_PROTOCOL* This, 715); 716``` 717 718### Parameters 719 720*This* 721 722A pointer to the [`GBL_EFI_AB_SLOT_PROTOCOL`](#protcol-interface-structure) 723instance. 724 725### Description 726 727Protocol driver implementations may store modifications to boot slot metadata in 728memory before committing changes to storage in a single write operation. 729Protocol consumers need a mechanism to instruct the driver that they are 730finished operating on boot slots and that changes should be committed. 731The implementation should conduct any necessary ancillary tasks, e.g. 732recalculating checksums, before writing to storage. 733This is an optimization for performance and flash lifetime; implementations are 734free to write all modifications to storage as they occur and to define `Flash()` 735as a no-op. 736 737### Status Codes Returned 738 739| Return Code | Semantics | 740|:-------------------|:----------------------------------------------------------| 741| `EFI_SUCCESS` | The call completed successfully. | 742| `EFI_DEVICE_ERROR` | The device reported a write error during synchronization. | 743