Як влаштована операційна система Андроїд

Ті, хто використовує iPhone давно, знають, як працювали ранні версії iOS. Фактично це була однозадачна операційка, яка дозволяла працювати в фоні або переривати роботу поточної програми тільки встановленим додаткам: ви читаєте книжку, вам дзвонять – книгочиталка згортається, і на екрані з’являється вікно дзвінка. А ось зворотна операція неможлива: книгочиталка не тільки не може перервати роботу інших додатків, але і буде вбита відразу після згортання.

Сенс існування такої системи, звичайно ж, в тому, щоб заощадити процесор, оперативну пам’ять, а також ресурс батареї. Завдяки їй (але не тільки) iPhone міг працювати швидко в умовах обмежених ресурсів і дуже дбайливо ставився до батареї.

Як влаштована операційна система Андроїд

Андроїд завжди працював інакше. Тут можна запустити безліч різних додатків і всі вони будуть залишатися в пам’яті і навіть зможуть працювати в фоні. Ви відкриваєте браузер, вводите адресу і, поки завантажується сторінка, запускаєте поштовий клієнт і читаєте листи. Все як на робочому столі, з тим винятком, що вам не потрібно піклуватися про закриття додатків, система зробить це сама, коли оперативна пам’ять підійде до кінця або її не вистачить для розміщення програми яку ви запускаєте (само собою, в першу чергу в витрата підуть рідко використовувані додатки ). Цей механізм називається lowmemorykiller.

Важливим елементом системи багатозадачності були служби (service). Це особливі компоненти додатків, які могли працювати в фоні абсолютно в будь-яких умовах: включений екран або вимкнений, згорнуто додаток або розгорнуто, службам плювати навіть на те, чи запущено батьківський додаток взагалі. Вони просто говорили: “Ей, Андроїд, мені потрібні ресурси процесора, я хочу зробити деякі розрахунки” – і отримувало ці ресурси. У термінології Android такий запит до системи називається wakelock (а якщо точніше – процесорний wakelock).

Однак підтримка такого потужного і корисного інструменту зіграла з Google злий жарт. З’явилася величезна кількість додатків, які плодили служби на кожен чих, постійно виконували якусь роботу і не давали смартфону спати. Встановивши на смартфон сотню додатків, користувач отримував кілька десятків служб, кожна з яких періодично щось робила (оновити стрічку твіттера, поки телефон спить, – це ж так важливо).

Справи йшли настільки плачевно, що китайські виробники, не обтяжені завданням зберегти сумісність з оригінальним Андроїд (це потрібно, якщо хочете встановлювати на свої смартфони Play Store), просто відключили в своїх смартфонах механізми підтримки життєвого циклу служб для несистемних додатків.


Просунуті користувачі йшли іншим шляхом: вони отримували права root і встановлювали додаток Greenify, яке дозволяло заморозити служби обраних додатків так, щоб їх вже ніхто не зміг розбудити. Існували й більш радикальні варіанти, наприклад знести весь софт, яким користуєшся рідше одного разу на добу.

Сама Google також робила певні дії для боротьби з «отруйними» службами. Великий крок в цьому напрямку був зроблений в Android 4.4, де з’явився інтелектуальний механізм, який визначав, чи не працює служба занадто багато часу і не сильно вона вантажить процесор, і, якщо це виявлялося так, прибивав її на місці і не давав запуститися. Навіть на перший погляд ця версія системи жила на батарейці помітно довше попередніх.

В Android 6.0 Google пішла ще далі і оснастила її механізмом Doze, який після певного часу неактивності смартфона (близько однієї години) перекладав його в спеціальний енергозберігаючий режим. Одна з особливостей цього режиму – заборона на wakelock, тобто ні додатки, ні служби просто не можуть розбудити смартфон, щоб виконати будь-яку роботу. На око Android 6.0 не став жити довше, так що невідомо, чи спрацював цей механізм взагалі.

І нарешті, в Android 8.0 Google пішла на радикальний крок – заборонила роботу фонових служб. Але з двома винятками:

Додаток в деяких випадках, наприклад коли воно знаходиться на екрані, може запускати служби, але Android приб’є їх після відходу додатки в сон.
Видимі користувачеві служби до сих пір дозволені. Це так званий foreground service, служба, яку видно в панелі повідомлень і має іконку в статусбаре.

