Android 9 includes the following changes to the bootloader boot reason specification.
Boot reasons
  A bootloader uses uniquely-available hardware and memory resources to
  determine why a device rebooted, then communicates that determination by
  adding androidboot.bootreason=<reason> to the Android
  kernel command line for its launch. init then translates this
  command line to propagate to the Android property
  bootloader_boot_reason_prop (ro.boot.bootreason).
  For devices launching with Android 12 or higher,
  using kernel version 5.10 or greater, androidboot.bootreason=<reason>
  is added to bootconfig instead of the kernel command line.
Boot reason specifications
  Previous releases of Android specified a boot reason format that used no
  spaces, was all lowercase, included few requirements (such as for reporting
  kernel_panic, watchdog,
  cold/warm/hard), and which made
  allowances for other unique reasons. This loose specification resulted in the
  proliferation of hundreds of custom (and sometimes meaningless) boot reason
  strings, which in turn led to an unmanageable situation. As of the current
  Android release, the sheer momentum of near unparseable or meaningless content
  filed by the bootloader has created compliance issues for
  bootloader_boot_reason_prop.
  With the Android 9 release, the Android team
  recognizes that the legacy bootloader_boot_reason_prop has
  substantial momentum and cannot be re-written at runtime. Any improvements to
  the boot reason specification must therefore come from interactions with
  bootloader developers and tweaks to the existing system. To that end the
  Android team is:
- Engaging with bootloader developers to encourage them to:
  - Provide canonical, parseable, and recognizable reasons to
    bootloader_boot_reason_prop.
- Participate in the system/core/bootstat/bootstat.cppkBootReasonMaplist.
 
- Provide canonical, parseable, and recognizable reasons to
    
- Adding a controlled and runtime-rewritable source of the
  system_boot_reason_prop(sys.boot.reason). A limited set of system apps (such asbootstatandinit) can rewrite this property, but all apps can be granted sepolicy rights to read it.
- Informing users of the boot reason to wait until after userdata is mounted
  before trusting the content in the system boot reason property
  system_boot_reason_prop.
  Why so late? While bootloader_boot_reason_prop is available early
  on in boot, it is blocked by the Android security policy on an as-need basis
  because it represents inaccurate, unparseable, and noncanonical information.
  In most situations, only developers with deep knowledge of the boot system
  should need to access this information. A refined, parseable, and canonical
  API for boot reason with system_boot_reason_prop can be reliably
  and accurately picked up only after userdata has mounted.
  Specifically:
- Before userdata has mounted,
    system_boot_reason_propwill contain the value frombootloader_boot_reason_prop.
- After userdata has mounted,
    system_boot_reason_propmay be updated to be compliant or to report more accurate information.
  For this reason, Android 9 extends the period of
  time before the boot reason can be officially acquired, changing it from being
  immediately accurate in boot (with bootloader_boot_reason_prop)
  to being available only after userdata has mounted (with
  system_boot_reason_prop).
  Bootstat logic depends on a more informative and compliant
  bootloader_boot_reason_prop. When that property uses a
  predictable format, it improves the accuracy of all controlled reboot and
  shutdown scenarios, which in turn refines and expands the accuracy and meaning
  of system_boot_reason_prop.
Canonical boot reason format
  The canonical boot reason format for bootloader_boot_reason_prop
  in Android 9 uses the following syntax:
<reason>,<subreason>,<detail>…
Formatting rules:
- Lower case
- No blanks (use underline)
- All printable characters
- Comma-separated reason,subreason, and one or moredetailinstances.- A required reasonthat represents the highest priority reason why the device had to reboot or shutdown.
- An optional subreasonthat represents a short summary of why the device had to reboot or shutdown (or who rebooted or shutdown the device).
- One or more optional detailvalues. Adetailmay point to a subsystem to aid in determining which specific system resulted in thesubreason. You can specify multipledetailvalues, which should generally follow a hierarchy of importance. However, it's also acceptable to report multipledetailvalues of equal importance.
 
