Загружая роботов

Zagrujaja-robotov

Тебя никогда не интересовало, как работают fastboot или ADB? Или почему смартфон под управлением Android практически невозможно превратить в кирпич? Или, может быть, ты давно хотел узнать, где кроется магия фреймворка Xposed и зачем нужны загрузочные скрипты / syste m /etc/i nit.d? А как насчет консоли восстановления (recovery)? Это часть Android или вещь в себе и почему для установки сторонней прошивки обычный рекавери не подходит? Ответы на все эти и многие другие вопросы ты найдешь в данной статье.

КАК РАБОТАЕТ ANDROID

Узнать о скрытых возможностях программных систем можно, поняв принцип их работы. В некоторых случаях сделать это затруднительно, так как код системы может быть закрыт, но в случае Android мы можем изучить всю систему вдоль и поперек. В этой статье я не буду рассказывать обо всех нюансах работы Android и остановлюсь только на том, как происходит запуск ОС и какие события имеют место быть в промежутке между нажатием кнопки питания и появлением рабочего стола.

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

( В iOS,а тем более в Windows Phone возможнось кастомизации ущербна или невозможна вообще.)

ШАГ ПЕРВЫЙ. U-BOOT И ТАБЛИЦА РАЗДЕЛОВ

Все начинается с первичного загрузчика. После включения питания система исполняет код загрузчика, записанного в постоянную память устройства. Чаще всего его роль выполняет модифицированная версия загрузчика u-boot со встроенной поддержкой протокола fastboot, но производитель мобильного чипа или смартфона/ планшета имеет право выбрать и любой другой загрузчик на его вкус. Например, компания Rockchip использует собственный, несовместимый с fastboot загрузчик, и для его перепрограммирования и управления им приходится использовать проприетарные инструменты.

Протокол fastboot, в свою очередь, представляет собой систему управления загрузчиком с ПК, которая позволяет выполнять такие действия, как разлочка загрузчика, прошивка нового ядра и recovery, установка прошивки и многие другие. Смысл существования fastboot в том, чтобы иметь возможность восстановить смартфон в начальное состояние в ситуации, когда все остальные средства не работают. Fastboot останется на месте, даже если в результате экспериментов ты сотрешь со смартфона все содержимое всех разделов NAND-памяти, потеряв доступ и к Android, и к recovery.

Получив управление, u-boot проверяет таблицу разделов и передает управление ядру, прошитому в раздел с именем boot, после чего ядро извлекает в память RAM-образ из того же раздела и начинает загрузку либо Android, либо консоли восстановления. NAND-память в Android-устройствах поделена на шесть условно обязательных разделов:

•    boot — содержит ядро и RAM-диск, обычно имеет размер в районе 16 Мб;

•    recovery — консоль восстановления, состоит из ядра, набора консольных приложений и файла настроек, размер 16 Мб;

•    system — содержит Android, в современных девайсах имеет размер не менее 1 Гб;

INFO

В терминологии Linux RAM-диск — это своего рода виртуальный жесткий диск, существующий только в оперативной памяти. На раннем этапе загрузки ядро извлекает содержимое диска из образа и подключает его как корневую файловую систему (rootfs).

•    cache — предназначен для хранения кешированных данных, также используется для сохранения прошивки в ходе OTA-обновления и поэтому имеет размер, сходный с размерами раздела system;

•    userdata — содержит настройки, приложения и данные пользователя, ему отводится все оставшееся пространство NAND-памяти;

•    misc — содержит флаг, определяющий, в каком режиме должна грузиться система: Android или recovery.

Кроме них, также могут существовать и другие разделы, однако общая разметка определяется еще на этапе проектирования смартфона и в случае u-boot зашивается в код загрузчика. Это значит, что:

1) таблицу разделов нельзя убить, так как ее всегда можно восстановить с помощью команды fastboot oem format;

2) для изменения таблицы разделов придется разлочить и перепрошить загрузчик с новыми параметрами. Из этого правила, однако, бывают исключения. Например, загрузчик того же Rockchip (прочитать об устройствах на чипе Rockchip) хранит информацию о разделах в первом блоке NAND-памяти, так что для ее изменения перепрошивка загрузчика не нужна.

Особенно интересен раздел misc. Существует предположение, что изначально он был создан для хранения различных настроек независимо от основной системы, но в данный момент используется только для одной цели: указать загрузчику, из какого раздела нужно грузить систему — boot или recovery. Эту возможность, в частности, использует приложение ROM Manager для автоматической перезагрузки системы в recovery с автоматической же установкой прошивки. На ее же основе построен механизм двойной загрузки Ubuntu Touch, которая прошивает загрузчик Ubuntu в recovery и позволяет управлять тем, какую систему грузить в следующий раз. Стер раздел misc — загружается Android, заполнил данными — загружается recovery… то есть Ubuntu Touch.

