در این مقاله Serviceهای پایه Binder Zygote system_server HAL و سخت افزار رسیدن به Home Screen

در مقاله قبل Kernel بالا آمد، init پارتیشن های Android را Mount کرد، SELinux آماده شد و second-stage init شروع به اجرای Serviceها کرد. اما هنوز چیزی که کاربر به عنوان Android می شناسد کامل نشده است.

در این مرحله باید سیستم ارتباط بین Processها، Android Runtime، Framework Serviceها و بخش گرافیکی بالا بیایند. بعد از آن است که Launcher می تواند روی صفحه ظاهر شود.

Android init
    ↓
native services
    ↓
Binder
    ↓
Zygote
    ↓
system_server
    ↓
Android Framework
    ↓
Launcher
    ↓
Home Screen

Serviceهای پایه قبل از Framework

init بر اساس فایل های rc مجموعه ای از Serviceهای Native را در زمان مناسب Start می کند. ترتیب دقیق بین نسخه ها و Deviceها فرق می کند، اما Serviceهایی برای Log، Storage، Graphics و Service management باید به تدریج بالا بیایند.

یکی از تفاوت های مهم این مرحله با Linux معمولی این است که Android بخش زیادی از سرویس های سطح بالا را روی سیستم IPC خودش یعنی Binder بنا کرده است.

Binder، ستون ارتباط داخلی Android

Android از Processهای زیادی ساخته شده که نباید همه آنها مستقیما به حافظه یکدیگر دسترسی داشته باشند. IPC لازم است تا این Processها بتوانند درخواست و پاسخ رد و بدل کنند.

Binder IPC اصلی Android است. Binder Driver در Kernel انتقال پیام را انجام می دهد و Service Manager کمک می کند Processها Serviceهای ثبت شده را پیدا کنند.

Client process
      ↓ Binder call
Binder driver
      ↓
Service process

بخش بزرگی از Android Framework روی همین مدل ساخته شده است. App به جای اینکه مستقیما Hardware یا Process دیگری را کنترل کند با یک Service صحبت می کند و Binder پیام را بین آنها منتقل می کند.

Zygote، کارخانه ساخت Processهای Android

یکی از مهم ترین Processهایی که init Start می کند Zygote است. Zygote محیط Android Runtime و مجموعه ای از Classها و Resourceهای عمومی را از قبل آماده می کند.

وقتی یک App جدید باید اجرا شود، لازم نیست Runtime از صفر ساخته شود. Zygote یک Process جدید Fork می کند و آن Process برای App موردنظر آماده می شود. این کار هم Startup را سریع تر می کند و هم امکان Share شدن بخشی از Memory را فراهم می کند.

init
  ↓
Zygote
  ├─ preload runtime / classes
  ├─ fork system_server
  └─ fork app processes
🛠 Zygote هنوز بخش اصلی Android است

بعضی توضیحات قدیمی یا ناقص این تصور را ایجاد می کنند که Zygote در Androidهای جدید کنار گذاشته شده است. در معماری فعلی Android هنوز Zygote ریشه Processهای System و App است و نقش مرکزی در ساخت Processها دارد.

🔍 عمیق تر بشویم، USAP Pool چه کمکی به Zygote می کند

Zygote می تواند تعدادی Process آماده ولی هنوز بدون هویت App مشخص بسازد که USAP نام دارند. وقتی App باید سریع اجرا شود یکی از این Processها Specialize می شود و به Process آن App تبدیل می شود.

Zygote
  ├─ fork on demand
  └─ USAP pool
       ├─ ready process
       ├─ ready process
       └─ specialize for app

USAP جای Zygote را نگرفته است، خود Zygote این Pool را مدیریت می کند.

system_server، جایی که بخش بزرگی از Framework زنده می شود

Zygote یکی از مهم ترین Processهای کل سیستم را Fork می کند که system_server نام دارد. system_server میزبان تعداد زیادی از Java Framework Serviceهای Android است.

Serviceهایی مثل Activity Manager، Package Manager، Power Manager و Window Manager در همین بخش یا در ارتباط نزدیک با آن بالا می آیند. بدون system_server دستگاه شاید Linux و حتی بخشی از Userspace را داشته باشد، اما Android Framework قابل استفاده نیست.

Zygote
   ↓ fork
system_server
   ├─ Activity Manager
   ├─ Package Manager
   ├─ Power Manager
   ├─ Window Manager
   └─ many other system services

در سورس فعلی Android، SystemServer Serviceها را در چند گروه اصلی Start می کند که با نام هایی مثل startBootstrapServices()، startCoreServices()، startOtherServices() و startApexServices() دیده می شوند. این تقسیم بندی یک جزئیات پیاده سازی است، چیزی که برای فهم مسیر مهم است بالا آمدن تدریجی Framework Serviceهاست.

Package Manager و Activity Manager، Appها وارد داستان می شوند

Package Manager اطلاعات Packageها، Permissionها و Componentهای نصب شده را آماده می کند. Android باید بداند چه Appهایی وجود دارند و هر App چه اجزایی دارد.

Activity Manager چرخه زندگی Processها و Componentهای App را هماهنگ می کند. وقتی Process جدیدی لازم باشد، Framework از Zygote برای ساخت آن استفاده می کند.

Framework چطور به Hardware واقعی می رسد

Framework نباید برای هر دوربین، مودم یا سنسور از کد مخصوص همان چیپ استفاده کند. Android برای جدا کردن Framework از پیاده سازی Hardware از HAL استفاده می کند.

Android Framework
      ↓
HAL interface
      ↓
Vendor implementation
      ↓
Kernel driver / hardware

Project Treble این مرز بین System و Vendor را استانداردتر کرد. در نسل های قدیمی تر HIDL نقش بزرگی در HALها داشت. در Android جدید برای HALهای جدید تا جای ممکن Stable AIDL ترجیح داده می شود، در حالی که HIDLهای موجود هنوز روی دستگاه های زیادی حضور دارند.

🔍 عمیق تر بشویم، HIDL و AIDL در یک نگاه

HIDL برای جداسازی System و Vendor در دوره اولیه Project Treble طراحی شد. Android بعدا Stable AIDL را برای HALها معرفی کرد و AOSP توصیه می کند Interfaceهای جدید در صورت امکان از AIDL استفاده کنند.

بنابراین دیدن HIDL روی یک گوشی به معنی قدیمی یا خراب بودن معماری نیست. HALهای موجود می توانند همچنان HIDL باشند، اما مسیر توسعه جدید بیشتر به سمت Stable AIDL رفته است.

Graphics، از Window Manager تا SurfaceFlinger

WindowManagerService وضعیت و Policy مربوط به Windowها را در Framework مدیریت می کند. در سطح Native، SurfaceFlinger Surfaceهای مختلف را Compose می کند تا تصویر نهایی برای Display ساخته شود.

نمایش Boot Animation نشان می دهد بخش بزرگی از Graphics stack بالا آمده است، اما لزوما به معنی آماده شدن کامل Framework نیست. ممکن است Animation دیده شود و system_server یا یکی از Serviceهای حیاتی هنوز مشکل داشته باشد.

آخرین مرحله قابل مشاهده، اجرای Launcher

وقتی Framework به اندازه کافی آماده شد، Android Activity مربوط به HOME را Resolve می کند. Launcher خودش یک App است. Process آن از مسیر Zygote ساخته می شود و Activity اصلی آن Home Screen را نمایش می دهد.

system_server ready enough
        ↓
resolve HOME activity
        ↓
Zygote creates Launcher process
        ↓
Launcher Activity starts
        ↓
HOME SCREEN

ظاهر شدن Home Screen یعنی زنجیره ای که از چند لحظه اول داخل Boot ROM شروع شد حالا به سطحی رسیده که Android Framework و App world قابل استفاده شده اند.

BOOT_COMPLETED و Unlock کاربر، Boot هنوز چند قدم دیگر دارد

بعد از رسیدن سیستم به Boot phase مناسب، Broadcastهایی مثل BOOT_COMPLETED برای Appهای مجاز ارسال می شوند. در دستگاهی که File Based Encryption دارد، بخشی از Data می تواند قبل از Unlock کاربر در دسترس باشد و بخش Credential Encrypted بعد از Unlock باز شود.

پس حتی بعد از دیدن Home Screen هم بعضی Serviceها یا Dataهای وابسته به Unlock کاربر می توانند کمی دیرتر آماده شوند.

کل مسیری که در این مجموعه طی کردیم

Power
 ↓
SoC ROM
 ↓
PBL / BROM
 ↓
Early Bootloaders
 ↓
Main Bootloader
 ↓
Secure Boot / AVB
 ↓
Boot Images
 ↓
Linux Kernel
 ↓
/init PID 1
 ↓
first-stage / second-stage init
 ↓
Binder / native services
 ↓
Zygote
 ↓
system_server
 ↓
Android Framework
 ↓
Launcher
 ↓
Home Screen
🛠 Boot failure حالا معنی بیشتری پیدا می کند

اگر فقط EDL یا BROM در دسترس باشد مشکل در سطح بسیار پایین است. اگر Fastboot کار کند Bootloader اصلی زنده است. اگر Kernel شروع شود ولی Android بالا نیاید مشکل می تواند در init، Mount یا Userspace باشد. اگر Boot Animation دیده شود بخش بزرگی از Graphics و Userspace شروع شده است. شناخت این زنجیره محل جستجوی مشکل را بسیار محدودتر می کند.

⭐ چیزی که از این مجموعه باید بماند

Android نتیجه یک Boot چند مرحله ای است. هیچ Stage به تنهایی همه کار را انجام نمی دهد. ROM اعتماد اولیه را می سازد، Bootloader سخت افزار و Imageها را آماده می کند، Kernel سیستم عامل را بالا می آورد، init Userspace Android را می سازد و Zygote و system_server Framework و App world را زنده می کنند.

واژه نامه کوتاه

Binder
سیستم IPC اصلی Android برای ارتباط کنترل شده بین Processها.
Zygote
Process اصلی Android Runtime که system_server و Processهای App را Fork می کند.
system_server
Process میزبان بخش بزرگی از Java Framework Serviceهای Android.
HAL
لایه Interface بین Android Framework و پیاده سازی Hardware توسط Vendor.
Launcher
App مربوط به HOME که صفحه اصلی Android را نمایش می دهد.

منابع رسمی برای مطالعه بیشتر