Android 13 улучшит DSU — установка общей системы GSI в два раза быстрее
Динамическое обновление системы (DSU) — одна из малоизвестных функций Android. Эта функция позволяет пользователям устанавливать общий образ системы (GSI) без разблокировки загрузчика или установки системных обновлений. Это упрощает переключение между текущим образом системы и GSI. Впервые представленная в Android 10, эта функция является одним из самых простых способов для разработчиков протестировать последнюю версию Android 13. Согласно информации от технического эксперта Мишаала Рахмана, DSU получит улучшения в Android 13.

Новый коммит от AOSP Gerrit предполагает, что Google вносит заметные улучшения производительности в DSU. Установка GSI через DSU выполняется намного быстрее за счет увеличения общей памяти по умолчанию . Google отмечает, что небольшое увеличение объема памяти (с 8 КБ до 64 КБ) значительно ускорит динамическую установку системы как на физических, так и на виртуальных устройствах.
Тесты Google показывают, что время установки на физическом устройстве сокращается с 2 минут и 2 секунд до 45 секунд. Кроме того, время установки на виртуальное устройство сокращается с 45 до 30 секунд.
Кроме того, индикатор выполнения также получил некоторые новые улучшения. Во время установки GSI индикатор выполнения в центре уведомлений будет показывать устанавливаемый раздел . В текущей версии Android 13 отображается только «Установка». DSU также добавит поддержку образов system, system_ext и продуктов. Эти функции и улучшения пока недоступны в Android 13 Developer Preview.
Android 13 будет изначально поддерживать открытие нескольких карт eSIM на одном чипе.
Традиционные мобильные телефоны используют физическую карту (SIM-карту) для подключения к сотовой сети. Тем не менее, цифровая карта eSIM не развивается быстро, отчасти потому, что она не полностью совместима с Android. Согласно новому отчету Esper, Google может внедрить eSIM в Android 13 , чтобы повысить популярность этой технологии. Эспер сообщает, что кодовая база Android 13 содержит патент, поданный Google в 2020 году, который позволяет использовать несколько профилей SIM-карт на одном встроенном чипе .
Согласно патентному описанию, это достигается за счет разделения единой физической шины данных между модемом и чипом eSIM на несколько логических интерфейсов, которые затем объединяются в один физический интерфейс. Это похоже на то, что современные ЦП разделяют физические ядра ЦП на логические ядра ЦП для одновременного выполнения большего количества задач. В отличие от физической SIM-карты, которая должна быть оснащена слотом, для eSIM требуется только небольшой компонент на материнской плате, что оставляет больше места для размещения в телефоне более крупных аккумуляторов, оборудования камеры или других компонентов. Однако не многие телефоны полностью отказались от физического слота для SIM-карты.
Интересные видео
Белоснежка в законе. Веселая сказка на пару минут
В городском королевстве проживала королева, известная своей красотой и жаждой подтверждения своего величия. Ее воле было подвластно волшебное зеркало, которое отвечало на ее вопросы. Но однажды зеркало объявило, что истинной красавицей королевства является не она, а приемная дочь Белоснежка.
Динамические и модульные обновления Android

