Как реализовать bootconfig в Android 12

В Android 12 функция bootconfig заменяет параметры командной строки ядра, androidboot.* которые использовались в Android 11 и более ранних версиях. Функция bootconfig – это механизм передачи сведений о конфигурации из сборки и загрузчика операционной системы в Android 12.

Эта функция позволяет отделить параметры конфигурации пользовательского пространства Android от параметров ядра. Перенос длинных параметров ядра androidboot.* в файл bootconfig освобождает место в командной строке ядра и позволяет добавлять новые параметры в будущем.

bootconfig должны поддерживать как ядро, так и пользовательское пространство Android.

  • Первая версия с поддержкой: Android 12
  • Первая версия ядра с поддержкой: 12-5.4.xx kernel

Реализуйте функцию bootconfig для новых устройств с версией ядра 12-5.10.xx. Если вы обновляете устройства, реализовывать его не нужно.

Примеры и источник

При просмотре примеров и исходного кода в этом разделе обратите внимание, что формат кода bootconfig лишь немного отличается от формата командной строки ядра, используемой в Android 11 и более ранних версиях. Однако для вас важно следующее различие:

  • Параметры должны быть разделены последовательностью символов переноса строки \n, а не пробелами.

Пример загрузчика

Пример загрузчика можно найти в справочной реализации загрузчика U-boot для Cuttlefish. Ниже приведены два коммита в ветке. Первый обновляет версию заголовка загрузки до последней версии. В примере первый коммит обновляет поддержку версии до следующей, v4. Второй выполняет два действия: добавляет обработку bootconfig и демонстрирует добавление параметров во время выполнения.

Пример сборки

Пример сборки, в котором показано, как изменить mkbootimg, чтобы создать vendor_boot.img с заголовком загрузки поставщика версии 4, можно найти на странице mkbootimg changes for bootconfig. Чтобы выполнить следующие действия, ознакомьтесь с изменениями в Cuttlefish:

Реализация

Партнерам необходимо добавить поддержку в загрузчики и перенести параметры androidboot.*, заданные во время сборки, из командной строки ядра в файл bootconfig. Лучше всего вносить изменения постепенно. Подробнее об этом рассказывается в разделе Поэтапное внедрение и проверка.

Если у вас есть изменения, которые ищут параметры androidboot.* в файле /proc/cmdline, перенаправьте их в файл /proc/bootconfig. Свойства ro.boot.* задаются с новыми значениями bootconfig, поэтому вам не нужно вносить изменения в код, использующий эти свойства.

Изменения в сборке

Сначала обновите версию заголовка загрузки до версии 4:

- BOARD_BOOT_HEADER_VERSION := 3

+ BOARD_BOOT_HEADER_VERSION := 4

Добавьте параметр командной строки ядра bootconfig. В результате ядро будет искать раздел bootconfig:

BOARD_KERNEL_CMDLINE += bootconfig

Параметры bootconfig создаются на основе параметров в переменной BOARD_BOOTCONFIG, так же как командная строка ядра создается на основе BOARD\_KERNEL\_CMDLINE.

Любые параметры androidboot.* можно перенести без изменений, как показано ниже:

- BOARD_KERNEL_CMDLINE += androidboot..selinux=enforcing

+ BOARD_BOOTCONFIG += androidboot..selinux=enforcing

Изменения в загрузчике ОС

Загрузчик операционной системы настраивает initramfs перед переходом к ядру. Конфигурация загрузки ядра ищет раздел bootconfig и проверяет, находится ли он в конце initramfs, и есть ли у него ожидаемый трейлер.

Загрузчик операционной системы получает информацию о макете vendor_boot.img из заголовка загрузочного образа поставщика.

Диаграмма с примером структуры распределения памяти bootconfig

Рисунок 1. Распределение памяти bootconfig в Android 12

Загрузчик создает в памяти раздел bootconfig. В разделе bootconfig содержатся данные о распределении памяти для следующих элементов:

  • Параметры
  • 4 Б (размер parameters size)
  • 4 Б (размер parameters checksum)
  • 12-байтовая волшебная строка bootconfig (#BOOTCONFIG\n)

Параметры берутся из двух источников: параметры, известные во время сборки, и параметры, неизвестные во время сборки. Необходимо добавить неизвестные параметры.

Параметры, известные во время сборки, упаковываются в конец изображения vendor_boot в разделе bootconfig. Размер раздела хранится в байтах в поле заголовка загрузки поставщика vendor_bootconfig_size.

Параметры, которые неизвестны во время сборки, становятся известны только во время выполнения в загрузчике. Их нужно добавить в конец раздела параметров bootconfig до применения трейлера bootconfig.

Если вам нужно добавить параметры после применения трейлера bootconfig, перезапишите трейлер и примените его снова.

Постепенная реализация и проверка

Реализуйте функцию bootconfig поэтапно, следуя инструкциям в этом разделе. Не изменяйте параметры командной строки ядра при добавлении параметров bootconfig.

Ниже описаны шаги по постепенной реализации с проверкой.

  1. Внесите изменения в загрузчик и сборку, а затем выполните следующие действия:
    1. Используйте переменную BOARD_BOOTCONFIG, чтобы добавить новый параметр bootconfig.
    2. Не изменяйте параметры командной строки ядра, чтобы устройство могло загружаться правильно. Это значительно упрощает отладку и проверку.
  2. Проверьте, правильно ли работает функция, изучив содержимое /proc/bootconfig. Убедитесь, что после загрузки устройства вы видите добавленный параметр.
  3. Перенесите параметры androidboot.* из командной строки ядра в bootconfig, используя переменную BOARD_BOOTCONFIG и загрузчик операционной системы.
  4. Убедитесь, что каждый из параметров есть в /proc/bootconfig И отсутствует в /proc/cmdline. Если вы можете подтвердить это, значит реализация прошла успешно.

Особенности беспроводного обновления и перехода на более ранние версии

При управлении обновлениями и откатами по беспроводной сети между разными версиями Android или разными версиями ядра следует соблюдать особую осторожность.

Android 12 – первая версия с поддержкой bootconfig. Если вы хотите перейти на более раннюю версию, вместо bootconfig необходимо использовать параметры командной строки ядра.

Версии ядра 12-5.4 и более поздние поддерживают bootconfig. Если вы хотите перейти на более раннюю версию(включая 11-5.4), необходимо использовать параметры командной строки ядра.

При обновлении с Android 11 и более ранних версий до Android 12 и более поздних можно продолжать использовать параметры командной строки ядра. То же самое касается обновления версий ядра.

Устранение неполадок

Если на этапе проверки вы не видите ожидаемые параметры в /proc/bootconfig, проверьте журналы ядра в logcat. Если ядро поддерживает bootconfig, в журнале всегда есть запись об этом.

Пример выходных данных журнала

$ adb logcat | grep bootconfig
02-24 17:00:07.610     0     0 I Load bootconfig: 128 bytes 9 nodes

Если вы видите журнал ошибок, значит при загрузке файла bootconfig возникла проблема. Чтобы посмотреть разные типы ошибок, откройте файл init/main.c.