Общие сведения о загрузчике операционной системы

Загрузчик – это образ, принадлежащий поставщику и отвечающий за запуск ядра на устройстве. Загрузчик операционной системы защищает состояние устройства и отвечает за инициализацию доверенной среды выполнения (TEE) и привязку ее корня доверия. Загрузчик также проверяет целостность разделов boot и recovery, прежде чем передать управление ядру.

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

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

  1. Загрузка и инициализация памяти.

  2. Проверьте устройство в соответствии с процессом проверки при запуске.

  3. Проверьте разделы загрузки, в том числе boot, dtbo, init_boot и recovery, в соответствии с процессом проверки при запуске. На этом этапе проверьте версию заголовка образа загрузки и выполните его синтаксический анализ.

  4. Если используются обновления A/B, определите текущий слот для загрузки.

  5. Определяет, нужно ли загружать режим восстановления. Подробнее о поддержке беспроводных обновлений…

  6. Загрузите загрузочные образы, например boot.img, vendor_boot.img, init_boot.img и другие проприетарные загрузочные образы поставщика. Эти загрузочные образы содержат образы ядра и виртуального диска.

    1. Загрузите ядро в память как самораспаковывающийся сжатый двоичный файл. Ядро распаковывается и начинает выполняться в памяти.

    2. Загрузите ramdisk и раздел bootconfig в память, чтобы создать initramfs.

Дополнительные функции, связанные с загрузчиком операционной системы

Ниже приведен список дополнительных функций, связанных с загрузчиком, которые вы можете реализовать:

  • Оверлей дерева устройств (DTO). Наложение дерева устройств позволяет загрузчику поддерживать разные конфигурации оборудования. DTO компилируется в двоичный объект дерева устройств (DTB), который используется загрузчиком.

  • Случайное распределение виртуальных адресов образа ядра. Загрузчик поддерживает случайное распределение виртуальных адресов, по которым загружается образ ядра. Чтобы рандомизировать адрес, задайте для параметра RANDOMIZE_BASE значение true в конфигурации ядра. Загрузчик должен предоставить энтропию, передав случайное значение u64 в узле дерева устройств /chosen/kaslr-seed.

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

  • Конфигурация загрузки Конфигурация загрузки доступна в Android 12 и более поздних версиях. Она позволяет передавать сведения о конфигурации из сборки и загрузчика в операционную систему. До Android 12 использовались параметры командной строки ядра с префиксом androidboot.

  • Беспроводные обновления. Устройства Android могут получать и устанавливать беспроводные обновления для системы, приложений и правил часовых поясов. Эта функция влияет на реализацию загрузчика операционной системы. Общую информацию о беспроводном обновлении можно найти в статье Беспроводные обновления. Подробнее о реализации беспроводных обновлений для загрузчика можно узнать в статье Поддержка беспроводных обновлений.

  • Привязка версии. Привязка версии привязывает ключи безопасности к операционной системе и версии уровня исправления. Привязка к версии гарантирует, что злоумышленник, обнаруживший уязвимость в старой версии системы или ПО доверенной среды исполнения, не сможет откатить устройство до уязвимой версии и использовать ключи, созданные в более новой версии. Загрузчик должен предоставлять определенную информацию для поддержки привязки версии. Дополнительную информацию можно найти в разделе Сведения о версии в свойствах AVB.

Командная строка ядра

Объедините командную строку ядра из следующих местоположений:

  • Командная строка загрузчика: набор статических и динамических параметров, определяемых загрузчиком.

  • Дерево устройств: узел chosen/bootargs

  • defconfig: от CONFIG_CMDLINE

  • boot.img – из командной строки (смещение и размер указаны в system/core/mkbootimg/bootimg.h).

В Android 12 для передачи параметров androidboot.* в пользовательское пространство Android вместо командной строки ядра можно использовать bootconfig.