Эта статья рассказывает о ряде технологий, которые были интегрированы в Android в последние несколько лет и приблизили решение проблемы фрагментации, отсутствия обновлений и существенно упростили создание кастомных прошивок.
A/B-разметка
Большой проблемой с обновлениями является отказ пользователей. Как показывает практика, многие владельцы смартфонов не хотят обновлять свои устройства, потому что: а) это отнимает время, в течение которого смартфон будет недоступен для использования; б) после обновления смартфон может работать некорректно или не включится вообще.
В свое время разработчики Chrome OS также столкнулись с этой проблемой и создали надежную и незаметную пользователю систему бесшовного обновления (Seamless updates). Суть ее состоит в том, что вместо одного системного раздела, поверх которого накладывались бы обновления системы, Chrome OS использует два идентичных системных раздела, каждый из которых содержит свою копию операционной системы.
Обновление в Chrome OS происходит следующим образом: когда ОС обнаруживает наличие обновления, она скачивает его в фоне, устанавливает на второй (неактивный) системный раздел и помечает этот раздел как активный. После перезагрузки (не обязательно сразу после обновления) ОС запускается уже с этого раздела.
Благодаря такой схеме пользователь даже не подозревает, что система обновилась, он просто попадает в обновленную ОС после перезагрузки или включения ноутбука. При этом Chrome OS способна гарантировать, что после обновления пользователь не получит кирпич: если во время загрузки с обновленного раздела произойдет сбой — система пометит текущий раздел флагом unbootable, сделает активным «старый» системный раздел и загрузит заведомо рабочую версию ОС.
Начиная с седьмой версии Android также поддерживает бесшовные обновления и так называемую A/B-разметку разделов. Однако, так как системных разделов в устройствах с Android намного больше, чем в хромбуках, сама раскладка разделов получается более запутанной. Вот только часть разделов, которые пришлось дублировать:
- boot — содержит ядро и RAM-диск, на устройствах с A/B-разметкой также консоль восстановления (recovery);
- system — содержит Android, системные библиотеки, системные приложения, стандартные рингтоны, обои и так далее;
- vendor — драйверы и все необходимые прослойки для работы с железом (Project Treble);
- userdata — настройки, приложения и данные пользователя;
- radio — прошивка радиомодуля (поддержка сотовых сетей);
- vbmeta — раздел Android Verified Boot 2.0 (механизм доверенной загрузки), содержащий контрольные суммы компонентов системы.
Всего дублированных разделов может быть несколько десятков. Например, на OnePlus 6 с A/B-разметкой общее количество разделов — 72 и несколько десятков из них используются только загрузчиком.
От других разделов, наоборот, стало возможным отказаться. Устройства с A/B-разметкой не включают в себя отдельный раздел recovery (консоль восстановления, нужна для установки обновления и сброса до заводских настроек) и раздел cache , который использовался для хранения файлов обновлений (теперь обновление скачивается напрямую в неактивный раздел).

A/B-разметка также позволила вдвое сократить размер раздела system , что вкупе с удалением разделов recovery и cache сделало переход на новую схему разметки менее болезненным. Например, на смартфонах Pixel потеря пространства составила всего несколько сотен мегабайт.
| Раздел | Размер A/B | Размер A-only |
|---|---|---|
| Bootloader | 50 Мбайт × 2 | 50 Мбайт |
| Boot | 32 Мбайт × 2 | 32 Мбайт |
| Recovery | 0 | 32 Мбайт |
| Cache | 0 | 100 Мбайт |
| Radio | 70 Мбайт × 2 | 70 Мбайт |
| Vendor | 300 Мбайт × 2 | 300 Мбайт |
| System | 2048 Мбайт × 2 | 4096 Мбайт |
| Всего | 5000 Мбайт | 4680 Мбайт |
Еще одно достоинство A/B-разметки — отсутствие экрана «Android is upgrading…» после обновления. Система просто загружается как обычно. Также A/B-разметка упрощает тестирование кастомных прошивок: кастом можно поставить второй системой и откатиться на первую, если что-то пойдет не так.
В целом одни плюсы и никаких минусов. Проблема только в том, что A/B-разметка до сих пор остается опциональной, а перешли на нее далеко не все производители смартфонов. Даже Samsung — крупнейший производитель устройств на Android — до сих пор использует старую разметку. И связано это, скорее всего, с нежеланием тратить средства и время на перепрофилирование уже работающей и отлаженной системы обновления.
Проверить, поддерживает ли твой смартфон A/B-разметку, можно с помощью все того же приложения Treble Check из предыдущего раздела или прочитав переменную ro . build . ab_update с помощью ADB:
$ adb shell getprop ro . build . ab_update
Шпаргалка по управлению A/B-разделами с помощью fastboot
Узнать, какой слот (группа разделов) теперь активен:
$ fastboot getvar all | grep “ current — slot ”
Сделать неактивный в данный момент слот активным:
$ fastboot set_active other
Сделать активным указанный слот (a или b):
$ fastboot set_active СЛОТ
Прошить указанный раздел:
$ fastboot flash имя _ раздела _a partition . img
$ fastboot flash имя _ раздела _b partition . img
Динамические обновления
Project Treble открыл дорогу для еще одной весьма полезной функции — Dynamic System Updates (DSU). Этот механизм появился в Android 10 специально для пользователей и разработчиков, которые хотят протестировать новую (бета) версию Android, но не желают жертвовать для этого установленной системой и своими данными.
DSU базируется на технологии Dynamic Partitions, которая должна быть реализована во всех устройствах, выпущенных на рынок с Android 10. При использовании Dynamic Partitions в смартфоне, по сути, есть только один суперраздел, в котором система может создавать динамические разделы, удалять их и менять размеры (такое возможно благодаря модулю ядра Linux dm-linear).
Все системные разделы в таком смартфоне тоже динамические (кроме загрузочных разделов: boot, dtbo и vbmeta). Поэтому при необходимости система может сдвинуть их, чтобы освободить место для дополнительных разделов. Именно так делает функция DSU. Она уменьшает размер системных разделов, создает в освободившемся пространстве еще один набор системных разделов и устанавливает в него образ GSI. Далее смартфон перезагружается в эту свежеустановленную систему, а следующая перезагрузка выполняется вновь со стандартных разделов.
Чтобы установить образ GSI, используя DSU, для начала необходимо разблокировать загрузчик смартфона. Затем активировать DSU с помощью ADB:
$ adb shell setprop persist . sys . fflag . override . settings_dynamic_system true
Затем нужно скачать сам образ, распаковать и закинуть его на внутреннюю карту памяти смартфона:
$ gzip — c system_raw . img > system_raw . gz
$ adb push system_raw . gz / storage / emulated / 0 / Download /
Затем можно запустить установку:
$ adb shell am start — activity \
— n com . android . dynsystem / com . android . dynsystem . VerificationActivity \
— a android . os . image . action . START_INSTALL \
— d file : ///storage/emulated/0/Download/system_raw.gz \
— el KEY_SYSTEM_SIZE $ ( du — b system_raw . img | cut — f1 ) \
— el KEY_USERDATA_SIZE 8589934592
После окончания установки в шторке появится уведомление с предложением перезагрузиться.