Здавалося б, так, служби – це зло, але як тепер бути таким програмам, як протиугінний, яке повинно працювати непомітно у фоновому режимі? Або той же поштовий клієнт? Через необхідність періодично перевіряти пошту він повинен висіти в панелі повідомлень?

Насправді ні. Google йшла до заборони служб ще з версії 5.0, де з’явився так званий JobScheduler. Це спеціальна підсистема, яка дозволяє програмам попросити Android виконати ту чи іншу роботу в таке-то час або при виникненні такого-то події (підключення до інтернету, наприклад). І так, JobScheduler сильно нагадує аналогічну функцію з iOS.

Binder

Всупереч розхожій думці, Android з найперших версій використовував пісочниці для ізоляції додатків. І реалізовані вони були вельми цікавим чином. Кожна програма запускалася від імені окремого користувача Linux і, таким чином, мало доступ тільки до свого каталогу всередині / data / data.

Один з одним і з операційною системою додатки могли спілкуватися тільки через IPC-механізм Binder, який вимагав авторизації на виконання тієї чи іншої дії. Цей же механізм використовувався і для кілька інших цілей: з його допомогою система сповіщала додатки про системні події, таких як вхідний дзвінок, яке прийшло СМС, втиканіе зарядки і так далі. Додатки отримували повідомлення і могли на них відреагувати.


Ця особливість дала Android дуже широкі можливості автоматизації, про які ми знаємо завдяки таким програмам, як Tasker, Automate або Locale. Всі ці програми доступні і для Android 8, хіба що деякі небезпечні можливості, такі як включення / вимикання режиму польоту, тепер заборонені для використання звичайними програмами.

Система оповіщення базується на ІНТЕНТ (intent), спеціальному механізмі, реалізованому поверх Binder і призначеному для обміну інформацією між додатками (або ОС і додатками), а також запуску компонентів додатків. За допомогою ІНТЕНТ можна оповіщати додатки про події, попросити систему відкрити програму для обробки певних типів даних (наприклад, щоб відкрити певну сторінку в браузері, досить послати широкомовний Интент з посиланням на сторінку, і на нього відгукнуться всі додатки, здатні відображати веб-сторінки, або тільки дефолтовий браузер) або просто запустити компонент того чи іншого додатка. Наприклад, додатки в Android запускаються не безпосередньо, а за допомогою ІНТЕНТ.

На жаль, як і служби, ІНТЕНТ стали проблемою для Google і користувачів Android. Справа в тому, що широкомовні ІНТЕНТ, використовувані для повідомлення додатків про події, приходять відразу до всіх програм, які заявили, що здатні на них реагувати. А щоб додаток змогло зреагувати на Интент, його треба запустити. Картина виходить така: на смартфоні є двадцять додатків, які можуть реагувати на Интент android.net.conn.CONNECTIVITY_CHANGE, і при кожному підключенні до мережі і відключення від неї система запускає ці додатки, щоб вони змогли зреагувати на Интент. Як це позначається на енергоспоживанні – уявіть самі.

Google виправила це непорозуміння знову ж в Android 8.0. Тепер додатки можуть реєструвати обробники широкомовних ІНТЕНТ тільки під час своєї роботи (за невеликими винятками).

Сервіси Google

Google любить хизуватися тим, що Android – операційна система з відкритим вихідним кодом. Це, звичайно ж, не зовсім так. З одного боку, код Android дійсно відкритий, і саме тому ми маємо доступ до такої кількості різноманітних кастомних прошивок. З іншого боку, зібравши Android з офіційних початкових кодів, ви отримаєте систему без кількох важливих компонентів: 1) окремих драйверів, вихідні коди яких виробник ховає, як комерційну таємницю, 2) сервісів Google, які потрібні в першу чергу для отримання доступу до аккаунту, запуску Google Play і хмарного бекапа.

Сервіси Google (Google Mobile Services) також відповідають за багато інших речей, включаючи підтримку push-повідомлень, Instant Apps, Google Maps, доступ до календаря, позиціонування на основі стільникових вишок і Wi-Fi-роутера, механізм Smart Lock, що дозволяє розблокувати пристрій в залежно від деяких умов.

