اگر بخواهیم Boot یک گوشی Android را واقعاً بفهمیم، بهتر است فعلاً Android را کنار بگذاریم.
در چند لحظه اولِ روشن شدن دستگاه نه Linux اجرا شده، نه فایل سیستم /system وجود دارد و نه چیزی از Zygote یا Framework خبری است.
همه چیز از لایه ای بسیار پایین تر شروع می شود.
مسیر کلی که در این مقاله دنبال می کنیم ساده است:
Power
↓
CPU starts
↓
Boot ROM ← موضوع اصلی این مقاله
↓
Early Bootloader
↓
Main Bootloader
↓
Linux Kernel
↓
Android
هدف این مقاله فقط فهمیدن همین شروع است: چه چیزی CPU را به حرکت درمی آورد، اولین کد کجاست، چرا داخل خود تراشه قرار گرفته و چگونه مرحله بعدی Boot را انتخاب می کند.
شروع ماجرا از SoC، قلب اصلی دستگاه
در یک گوشی، بسیاری از اجزایی که در یک کامپیوتر ممکن است روی چند تراشه جدا باشند، داخل یک تراشه اصلی جمع شده اند. به این تراشه SoC می گوییم.
SoC فقط CPU نیست. بسته به طراحی دستگاه می تواند شامل Memory Controller، کنترلرهای USB و Storage، GPU، DSP و مجموعه ای از بخش های امنیتی و پردازنده های جانبی باشد.
بنابراین وقتی گوشی روشن می شود، داستان Boot از همین تراشه شروع می شود، نه از Android و نه حتی از Linux.
از فشردن دکمه پاور تا اجرای اولین دستور
با فشردن دکمه پاور، آی سی تغذیه (PMIC) و مدارهای مدیریت توان، ولتاژهای موردنیاز بخش های مختلف دستگاه را به ترتیب مناسب فعال می کنند. کلاک های لازم هم باید پایدار شوند.
تا وقتی این شرایط آماده نشده اند، CPU در وضعیت اولیه نگه داشته می شود و اجرای عادی کد را شروع نمی کند. وقتی سخت افزار آماده شد، چیزی که در مستندات معمولاً با عبارت Reset is released می بینیم اتفاق می افتد، یعنی پردازنده دیگر در حالت Reset نگه داشته نمی شود و اجازه پیدا می کند اجرای کد را از نقطه شروع تعریف شده برای آن SoC آغاز کند.
Power button
↓
Voltages become stable
↓
Clocks become ready
↓
Reset is released
↓
CPU starts executing code
جزئیات این نقطه شروع بین SoCها فرق دارد، اما اصل ماجرا ثابت است: CPU باید یک آدرس یا مسیر شروع از پیش تعریف شده داشته باشد تا اولین دستور را از آنجا بردارد.
Boot ROM، اولین Firmware داخل تراشه
اولین کدی که در این مرحله اجرا می شود داخل خود SoC قرار دارد. برای این مفهوم معمولاً از نام Boot ROM استفاده می کنیم.
Boot ROM کوچک، بسیار محدود و در استفاده عادی غیرقابل تعویض است. این کد قرار نیست Android را بالا بیاورد، فقط باید محیط را آن قدر آماده کند که سیستم بتواند به مرحله بعد برسد.
وظایف معمول Boot ROM را می توان در چند مورد خلاصه کرد:
- تشخیص مسیر یا منبع مناسب برای Boot
- آماده سازی حداقلی سخت افزار موردنیاز برای ادامه کار
- پیدا کردن و Load کردن مرحله بعدی Boot
- در صورت فعال بودن بوت امن، بررسی معتبر بودن مرحله بعدی پیش از اجرا
- و در بسیاری از SoCها، فراهم کردن یک مسیر بسیار سطح پایین برای Recovery یا Download
قرار گرفتن این کد داخل خود SoC اتفاقی نیست. اگر اولین مرحله Boot مثل یک فایل عادی روی UFS یا eMMC قابل تعویض بود، مهاجم می توانست همان نقطه شروع را تغییر دهد و پایه اعتماد تمام مراحل بعدی را از بین ببرد. به همین دلیل Boot ROM یک نقطه شروع کوچک و ثابت برای زنجیره Boot ایجاد می کند.
Boot ROM فقط مسیر عادی Boot را نمی شناسد
یکی از جذاب ترین بخش های این معماری این است که Boot ROM در بسیاری از پلتفرم ها فقط برای Boot عادی استفاده نمی شود. یک مسیر بسیار سطح پایین برای Recovery یا Download هم وجود دارد که حتی وقتی Android یا Bootloader اصلی دیگر بالا نمی آید، ممکن است هنوز قابل استفاده باشد.
Boot ROM
├─ Normal Boot
│ ↓
│ Next boot stage
│
└─ Low-level Recovery / Download
↓
Connection to PC
در Qualcomm این مسیر سطح پایین معمولاً با نام EDL شناخته می شود. در MediaTek نیز خود BROM می تواند وارد Download Mode شود.
این همان دلیلی است که گاهی یک گوشی کاملاً Brick شده هیچ تصویری روی صفحه ندارد و Fastboot هم بالا نمی آید، اما کامپیوتر هنوز آن را به عنوان یک دستگاه Qualcomm در EDL یا یک دستگاه MediaTek در BROM Mode تشخیص می دهد.
روی بعضی بردها، تعمیرکارها از نقاط مشخصی روی PCB که با نام Test Point شناخته می شوند استفاده می کنند. اتصال موقت یک Test Point خاص هنگام روشن شدن دستگاه می تواند شرایط اولیه Boot را تغییر دهد و SoC را به جای مسیر عادی وارد یک Mode سطح پایین مثل EDL یا BROM کند.
به همین دلیل عکس محل Test Point مدل های مختلف بین تعمیرکارها ردوبدل می شود: هدف این است که حتی وقتی Bootloader عادی از دسترس خارج شده، راه ارتباط با SoC دوباره باز شود.
Test Point یک روش عمومی و یکسان برای همه گوشی ها نیست. محل پدها و رفتارشان کاملاً به مدل و طراحی برد وابسته است و اتصال اشتباه می تواند به سخت افزار آسیب بزند. همچنین ورود به EDL یا BROM به معنی دور زدن امنیت نیست، دستگاه ممکن است همچنان فقط Loader یا Download Agent امضاشده و مورداعتماد را قبول کند.
🔍 عمیق تر بشویم: چرا یک Test Point می تواند مسیر Boot را عوض کند؟
SoC هنگام Power-on یا Reset بعضی سیگنال های سخت افزاری را نمونه برداری می کند. این سیگنال ها می توانند روی انتخاب Boot source، Recovery mode یا رفتار اولیه پلتفرم اثر بگذارند.
در بعضی بردها Test Point به یکی از همین مسیرها یا به سیگنالی مرتبط با Storage/Boot متصل است. تغییر موقت وضعیت آن می تواند باعث شود Boot ROM مرحله عادی بعدی را اجرا نکند و وارد مسیر Recovery شود.
این رفتار کاملاً Board-specific است و برای تحلیل یا تعمیر هر دستگاه باید نقشه و رفتار همان مدل را در نظر گرفت.
بوت امن، موضوع فقط بارگذاری و اجرای مرحله بعد نیست باید قابل اعتماد هم باشد
در دستگاهی که بوت امن فعال است، پیدا کردن مرحله بعدی کافی نیست. Boot ROM باید قبل از اجرای آن مطمئن شود Image موردنظر معتبر است و از زنجیره مورداعتماد سازنده آمده است.
برای این کار SoC به یک Root of Trust نیاز دارد، یعنی اطلاعاتی که از قبل و در سطح سخت افزار مورداعتماد است. بخشی از این اطلاعات می تواند در eFuse یا OTP تثبیت شده باشد.
Hardware Root of Trust
↓
Boot ROM
↓
Verify next boot image
↓
Valid → execute
Invalid → stop / recovery policy
به این ترتیب Boot ROM دو کار را هم زمان انجام می دهد: مرحله بعد را پیدا می کند و در دستگاه امن بررسی می کند که همان مرحله ای باشد که سیستم اجازه اجرای آن را می دهد.
🔍 عمیق تر بشویم: eFuse، Signature و زنجیره اعتماد
در یک پیاده سازی معمول، Image مرحله بعد دارای Signature و گاهی Certificate chain است. Boot ROM برای Image یک Hash محاسبه می کند و Signature را با Public Key مورداعتماد بررسی می کند.
Hash یا مشخصات Root Public Key می تواند در eFuse/OTP تثبیت شده باشد. اگر زنجیره اعتماد معتبر باشد، Image اجازه اجرا پیدا می کند، در غیر این صورت سیاست امنیتی دستگاه تعیین می کند Boot متوقف شود یا وارد مسیر Recovery شود.
Boot ROM عمداً کوچک است، مرحله بعد باید امکانات بیشتری بسازد
Boot ROM نباید به یک Bootloader بزرگ و پیچیده تبدیل شود. هرچه کد داخل ROM بیشتر باشد، احتمال خطای غیرقابل اصلاح هم بیشتر می شود. به همین دلیل فقط حداقل امکانات در آن قرار می گیرد.
در لحظات خیلی ابتدایی حتی DRAM اصلی دستگاه ممکن است هنوز آماده استفاده نباشد. SoC می تواند ابتدا از مقدار محدودی SRAM داخلی استفاده کند و یک Stage کوچک تر را Load کند. آن Stage بعدی می تواند DRAM، Storage، کلاک ها و بخش های بیشتری از پلتفرم را آماده کند.
Boot ROM
↓
Small early boot stage
↓
DRAM and storage become usable
↓
Richer bootloader environment
↓
Linux Kernel
این همان دلیل اصلی چندمرحله ای بودن Boot در گوشی های مدرن است: هر مرحله فقط به اندازه ای محیط را آماده می کند که مرحله بعد بتواند با امکانات بیشتری ادامه دهد.
یک لایه امنیتی که در پشت صحنه باقی می ماند
برای دنبال کردن مسیر اصلی Boot لازم نیست همین جا وارد جزئیات معماری امنیتی ARM شویم. فقط یک نکته ارزش نگه داشتن دارد: بعضی Firmwareهای امنیتی بعد از پایان Boot هم در حافظه باقی می مانند و سرویس های سطح پایین را ارائه می کنند.
🔍 عمیق تر بشویم: Exception Level، TEE و TF-A در ARM
در پردازنده های 64 بیتی ARMv8-A و جدیدتر، سطوح دسترسی با مفهوم Exception Level بیان می شوند. Applicationها در سطح پایین تر اجرا می شوند، Linux Kernel معمولاً در Non-secure EL1 قرار دارد و Secure Firmware می تواند در سطوح بالاتر نقش داشته باشد.
EL3 Secure firmware / Secure Monitor
↓
EL2 Hypervisor
↓
EL1 Linux Kernel
↓
EL0 Applications
TrustZone نیز امکان جداسازی Normal World از Secure World را فراهم می کند. یک TEE می تواند سرویس هایی مثل Secure Storage، DRM یا نگهداری کلیدهای حساس را در Secure World ارائه کند.
TF-A یکی از پروژه های مهم این حوزه است. در مدل TF-A، BL31 معمولاً Runtime Firmware سطح EL3 است و BL32 می تواند یک Secure Payload مثل OP-TEE باشد. این اجزا می توانند بعد از بالا آمدن Linux هم resident بمانند.
این نام ها به مدل TF-A مربوط اند و نباید آنها را نام ثابت Stageهای تمام Qualcommها یا MediaTekها در نظر گرفت.
نام های متفاوت، ایده مشترک
تا اینجا عمداً بیشتر درباره مفهوم عمومی Boot ROM صحبت کردیم. Vendorها برای پیاده سازی خود نام های متفاوتی دارند. در بسیاری از Qualcommها اولین مرحله ROM با نام PBL شناخته می شود، در MediaTek معمولاً اصطلاح BROM یا BootROM را می بینیم.
خانواده های دیگری مثل Samsung Exynos، Google Tensor، HiSilicon Kirin و UNISOC هم وجود دارند. در این مجموعه Qualcomm و MediaTek را با جزئیات بیشتری دنبال می کنیم چون هم بسیار رایج اند و هم مسیرهای Boot و Recovery آنها در دنیای توسعه و تعمیرات اهمیت عملی زیادی دارند.
روشن شدن گوشی از Android شروع نمی شود. CPU ابتدا کدی بسیار کوچک و ثابت داخل SoC را اجرا می کند. این کد مسیر بعدی Boot را پیدا می کند، در دستگاه امن آن را اعتبارسنجی می کند و حتی می تواند یک مسیر سطح پایین برای Recovery فراهم کند. بعد از آن کنترل به Bootloaderهای کامل تر منتقل می شود.
واژه نامه کوتاه
- SoC
- System on Chip، تراشه اصلی که CPU و بخش های متعدد سیستم را در خود جای می دهد.
- Boot ROM
- کد اولیه و ثابت داخل SoC که Boot از آن آغاز می شود.
- PBL
- Primary Boot Loader، نام رایج اولین مرحله ROM در بسیاری از Qualcommها.
- BROM
- BootROM، نام رایج کد اولیه داخل SoC در MediaTek.
- EDL
- Emergency Download Mode، مسیر Recovery سطح پایین Qualcomm.
- SRAM
- حافظه سریع و محدود داخل SoC که در مراحل بسیار اولیه Boot قابل استفاده است.
- DRAM
- حافظه اصلی و پرظرفیت دستگاه که مراحل بعدی Boot آن را آماده می کنند.