Сложно, не правда ли? Именно поэтому в Android 11 появилась функция под названием DSU Loader. Она позволяет автоматически загрузить и установить образ GSI в пару кликов.
В текущих сборках Android 11 DSU Loader требует разблокированный загрузчик. Однако к релизу стабильной версии Google планирует убрать это ограничение.

Виртуальная A/B-разметка
Кроме возможности временной установки официальных сборок GSI, механизм DSU также позволил реализовать еще одну весьма интересную функцию — Virtual A/B.
Мы уже рассматривали преимущества новой A/B-разметки и то, какие проблемы она может решить. Однако ввиду потери пространства, которое может принести с собой A/B-разметка на устройствах с ограниченным объемом NAND-памяти, а также проблем с миграцией Google не спешит заставлять производителей смартфонов использовать новую разметку.
Вместо этого они создали виртуальную A/B-разметку. Работает она примерно так же, как динамические обновления, только без отката на ранее установленную прошивку: когда смартфон обнаруживает новое OTA-обновление, он создает несколько дополнительных системных разделов для новой прошивки, скачивает в них обновление, а затем делает эти разделы активными (как и в случае с A/B-разметкой). После следующей перезагрузки смартфон загружается уже с новых разделов; если загрузка проходит успешно, то старые разделы удаляются, а освобожденное ими место отдается разделу userdata.
Виртуальная A/B-разметка будет обязательной для всех устройств, вышедших на рынок с Android 11.
Модульные обновления
Еще один шаг в решении проблемы с обновлениями — Project Mainline. Это внедренная в Android 10 подсистема, позволяющая обновлять куски Android в обход производителя устройства.
В центре новой подсистемы — пакетный менеджер APEX, очень похожий на тот, что используется в дистрибутивах Linux и новой операционке Google Fuchsia. Работает он примерно так: допустим, по очередному указу правительства в России вновь меняют часовые пояса. Команда разработчиков Android формирует новую версию пакета с часовыми поясами и выкладывает ее в Google Play. Пользователи получают обновление — все счастливы.

Таким же образом могут быть обновлены библиотеки и целые подсистемы. Уже сейчас в AOSP доступны пакеты с рантаймом ART («виртуальная машина», ответственная за запуск приложений), библиотека криптографических алгоритмов Conscrypt, набор мультимедийных кодеков, мультимедийный фреймворк, DNS-резолвер, интерфейс Documents UI, Permission Controller, ExtServices, данные часовых поясов, ANGLE (прослойка для трансляции вызовов OpenGL ES в OpenGL, Direct3D 9/11, Desktop GL и Vulkan) и Captive Portal Login. В теории в пакет APEX можно упаковать практически любой компонент системы, и пользователи смогут обновить его независимо от производителя смартфона.
Интересно, что APEX не производит обновление «на живую», когда старый компонент заменяется новым. Раздел / system в Android недоступен для записи, поэтому APEX использует трюк с монтированием. Все обновляемые файлы внутри пакета APEX находятся в образе файловой системы ext4. Когда пакет «устанавливается», система монтирует этот образ поверх раздела / system в режиме bind. В результате файлы пакета как бы заменяют оригинальные файлы Android, хотя в реальности все остается на своих местах.
Такой же трюк использует Magisk для установки модификаций Android без изменения раздела / system . И его автор уже сказал, что APEX станет проблемой для Magisk.

Трюк с сохранением пространства
Внимательно прочитав раздел «A/B-разметка», ты мог заметить, что экономия пространства при такой разметке в основном достигается за счет сокращения размера раздела system в два раза. И дело здесь вовсе не в том, что при A/B-разметке используется какая-то специализированная сборка Android, а в отказе от «лишних» файлов.
В классическом варианте разметки системный раздел содержит в себе не только саму операционную систему, но и так называемые файлы odex. Они представляют собой оптимизированные (пропущенные через AOT-компилятор) версии dex-файлов, которые, в свою очередь, содержат код приложения.
Файлы odex позволяют сократить время старта приложения и повысить его производительность. Они могут быть созданы тремя путями:
- преинсталлированы на устройство (в классическом варианте разметки — в раздел system);
- сгенерированы динамически во время использования приложения или простоя устройства;
- загружены из Google Play вместе с самим приложением.
Отсутствие файлов odex может серьезно испортить пользовательский экспириенс от первого запуска смартфона (время загрузки может составить несколько минут вместо десятков секунд), поэтому они необходимы сразу. С другой стороны, они занимают примерно половину всего пространства раздела system, а если этот раздел продублировать, то потеря пространства станет существенной.
Именно поэтому разработчики отказались от предустановки файлов odex в активный системный раздел, а вместо этого залили их в неактивный системный раздел вместо копии операционной системы. Так что жизненный цикл смартфона с A/B-разметкой выглядит так:
- При выпуске с конвейера раздел system_a активный, содержит файлы операционной системы, раздел system_b неактивный, содержит файлы odex.
- Во время первого запуска система копирует файлы odex в раздел userdata .
- После получения первого OTA-обновления система записывает обновление в раздел system_b , далее запускает генерацию файлов odex (инструмент dex2oat) для новой версии ОС (они также записываются в userdata) и после ее завершения помечает раздел system_b (все разделы слота B) как активный.
- После перезагрузки смартфон загружает операционную систему с раздела system_b , используя сгенерированные на третьем этапе файлы odex.
Выводы
A/B-разметка и динамические разделы — одни из самых интересных и полезных технологий, появившихся в Android в последние пять лет. В теории с их помощью можно реализовать мультизагрузку, создавать разделы для любых подсобных задач и полностью менять таблицу разделов устройства, выкинув все лишнее. Проблема только в том, что без разлочки загрузчика и кастомной прошивки все это будет недоступно.
APEX, с другой стороны, в теории может решить большинство проблем с обновлением смартфонов. Однако, в отличие от дистрибутивов Linux и ОС Fuchsia, пакеты APEX больше напоминают костыль, чем уместное инженерное решение. С другой стороны — лучше так, чем никак.
DSU Loader — что это и зачем нужно в смартфоне?
Принцип работы функции DSU Loader в режиме разработчика на телефоне.
Режим разработчика на смартфоне необходим для более детальных настроек мобильного телефона, но не все его функции понятны простому пользователю. Расскажем, что такое «DSU Loader», за что эта функция отвечает и нужно ли ее активировать.
Что такое DSU Loader в смартфоне?
Один из пунктов меню для разработчиков, который часто вызывает вопросы у пользователей, называется DSU Loader. Эта функция полноценно была введена в версии Android 11 и расшифровывается как «Dynamic System Updates» или «динамическое обновление системы». Задача этой функции — установить на смартфон системный образ новой ОС (GSI), который включает как саму операционную систему, так и настройки, конфигурации и все программы, установленные на нее.
Простыми словами, DSU Loader позволяет временно протестировать новую версию Android без полной перепрошивки устройства. При этом текущая версия ОС, а также фирменная оболочка производителя остаются нетронутыми и не подвергаются никакому риску. После того, как пользователь ознакомится со всеми функциями новой версии Android, он сможет так же легко вернуться к своей старой ОС — для этого понадобится всего лишь перезагрузить смартфон.
DSU Loader максимально упрощает процесс тестирования новой версии Android как для разработчиков приложений, так и для простых пользователей, которые хотят ознакомиться со свежей ОС и ее функциями, чтобы решить, стоит ли она полноценной установки. И если раньше для подобного теста требовалось использование команд ADB или Fastboot, то с появлением функции DSU Loader для установки необходимо всего несколько нажатий.
Как активировать DSU Loader на смартфоне?
Возможность установить и протестировать новую версию ОС появится, только если соблюдены несколько факторов:
- Системный образ ОС должен быть подписан Google или производителем смартфона.
- Функция DSU Loader должна быть добавлена в настройки смартфона производителем мобильного устройства.
Функция доступна на большинстве современных телефонов, а найти ее можно в режиме для разработчиков. Для этого его необходимо активировать, нажав на номер сборки устройства 5-7 раз — этот пункт находится в разделе «О телефоне».
Далее в основном меню настроек нужно найти пункт «Для разработчиков» (он может находиться в разделе «Дополнительные» или «Расширенные» настройки) и среди настроек найти строку DSU Loader. Теперь остается выбрать один из предложенных образов в зависимости от архитектуры устройства и установить его, следуя инструкции. Чтобы вернуться к исходной ОС, достаточно перезагрузить смартфон.
Рекомендуем почитать:
- Android System Intelligence — что это и зачем нужно?
- Почему желтеет экран телефона и что делать?
- Отладка по Wi-Fi в режиме разработчика — что это и зачем нужно?
- Телефон вибрирует сам по себе (без причины) — почему и что делать?
- Использование памяти приложениями — что есть полезного в этом разделе?
Установите GSI на Android через DSU Loader
В этом руководстве мы покажем вам, как установить GSI на ваше устройство Android с помощью DSU Loader, без использования каких-либо команд ADB или Fastboot или даже TWRP! [Click to Skip the Theory and Directly go to the Instructions Part]. С появлением устройств Project Treble в архитектуре Android произошли серьезные изменения. Google разделил фреймворк и реализацию поставщика.
Следовательно, поставщику больше не нужно было обновляться при каждом новом обновлении ОС, а OEM-производителю нужно было только искать часть платформы. Это значительно ускорило весь процесс развертывания ОС, поскольку ранее OEM-производителям приходилось ждать, пока производители наборов микросхем внесут необходимые изменения в поставщика, прежде чем они могли фактически развернуть обновление. Но теперь это время ожидания прошло.
Следовательно, OEM-производители теперь могут напрямую проверить, правильно ли реализован Project Treble, просто загрузив подписанный файл общего образа системы. И это то, что привело к появлению ПЗУ GSI, которые мы знаем сегодня! Тем не менее, он больше не ограничивается разработчиками в целях тестирования, теперь все техническое сообщество получает выгоду от этих ПЗУ GSI, поскольку они могут получить последнюю версию ОС в первый же день.
Что ж, на этот раз мы получили Android 12 Beta GSI еще до того, как Google анонсировала первое бета-обновление в I/O! С учетом сказанного, все еще есть некоторые сомнения относительно установки этих ПЗУ. Уже нет. Сегодня мы покажем вам, как установить GSI на ваше Android-устройство с помощью DSU Loader, без использования каких-либо команд ADB или Fastboot или пользовательского восстановления, такого как TWRP. Следуйте вместе. [ALSO READ: How to Go Back to Stock ROM from GSI ROM].
Программы для Windows, мобильные приложения, игры — ВСЁ БЕСПЛАТНО, в нашем закрытом телеграмм канале — Подписывайтесь:)
Что такое динамические обновления системы (DSU) в Android

Прежде чем мы перечислим инструкции, я настоятельно рекомендую вам понять всю концепцию, стоящую за всем этим. В Android 10 Google впервые представил DSU. Это позволило разработчикам временно установить ПЗУ GSI без использования команд Fastboot, протестировать свои приложения, а затем вернуться к стандартной ОС.
При загрузке GSI ROM через GSU на вашем устройстве были созданы новые и временные системные разделы и разделы данных, которые хранятся внутри раздела /data/gsi. В результате DSU загрузит эти разделы, а не исходные, и ваше устройство будет загружено с установленным GSI. Но откуда у нашего устройства было место для создания этих дополнительных разделов?
Что ж, Google обязал каждое устройство, запущенное с Android 10, иметь логические разделы, которые могут динамически изменять свой размер во время загрузки. Поэтому, если ваше устройство поставляется с Android 10 из коробки, вы сможете установить GSI на свое устройство Android с помощью этого загрузчика DSU. Давайте теперь проверим, как этого можно достичь.
Как установить GSI на Android через загрузчик DSU без команд ADB Fastboot или TWRP
Загрузчик DSU в Android 10 не был полностью отполирован. В результате вам, возможно, придется воспользоваться помощью команд Fastboot. Однако с Android 11 все снова в порядке, и вам не нужна команда Fastboot или пользовательское восстановление для установки ПЗУ GSI через DSU. Таким образом, вы получите наилучший результат, если вы в настоящее время используете Android 11 и хотите попробовать файл Android 12 GSI.
Кроме того, вам даже не нужно вручную искать и загружать файл GSI. DSU автоматически сделает все за вас и перечислит все GSI, совместимые только с вашим устройством и архитектурой процессора. Таким образом, вы можете быть уверены в его совместимости. На этой ноте давайте теперь ознакомимся с инструкциями по установке GSI на ваше устройство Android с помощью DSU Loader.
Шаги инструкции
- Для начала вам нужно включить параметры разработчика на вашем устройстве. Итак, перейдите в «Настройки»> «О телефоне»> «Семь раз нажмите на номер сборки»> «Вернитесь в «Настройки»> «Система»> «Дополнительно»> «Параметры разработчика»> «Включить отладку по USB».

- На данный момент вам также понадобится разблокированный загрузчик. Однако. в будущем Google планирует снять и это требование. Это имеет смысл, поскольку мы устанавливаем только GSI, предоставленный и подписанный Google. Так что проблем с безопасностью как таковых не будет. И в конце концов, кому бы не понравилась возможность прошивать ПЗУ при заблокированном загрузчике! Поэтому сделайте полную резервную копию устройства и обратитесь к нашему руководству: Как разблокировать загрузчик любого устройства Android.
- Теперь перейдите в «Параметры разработчика» и прокрутите до параметра «Загрузчик DSU». Убедитесь, что вы подключены к Интернету.

- Теперь Google выполнит поиск и выведет все поддерживаемые ПЗУ GSI для вашего устройства. Выберите любой из ваших вариантов [see Note below].
- Выбранный файл GSI будет загружен на ваше устройство. После этого перейдите на панель уведомлений и нажмите «Перезагрузить». Теперь ваше устройство загрузится с только что установленным GSI.

ПРИМЕЧАНИЕ. Вы можете увидеть два разных пакета для ПЗУ, один будет называться GSI, а другой — GSI+GSM, так в чем между ними разница? Что ж, GSI не поставляется с какими-либо приложениями, службами и инфраструктурой Google, тогда как GSI+GSM имеет все предустановленные приложения Google, поэтому вы можете выбрать то, которое соответствует вашим требованиям.
Заключение
Все это было из этого руководства о том, как установить GSI на ваше устройство Android с помощью DSU Loader, без использования каких-либо команд ADB или Fastboot или TWRP Recovery. Это определенно упростило прошивку универсальных образов системы на наши устройства. Это связано с тем, что метод быстрой загрузки требует довольно много усилий и также сопряжен с осложнениями.
К ним относятся прошивка пустого файла vbmeta, стирание системного раздела (что чаще всего приводит к большему количеству проблем), а затем прошивка необходимого GSI. Однако с DSU перепрошивка теперь выполняется одним щелчком мыши (или, скорее, касанием). А с развитием того, что нам даже не нужно будет разблокировать загрузчик, чтобы прошить GSI через DSU, это может вскоре стать популярным выбором для масс. Каковы ваши взгляды на то же самое? Дайте нам знать в разделе комментариев ниже.