static struct partition partitions [] = {

{ 128 },

{ «xloader», 128 >,

{ «bootloader», 256 >,

/* «misc» partition is required for recovery */

{ «misc», 128 },

Часть кода загрузчика, определяющая таблицу разделов

ШАГ ВТОРОЙ. РАЗДЕЛ BOOT

Если в разделе misc не стоит флаг загрузки в recovery, u-boot передает управление коду, расположенному в разделе boot. Это не что иное, как ядро Linux; оно находится в начале раздела, а сразу за ним следует упакованный с помощью архиваторов cpio и gzip образ RAM-диска, содержащий необходимые для работы Android каталоги, систему инициализации init и другие инструменты. Никакой файловой системы на разделе boot нет, ядро и RAM-диск просто следуют друг за другом. Содержимое RAM-диска такое:

•    data — каталог для монтирования одноименного    раздела;

•    dev — файлы устройств;

•    proc — сюда монтируется procfs;

•    sbin — набор подсобных утилит и демонов (adbd,    например);

•    res — набор изображений для charger (см. ниже);

•    sys — сюда монтируется sysfs;

•    system — каталог для монтирования системного раздела;

•    charger — приложение для отображения процесса зарядки;

•    build.prop — системные настройки;

•    init — система инициализации;

•    init.rc — настройки системы инициализации;

•    ueventd.rc — настройки демона uventd, входящего в состав init.

Это, если можно так выразиться, скелет системы: набор каталогов для подключения файловых систем из разделов NAND-памяти и система инициализации, которая займется всей остальной работой по загрузке системы. Центральный элемент здесь — приложение init и его конфиг init.rc, о которых во всех подробностях я расскажу позже. А пока хочу обратить внимание на файлы charger и ueventd.rc, а также каталоги sbin, proc и sys.

Файл charger — это небольшое приложение, единственная задача которого в том, чтобы вывести на экран значок батареи. Он не имеет никакого отношения к Android и используется тогда, когда устройство подключается к заряднику в выключенном состоянии. В этом случае загрузки Android не происходит, а система просто загружает ядро, подключает RAM-диск и запускает charger. Последний выводит на экран иконку батареи, изображение которой во всех возможных состояниях хранится в обычных PNG-файлах внутри каталога res.

Файл ueventd.rc представляет собой конфиг, определяющий, какие файлы устройств в каталоге sys должны быть созданы на этапе загрузки системы. В основанных на ядре Linux системах доступ к железу осуществляется через специальные файлы внутри каталога dev, а за их создание в Android отвечает демон ueventd, являющийся частью init. В нормальной ситуации он работает в автоматическом режиме, принимая команды на создание файлов от ядра, но некоторые файлы необходимо создавать самостоятельно. Они перечислены в ueventd.rc.

Каталог sbin в стоковом Android обычно не содержит ничего, кроме adbd, то есть демона ADB, который отвечает за отладку системы с ПК. Он запускается на раннем этапе загрузки ОС и позволяет выявить возможные проблемы на этапе инициализации ОС. В кастомных прошивках в этом каталоге можно найти кучу других файлов, например mke2fs, которая может потребоваться, если разделы необходимо переформатировать в ext3/4. Также модеры часто помещают туда BusyBox, с помощью которого можно вызвать сотни Linux-команд.

INFO

В процессе загрузки Android отображает три разных загрузочных экрана: первый появляется сразу после нажатия кнопки питания и прошит в ядро Linux, второй отображается на ранних этапах инициализации и записан в файл / initlogo.rle (сегодня почти не используется), последний запускаетсяс помощью приложения bootanimation и содержится в файле /system/media/ bootanimation.zip.

Каталог proc для Linux стандартен, на следующих этапах загрузки init подключит к нему procfs, виртуальную файловую систему, которая предоставляет доступ к информации обо всех процессах системы. К каталогу sys система подключит sysfs, открывающую доступ к информации о железе и его настройкам.

С помощью sysfs можно, например, отправить устройство в сон или изменить используемый алгоритм энергосбережения.

Файл build.prop предназначен для хранения низкоуровневых настроек Android. Позже система обнулит эти настройки и перезапишет их значениями из недоступного пока файла system/build.prop.

kornevoj-razdel-ouya

Корневой раздел ТВ-приставки OUYA (что такое OUYA читайте здесь )

konfig-init.rc-cyanogenmod

Часть конфига init.rc из CyanogenMod

ШАГ ВТОРОЙ, АЛЬТЕРНАТИВНЫЙ. РАЗДЕЛ RECOVERY

В том случае, если флаг загрузки recovery в разделе misc установлен или пользователь включил смартфон с зажатой клавишей уменьшения громкости, u-boot передаст управление коду, расположенному в начале раздела recovery.

Как и раздел boot, он содержит ядро и RAM-диск, который распаковывается в память и становится корнем файловой системы. Однако содержимое RAM-диска здесь несколько другое.

В отличие от раздела boot, выступающего в роли переходного звена между разными этапами загрузки ОС, раздел recovery полностью самодостаточен и содержит миниатюрную операционную систему, которая никак не связана с Android. У recovery свое ядро, свой набор приложений (команд) и свой интерфейс, позволяющий пользователю активировать служебные функции.

В стандартном (стоковом) recovery таких функций обычно всего три: установка подписанных ключом производителя смартфона прошивок, вайп и перезагрузка. В модифицированных сторонних recovery, таких как ClockworkMod и TWRP, функций гораздо больше. Они умеют форматировать файловые системы, устанавливать прошивки, подписанные любыми ключами (читай: кастомные), монтировать файловые системы на других разделах (в целях отладки ОС) и включают в себя поддержку скриптов, которая позволяет автоматизировать процесс прошивки и многие другие функции.

С помощью скриптов, например, можно сделать так, чтобы после загрузки recovery автоматически нашел на карте памяти нужные прошивки, установил их и перезагрузился в Android. Эта возможность используется инструментами ROM Manager, autoflasher, а также механизмом автоматического обновления CyanogenMod и других прошивок.

Кастомные рекавери также поддерживают скрипты бэкапа, располагающиеся в каталоге /system/addon.d/. Перед прошивкой recovery проверяет наличие скриптов и выполняет их перед тем, как произвести прошивку. Благодаря таким скриптам

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *