پیاده سازی bootconfig در اندروید 12

در اندروید ۱۲، ویژگی bootconfig جایگزین گزینه‌های androidboot.* kernel cmdline شده است که در اندروید ۱۱ و پایین‌تر استفاده می‌شوند. ویژگی bootconfig مکانیزمی برای انتقال جزئیات پیکربندی از build و bootloader به اندروید ۱۲ است.

این ویژگی راهی برای جداسازی پارامترهای پیکربندی فضای کاربری اندروید از پارامترهای مربوط به هسته فراهم می‌کند. انتقال پارامترهای طولانی androidboot.* هسته به فایل bootconfig، فضایی را در cmdline هسته ایجاد می‌کند و آن را برای توسعه‌های آینده در دسترس قرار می‌دهد.

هم هسته و هم فضای کاربری اندروید باید از bootconfig پشتیبانی کنند.

  • اولین نسخه‌ای که از این پشتیبانی می‌کند: اندروید ۱۲
  • اولین نسخه کرنل که از این پشتیبانی می‌کند: کرنل 12-5.4.xx

ویژگی bootconfig را برای دستگاه‌های جدیدی که با نسخه کرنل 12-5.10.xx راه‌اندازی می‌شوند، پیاده‌سازی کنید. اگر در حال ارتقاء دستگاه‌ها هستید، نیازی به پیاده‌سازی آن ندارید.

مثال‌ها و منابع

همانطور که مثال‌ها و کد منبع این بخش را مشاهده می‌کنید، توجه داشته باشید که قالب کد bootconfig تنها کمی با قالب cmdline هسته مورد استفاده در اندروید ۱۱ و پایین‌تر متفاوت است. با این حال، تفاوت زیر برای استفاده شما مهم است:

  • پارامترها باید با کاراکتر escape sequence \n از هم جدا شوند، نه با فاصله.

مثال بوت لودر

برای مثالی از یک بوت‌لودر، به پیاده‌سازی بوت‌لودر مرجع Cuttlefish U-boot مراجعه کنید. دو کامیت در مرجع در زیر فهرست شده‌اند. اولین کامیت، پشتیبانی از نسخه هدر بوت را به آخرین نسخه ارتقا می‌دهد. در این مثال، کامیت اول، پشتیبانی از نسخه را به نسخه بعدی، یعنی v4، به‌روزرسانی (یا ارتقا) می‌کند. دومی دو کار انجام می‌دهد؛ مدیریت بوت‌کانفیگ را اضافه می‌کند و افزودن پارامترها را در زمان اجرا نشان می‌دهد:

مثال ساخت

برای مثالی از ساخت که تغییرات mkbootimg را برای ساخت vendor_boot.img با هدر بوت vendor نسخه ۴ نشان می‌دهد، به mkbootimg changes for bootconfig مراجعه کنید. برای انجام موارد زیر، به تغییرات Cuttlefish مراجعه کنید:

پیاده‌سازی

شرکا باید پشتیبانی را به بوت‌لودرهای خود اضافه کنند و پارامترهای androidboot.* زمان ساخت خود را از cmdline هسته به فایل bootconfig منتقل کنند. بهترین راه برای پیاده‌سازی این تغییر، انجام تدریجی آن است؛ برای اطلاعات بیشتر در مورد پیروی از یک فرآیند تدریجی، به بخش پیاده‌سازی و اعتبارسنجی تدریجی مراجعه کنید.

اگر تغییراتی دارید که فایل /proc/cmdline را برای androidboot.* جستجو می‌کنند، آنها را به فایل /proc/bootconfig ارجاع دهید. ویژگی‌های ro.boot.* با مقادیر جدید bootconfig تنظیم شده‌اند، بنابراین نیازی به ایجاد تغییرات در کد با استفاده از آن ویژگی‌ها ندارید.

تغییرات را بسازید

ابتدا، نسخه هدر بوت خود را به نسخه ۴ ارتقا دهید:

- BOARD_BOOT_HEADER_VERSION := 3

+ BOARD_BOOT_HEADER_VERSION := 4

پارامتر bootconfig kernel cmdline را اضافه کنید. این باعث می‌شود هسته به دنبال بخش bootconfig بگردد:

BOARD_KERNEL_CMDLINE += bootconfig

پارامترهای bootconfig از پارامترهای موجود در متغیر BOARD_BOOTCONFIG ایجاد می‌شوند، دقیقاً مانند cmdline هسته که از BOARD\_KERNEL\_CMDLINE ایجاد می‌شود.

هر پارامتر androidboot.* را می‌توان به همان صورت که هست، مشابه موارد زیر، منتقل کرد:

- BOARD_KERNEL_CMDLINE += androidboot..selinux=enforcing

+ BOARD_BOOTCONFIG += androidboot..selinux=enforcing

تغییرات بوت لودر

بوت لودر قبل از پرش به هسته، initramfs تنظیم می‌کند. پیکربندی بوت هسته به دنبال بخش bootconfig می‌گردد و آن را در انتهای initramfs, همراه با تریلر مورد انتظار، جستجو می‌کند.

بوت لودر اطلاعات طرح بندی vendor_boot.img را از هدر تصویر بوت فروشنده دریافت می‌کند.

نمودار طرح تخصیص حافظه bootconfig

شکل 1. تخصیص حافظه bootconfig اندروید 12

بوت‌لودر بخش bootconfig را در حافظه ایجاد می‌کند. بخش bootconfig شامل تخصیص حافظه برای موارد زیر است:

  • پارامترها
  • parameters size اندازه 4 B
  • ۴ parameters checksum
  • رشته جادویی پیکربندی بوت ۱۲ بیتی ( #BOOTCONFIG\n )

پارامترها از دو منبع می‌آیند: پارامترهایی که در زمان ساخت شناخته شده‌اند، و پارامترهایی که در زمان ساخت شناخته نشده‌اند. پارامترهای ناشناخته باید اضافه شوند.

پارامترهای شناخته شده در زمان ساخت، در انتهای تصویر vendor_boot در بخش bootconfig بسته‌بندی می‌شوند. اندازه این بخش (به صورت بایت) در فیلد هدر boot فروشنده vendor_bootconfig_size ذخیره می‌شود.

پارامترهایی که در زمان ساخت شناخته نشده‌اند، فقط در زمان اجرا در بوت‌لودر شناخته می‌شوند. این پارامترها باید قبل از اعمال تریلر بوت‌کانفیگ، به انتهای بخش پارامترهای بوت‌کانفیگ اضافه شوند.

اگر بعد از اعمال تریلر bootconfig نیاز به اضافه کردن پارامتری داشتید، تریلر را بازنویسی کرده و دوباره آن را اعمال کنید.

پیاده‌سازی و اعتبارسنجی افزایشی

ویژگی bootconfig را به صورت تدریجی و با دنبال کردن فرآیند ارائه شده در این بخش پیاده‌سازی کنید. پارامترهای cmdline هسته را دست نخورده باقی بگذارید تا پارامترهای bootconfig اضافه شوند.

مراحل پیاده‌سازی افزایشی به همراه اعتبارسنجی به شرح زیر است:

  1. بوت لودر را بسازید و تغییرات را ایجاد کنید، سپس موارد زیر را انجام دهید:
    1. از متغیر BOARD_BOOTCONFIG برای اضافه کردن یک پارامتر bootconfig جدید استفاده کنید.
    2. پارامترهای cmdline هسته را به همان شکلی که هستند نگه دارید تا دستگاه بتواند به درستی بوت شود. این کار اشکال‌زدایی و اعتبارسنجی را بسیار آسان‌تر می‌کند.
  2. با بررسی محتویات /proc/bootconfig کار خود را تأیید کنید . مطمئن شوید که پارامتر تازه اضافه شده را پس از بوت شدن دستگاه مشاهده می‌کنید.
  3. پارامترهای androidboot.* را با استفاده از متغیر BOARD_BOOTCONFIG و بوت لودر، از cmdline هسته به bootconfig منتقل کنید .
  4. تأیید کنید که هر یک از پارامترها در /proc/bootconfig وجود دارند و در /proc/cmdline نیستند . اگر بتوانید این را تأیید کنید، پیاده‌سازی شما موفقیت‌آمیز بوده است.

ملاحظات ارتقاء و تنزل رتبه OTA

وقتی که ارتقا و دانگرید OTA را بین نسخه‌های مختلف اندروید یا نسخه‌های مختلف کرنل مدیریت می‌کنید، باید دقت ویژه‌ای داشته باشید.

اندروید ۱۲ اولین نسخه‌ای است که از bootconfig پشتیبانی می‌کند. در صورت بازگشت به هر نسخه قبل از آن، باید از پارامترهای cmdline هسته به جای bootconfig استفاده شود.

نسخه‌های کرنل ۱۲ تا ۵.۴ و بالاتر از bootconfig پشتیبانی می‌کنند. در صورت بازگشت به هر نسخه‌ای قبل از آن (از جمله ۱۱ تا ۵.۴)، باید از پارامترهای cmdline کرنل استفاده شود.

ارتقا از اندروید ۱۱ و پایین‌تر به اندروید ۱۲ و بالاتر می‌تواند همچنان از پارامترهای cmdline هسته استفاده کند. همین امر در مورد ارتقاء نسخه‌های هسته نیز صدق می‌کند.

عیب‌یابی

وقتی مرحله تأیید را انجام می‌دهید، اگر پارامترهای مورد انتظار را در /proc/bootconfig نمی‌بینید، لاگ‌های هسته را در logcat بررسی کنید. اگر هسته از bootconfig پشتیبانی کند، همیشه یک ورودی لاگ برای آن وجود دارد.

مثال خروجی لاگ

$ adb logcat | grep bootconfig
02-24 17:00:07.610     0     0 I Load bootconfig: 128 bytes 9 nodes

اگر گزارش خطایی مشاهده کردید، یعنی مشکلی در بارگذاری bootconfig وجود داشته است. برای مشاهده انواع مختلف خطا، به فایل init/main.c مراجعه کنید.