У сучасних версіях Android сервіси Google взяли на себе настільки велику частину роботи, що жити без них виявляється хоч і можливо, але дуже проблематично. А з ними теж невесело: мінімальний варіант пакету GApps (який містить лише сервіси Google і Google Play) важить більше 120 Мбайт, а самі сервіси славляться своєю любов’ю до оперативці і заряду батареї. А ще вони закриті, тобто про те, що вони можуть робити, знає тільки сама Google.
Саме тому на світ з’явився проект microG, завдання якого – відтворити найважливішу функціональність сервісів Google у відкритому коді. Уже зараз microG дозволяє отримати доступ до свого облікового запису, активувати push-повідомлення, доступ до карт Google і визначення місця розташування по стільникових вишок. І все це при розмірі в чотири мега і майже повній відсутності вимог до оперативці і ресурсу батареї.

У проекту є власна збірка прошивки LineageOS, яка з коробки включає в себе microG і всі необхідні для його роботи модифікації.

Ядро Linux і рантайм

Android заснований на ядрі Linux. Ядро керує ресурсами смартфона, в тому числі доступом до залозу, управлінням оперативної і постійної пам’яттю, запуском, зупинкою і перенесенням процесів між ядрами процесора і багатьма іншими завданнями. Як і в будь-який інший ОС, ядро ​​- це серце Android, центральна частина, без якої все інше розвалиться.

Наявність ядра Linux, а також частково сумісною зі стандартом POSIX середовища виконання (в першу чергу це бібліотека bionic, заснована на реалізації стандартної бібліотеки мови С з OpenBSD) робить Android сумісним з додатками для Linux. Наприклад, система аутентифікації wpa_supplicant, що застосовується для підключення до Wi-Fi-мереж, тут точно така ж, як в будь-якому дистрибутиві Linux. У ранніх версіях Android використовувався стандартний bluetooth-стек Linux під назвою bluez (пізніше його замінили реалізацією від Qualcomm під назвою Bluedroid). Тут навіть є своя консоль з набором стандартних UNIX / Linux-команд, реалізованих в наборі Toybox, спочатку створеному для вбудованих Linux-систем.

Більшість консольних додатків, написаних для Linux, можна перенести в Android простий перекомпиляцией за допомогою крос-компілятора (головне – використовувати статичну компіляцію, щоб не отримати конфлікт бібліотек), а маючи права root, на Android-девайс можна без всяких проблем запустити повноцінний Linux- дистрибутив. Один нюанс – доступ до нього можна буде отримати або тільки через консоль, або використовуючи VNC-з’єднання. Також існує проект Maru OS, що дозволяє використовувати смартфон в якості ПК на базі Debian при підключенні до монітора. Ту ж функцію обіцяє Samsung при підключенні своїх смартфонів до монітора за допомогою дока DeX.

Починаючи з версії 4.4 Android вміє використовувати систему примусового контролю доступу SELinux для захисту від злому і отримання прав root. SELinux розроблена Агентством національної безпеки США і, якщо не вдаватися в деталі, дозволяє обмежити застосування (в тому числі системні низькорівневі компоненти) в можливостях. І мова зовсім не про повноваження, які користувач надає додаткам, а про такі речі, як системні виклики і доступ до тих чи інших файлів, незважаючи на стандартні права доступу UNIX.

Серія вразливостей Stagefright, які вразили Android кілька років тому, дозволяла отримати контроль над пристроєм, просто змусивши користувача відкрити прийшла MMS або спеціальний файл в браузері. Проблема полягала в мультімедіафреймворке Stagefright, що містить відразу кілька вразливостей переповнення буфера. При відкритті спеціальним чином підготовленого мультімедіафайла експлоїт використовував уразливість і запускав на пристрої код від імені Stagefright (який працював під рутом).

Всі ці баги Google благополучно закрила, а також попрацювала над модулярізаціі коду фреймворка і його запуском в спеціальних доменах SELinux. Ці домени забороняють компонентам, відповідальним за обробку мультимедіа, використовувати більшу частину системних викликів Linux, включаючи системні виклики групи execve, які як раз і були причетні до запуску шкідливого коду.

Сьогодні SELinux використовується для захисту майже всіх системних компонентів Android. І це стало причиною різкого зниження кількості знайдених багів в Android. Але призвело до фокусування зломщиків на ядрі, а точніше тих самих закритих драйвери, аудит коду яких ніхто не проводив і безпеку яких не гарантована (а вона, як виявилося, знаходиться в жалюгідному стані).

Висновки

Android безумовно не сама стандартна ОС. Багато свої риси вона запозичила з операційної системи Inferno, до створення якої доклали руку розробники мови С, UNIX і Plan 9. А ці хлопці явно знали, що робили.

Якщо Вам сподобалась публікація, поділіться нею!

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *