Android 9 включает следующие изменения в спецификации причины загрузки загрузчика.
Причины загрузки
Загрузчик использует уникально доступные аппаратные ресурсы и ресурсы памяти, чтобы определить причину перезагрузки устройства, а затем сообщает об этом определении, добавляя androidboot.bootreason=<reason> в командную строку ядра Android для его запуска. Затем init переводит эту командную строку в свойство Android bootloader_boot_reason_prop ( ro.boot.bootreason ). Для устройств с Android 12 или более поздней версии, использующих версию ядра 5.10 или более позднюю, androidboot.bootreason=<reason> добавляется в bootconfig вместо командной строки ядра.
Спецификации причины загрузки
Предыдущие выпуски Android указывали формат причины загрузки, который не использовал пробелы, был весь в нижнем регистре, включал несколько требований (например, для сообщения kernel_panic , watchdog , cold / warm / hard ) и учитывал другие уникальные причины. Эта свободная спецификация привела к появлению сотен пользовательских (и иногда бессмысленных) строк причин загрузки, что, в свою очередь, привело к неуправляемой ситуации. В текущем выпуске Android огромное количество почти неразборчивого или бессмысленного контента, поданного загрузчиком, создало проблемы с соответствием для bootloader_boot_reason_prop .
С выпуском Android 9 команда Android осознает, что устаревший bootloader_boot_reason_prop имеет значительный импульс и не может быть переписан во время выполнения. Следовательно, любые улучшения спецификации причины загрузки должны исходить из взаимодействия с разработчиками загрузчика и доработок существующей системы. С этой целью команда Android:
- Взаимодействие с разработчиками загрузчиков, чтобы побудить их:
- Укажите канонические, анализируемые и узнаваемые причины для
bootloader_boot_reason_prop. - Участвуйте в списке
system/core/bootstat/bootstat.cppkBootReasonMap.
- Укажите канонические, анализируемые и узнаваемые причины для
- Добавление контролируемого и перезаписываемого во время выполнения источника
system_boot_reason_prop(sys.boot.reason). Ограниченный набор системных приложений (например,bootstatиinit) может переписать это свойство, но всем приложениям могут быть предоставлены права sepolicy на его чтение. - Информирование пользователей о причине загрузки, чтобы дождаться монтирования пользовательских данных, прежде чем доверять содержимому в свойстве причины загрузки системы
system_boot_reason_prop.
Почему так поздно? Хотя bootloader_boot_reason_prop доступен на ранней стадии загрузки, он блокируется политикой безопасности Android по мере необходимости, поскольку представляет неточную, неразборчивую и неканоническую информацию. В большинстве ситуаций доступ к этой информации должен иметь только разработчик с глубоким знанием системы загрузки. Усовершенствованный, анализируемый и канонический API для загрузки через system_boot_reason_prop может быть надежно и точно получен только после монтирования пользовательских данных. Конкретно:
- Прежде чем пользовательские данные будут смонтированы,
system_boot_reason_propбудет содержать значение изbootloader_boot_reason_prop. - После того , как пользовательские данные смонтированы,
system_boot_reason_propможет быть обновлен, чтобы соответствовать требованиям или сообщать более точную информацию.
По этой причине Android 9 продлевает период времени до того, как причина загрузки может быть официально получена, изменяя ее с немедленной точной при загрузке (с помощью bootloader_boot_reason_prop ) на доступную только после монтирования пользовательских данных (с помощью system_boot_reason_prop ).
Логика Bootstat зависит от более информативного и совместимого bootloader_boot_reason_prop . Когда это свойство использует предсказуемый формат, оно повышает точность всех контролируемых сценариев перезагрузки и завершения работы, что, в свою очередь, уточняет и расширяет точность и значение system_boot_reason_prop .
Канонический формат причины загрузки
Канонический формат причины загрузки для bootloader_boot_reason_prop в Android 9 использует следующий синтаксис:
<reason>,<subreason>,<detail>…
Правила оформления:
- Нижний регистр
- Без пробелов (используйте подчеркивание)
- Все печатные символы
-
reason, разделенная запятыми,subreasonи одна или несколькоdetail.- Требуемая
reason, представляющая причину с наивысшим приоритетом, по которой устройство должно было перезагрузиться или завершить работу. - Необязательная
subreason, которая представляет собой краткую информацию о том, почему устройство было перезагружено или выключено (или кто перезагрузил или выключил устройство). - Одно или несколько необязательных значений
detail.detailможет указывать на подсистему, чтобы помочь определить, какая конкретная система привела кsubreason. Вы можете указать несколько значенийdetail, которые обычно должны следовать иерархии важности. Однако также допустимо сообщать несколько значенийdetailравной важности.
- Требуемая
Пустое значение для bootloader_boot_reason_prop считается недопустимым (поскольку это позволяет другим агентам ввести причину загрузки постфактум).
Причина требований
Значение, указанное для reason (первый диапазон, до завершения или запятой), должно принадлежать к следующему набору, разделенному на основные, сильные и грубые причины:
- набор ядра:
- "
watchdog" -
"kernel_panic"
- "
- сильный набор:
-
"recovery" -
"bootloader"
-
- тупой набор:
-
"cold". Вообще указывает на полный сброс всех устройств, включая память. -
"hard". Обычно указывает, что состояние оборудования сброшено, иramoopsдолжен сохранять постоянное содержимое. -
"warm". Обычно указывает, что память и устройства сохраняют некоторое состояние, аramoops(см. драйверpstoreв ядре) содержит постоянное содержимое. -
"shutdown" -
"reboot". Обычно означает, что состояниеramoopsнеизвестно, а состояние оборудования неизвестно. Это значение является универсальным, поскольку значенияcold,hardиwarmдают представление о глубине сброса устройства.
-
Загрузчики должны предоставить набор ядра или тупую reason , и настоятельно рекомендуется subreason , если ее можно определить. Например, длительное нажатие клавиши питания, которое может иметь или не иметь резервную копию ramoops , будет иметь причину загрузки "reboot,longkey" .
Никакая основная reason не может быть частью какой-либо subreason или detail . Однако, поскольку причины, установленные ядром, не могут быть созданы пользовательским пространством, "watchdog" может быть повторно использован после явно заданной причины вместе с подробностями источника (например "reboot,watchdog,service_manager_unresponsive" или "reboot,software,watchdog" ).
Причины загрузки не должны требовать экспертных внутренних знаний для расшифровки и/или должны быть удобочитаемыми для человека с интуитивно понятным отчетом. Примеры: "shutdown,vbxd" (плохо), "shutdown,uv" (лучше), "shutdown,undervoltage" (предпочтительно).
Комбинации причина-подпричина
Android резервирует набор комбинаций reason subreason , которые не должны быть перегружены при обычном использовании, но могут использоваться в каждом конкретном случае, если комбинация точно отражает связанное условие. Примеры зарезервированных комбинаций включают:
-
"reboot,userrequested" -
"shutdown,userrequested" -
"shutdown,thermal"(от «thermald) -
"shutdown,battery" -
"shutdown,battery,thermal"(отBatteryStatsService) -
"reboot,adb" -
"reboot,shell" -
"reboot,bootloader" -
"reboot,recovery"
Дополнительные сведения см. в kBootReasonMap в system/core/bootstat/bootstat.cpp и в соответствующей истории изменений git в исходном репозитории Android.
Сообщение о причинах загрузки
Все причины загрузки, либо из загрузчика, либо записанные в канонической причине загрузки, должны быть записаны в разделе kBootReasonMap system/core/bootstat/bootstat.cpp . Список kBootReasonMap представляет собой сочетание совместимых и устаревших несовместимых причин. Разработчики загрузчика должны регистрировать здесь только новые совместимые причины (и не должны регистрировать несовместимые причины, если только продукт уже не отправлен и не может быть изменен).
Мы настоятельно рекомендуем использовать существующие соответствующие записи в system/core/bootstat/bootstat.cpp и проявлять сдержанность перед использованием несовместимой строки. Как правило, это:
- OK , чтобы сообщить
"kernel_panic"из загрузчика, так какbootstatможет проверятьramoopsнаkernel_panic signatures, чтобы уточнить подпричины в каноническомsystem_boot_reason_prop. -
kBootReasonMap( например,"panic")из загрузчика, так как это в конечном итоге лишает возможности уточнитьreason.
Например, если kBootReasonMap содержит "wdog_bark" , разработчик загрузчика должен:
- Измените на
"watchdog,bark"и добавьте в список вkBootReasonMap. - Подумайте, что означает
"bark"для тех, кто не знаком с технологией, и определите, доступна ли более значимаяsubreason.
Проверка соответствия причины загрузки
В настоящее время Android не предоставляет активный тест CTS, который может точно запускать или проверять все возможные причины загрузки, которые может предоставить загрузчик; партнеры по-прежнему могут попытаться запустить пассивный тест для определения совместимости.
В результате соответствие загрузчика требует, чтобы разработчики загрузчика добровольно придерживались духа правил и указаний, описанных выше. Мы призываем таких разработчиков вносить свой вклад в AOSP (в частности, в system/core/bootstat/bootstat.cpp ) и использовать эту возможность в качестве форума для обсуждения причин загрузки.