- A required 
  An empty value for bootloader_boot_reason_prop is considered
  illegal (as this allows other agents to inject a boot reason after the fact).
Reason requirements
  The value given for reason (first span, prior to termination or
  comma) must be of the following set divided into kernel, strong, and blunt
  reasons:
- kernel set:
  - "watchdog"
- "kernel_panic"
 
- "
- strong set:
  - "recovery"
- "bootloader"
 
- blunt set:
  - "cold". Generally indicates a full reset of all devices, including memory.
- "hard". Generally indicates the hardware has its state reset and- ramoopsshould retain persistent content.
- "warm". Generally indicates the memory and the devices retain some state, and the- ramoops(see- pstoredriver in kernel) backing store contains persistent content.
- "shutdown"
- "reboot". Generally means the- ramoopsstate is unknown and the hardware state is unknown. This value is a catchall as the- cold,- hard, and- warmvalues provide clues as to the depth of the reset for the device.
 
  Bootloaders must provide a kernel set or a blunt set reason, and
  are strongly encouraged to provide a subreason if it can be
  determined. For example, a power key long press that may or may not have
  ramoops backup would have the boot reason
  "reboot,longkey".
  No first-span reason can be part of any subreason or
  detail. However, because kernel set reasons cannot be produced by
  user space, "watchdog" may be reused after a blunt set reason,
  along with a detail of the source (for example,
  "reboot,watchdog,service_manager_unresponsive", or
  "reboot,software,watchdog").
  Boot reasons should not require expert internal knowledge to decipher and/or
  should be human readable with an intuitive report. Examples:
  "shutdown,vbxd" (bad), "shutdown,uv" (better),
  "shutdown,undervoltage" (preferred).
Reason-subreason combinations
  Android reserves a set of reason-subreason
  combinations that should not be overloaded in normal usage but can be used on
  a case-by-case basis if the combination accurately reflects the associated
  condition. Examples of reserved combinations include:
- "reboot,userrequested"
- "shutdown,userrequested"
- "shutdown,thermal"(from- thermald)
- "shutdown,battery"
- "shutdown,battery,thermal"(from- BatteryStatsService)
- "reboot,adb"
- "reboot,shell"
- "reboot,bootloader"
- "reboot,recovery"
  For more details, refer to kBootReasonMap in
  system/core/bootstat/bootstat.cpp and the associated git
  changelog history in the Android source repository.
Report boot reasons
  All boot reasons, either from the bootloader or recorded in the canonical boot
  reason, must be recorded in the kBootReasonMap section of
  system/core/bootstat/bootstat.cpp. The
  kBootReasonMap list is a mix of compliant and legacy
  noncompliant reasons. Bootloader developers should register only new
  compliant reasons here (and shouldn't register noncompliant reasons unless
  the product has already shipped and cannot be changed).
  We strongly recommend using existing, compliant entries in
  system/core/bootstat/bootstat.cpp and exercising restraint before
  using a noncompliant string. As a guideline, it is:
- OK to report "kernel_panic"from the bootloader, asbootstatmay be able to inspectramoopsforkernel_panic signaturesto refine the subreasons into the canonicalsystem_boot_reason_prop.
- Not OK to report a noncompliant string in
  kBootReasonMap(such as"panic")from the bootloader, as this will ultimately break the ability to refine thereason.
  For example, if kBootReasonMap contains "wdog_bark",
  a bootloader developer should:
- Change to "watchdog,bark"and add to the list inkBootReasonMap.
- Consider what "bark"means for those unfamiliar with the technology and determine if a more meaningfulsubreasonis available.
Verify boot reason compliance
At this time, Android does not provide an active CTS test that can accurately trigger or inspect all possible boot reasons a bootloader could provide; partners can still attempt to run a passive test to determine compatibility.
  As a result, bootloader compliance requires bootloader developers to
  voluntarily adhere to the spirit of the rules and guidelines described above.
  We urge such developers to contribute to AOSP (specifically to
  system/core/bootstat/bootstat.cpp) and use this opportunity as a
  forum for discussions about boot reason issues.