این صفحه تغییرات اضافه شده به AOSP را برای کاهش تغییرات غیرضروری فایل بین بیلدها توضیح می دهد. پیادهکنندههای دستگاهی که سیستمهای ساخت خود را حفظ میکنند، میتوانند از این اطلاعات به عنوان راهنمایی برای کاهش اندازه بهروزرسانیهای خارج از هوا (OTA) خود استفاده کنند.
بهروزرسانیهای Android OTA گهگاه حاوی فایلهای تغییر یافتهای هستند که با تغییرات کد مطابقت ندارند. آنها در واقع مصنوعات سیستمی را می سازند. این می تواند زمانی اتفاق بیفتد که همان کد، ساخته شده در زمان های مختلف، از دایرکتوری های مختلف، یا در ماشین های مختلف، تعداد زیادی فایل تغییر یافته را تولید کند. چنین فایلهای اضافی اندازه یک پچ OTA را افزایش میدهند و تعیین کد تغییر کرده را دشوار میکنند.
برای شفافتر کردن محتویات یک OTA، AOSP شامل تغییرات سیستمی است که برای کاهش اندازه وصلههای OTA طراحی شدهاند. تغییرات غیرضروری فایل بین ساختها حذف شده است و فقط فایلهای مرتبط با پچ در بهروزرسانیهای OTA وجود دارند. AOSP همچنین شامل یک ابزار build diff است که تغییرات رایج فایل مربوط به ساخت را فیلتر می کند تا تفاوت فایل ساختی تمیزتر را ارائه دهد و یک ابزار نقشه برداری بلوک که به شما کمک می کند تخصیص بلوک را ثابت نگه دارید.
یک سیستم ساخت می تواند به روش های مختلف وصله های بزرگ غیر ضروری ایجاد کند. برای کاهش این مشکل، در اندروید 8.0 و بالاتر، ویژگیهای جدیدی برای کاهش اندازه پچ برای هر تفاوت فایل پیادهسازی شد. بهبودهایی که اندازه بستههای بهروزرسانی OTA را کاهش داد، شامل موارد زیر است:
- استفاده از ZSTD ، یک الگوریتم فشرده سازی بدون تلفات با هدف عمومی برای تصاویر کامل در به روز رسانی دستگاه های غیر A/B. ZSTD را می توان با افزایش سطح فشرده سازی برای نسبت تراکم بالاتر سفارشی کرد. سطح فشرده سازی در طول زمان تولید OTA تنظیم می شود و می توان با عبور از پرچم
--vabc_compression_param=zstd,$COMPRESSION_LEVEL
تنظیم کرد. - افزایش اندازه پنجره فشرده سازی استفاده شده در طول OTA. حداکثر اندازه پنجره فشردهسازی را میتوان با سفارشیسازی پارامتر ساخت در فایل
.mk
دستگاه تنظیم کرد. این متغیر به عنوانPRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144
تنظیم شده است - استفاده از فشردهسازی مجدد Puffin ، یک ابزار اصلاحی قطعی برای تخلیه جریانها، که عملکردهای فشردهسازی و تفاوت را برای تولید بهروزرسانی A/B OTA انجام میدهد.
- تغییراتی در استفاده از ابزار نسل دلتا، مانند نحوه استفاده از کتابخانه
bsdiff
برای فشردهسازی وصلهها. در اندروید 9 و بالاتر، ابزارbsdiff
الگوریتم فشردهسازی را انتخاب میکند که بهترین نتایج فشردهسازی را برای یک پچ ارائه میدهد. - هنگامی که وصلهها برای بهروزرسانیهای دستگاه A/B اعمال میشوند، بهبودهایی در
update_engine
منجر به مصرف کمتر حافظه میشود.
بخشهای زیر موضوعات مختلفی را مورد بحث قرار میدهند که بر اندازههای بهروزرسانی OTA، راهحلهای آنها و نمونههایی از پیادهسازی در AOSP تأثیر میگذارند.
سفارش فایل
مشکل : وقتی از فایلهای موجود در فهرستی درخواست میشود، فایلسیستمها ترتیب فایل را تضمین نمیکنند، اگرچه معمولاً برای همان پرداخت یکسان است. ابزارهایی مانند ls
نتایج را به طور پیشفرض مرتب میکنند، اما تابع wildcard که توسط دستوراتی مانند find
و make
استفاده میشود مرتبسازی نمیشوند. قبل از استفاده از این ابزارها، باید خروجی ها را مرتب کنید.
راه حل : وقتی از ابزارهایی مانند find
and make
با تابع wildcard استفاده می کنید، خروجی این دستورات را قبل از استفاده مرتب کنید. هنگام استفاده از $(wildcard)
یا $(shell find)
در فایل های Android.mk
، آنها را نیز مرتب کنید. برخی از ابزارها، مانند جاوا، ورودیها را مرتب میکنند، بنابراین قبل از مرتبسازی فایلها، بررسی کنید که ابزاری که استفاده میکنید قبلاً این کار را انجام نداده باشد.
مثالها: بسیاری از نمونهها در سیستم ساخت هسته با استفاده از ماکرو داخلی all-*-files-under
، که شامل all-cpp-files-under
میشود، ثابت شدند (همانطور که تعاریف متعددی در سایر فایلهای ساخته شده منتشر شد). برای جزئیات به ادامه مطلب مراجعه کنید:
- https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f
- https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410
- https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653
- https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c
ساخت دایرکتوری
مشکل: تغییر دایرکتوری که در آن چیزها ساخته شده اند می تواند باعث متفاوت شدن باینری ها شود. بیشتر مسیرها در ساخت اندروید مسیرهای نسبی هستند، بنابراین __FILE__
در C/C++ مشکلی نیست. با این حال، نمادهای اشکال زدایی به طور پیش فرض نام مسیر کامل را رمزگذاری می کنند، و .note.gnu.build-id
از هش کردن باینری از پیش جدا شده ایجاد می شود، بنابراین اگر نمادهای اشکال زدایی تغییر کنند، تغییر می کند.
راه حل: AOSP اکنون مسیرهای اشکال زدایی را نسبی می کند. برای جزئیات، به CL مراجعه کنید: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02 .
مهر زمانی
مشکل: مهرهای زمانی در خروجی ساخت منجر به تغییرات غیر ضروری فایل می شود. این احتمالاً در مکان های زیر رخ می دهد:
- ماکروهای
__DATE__/__TIME__/__TIMESTAMP__
در کد C یا C++. - مُهرهای زمانی تعبیه شده در آرشیوهای مبتنی بر zip.
راهحلها/مثالها: برای حذف مُهرهای زمانی از خروجی ساخت، از دستورالعملهای زیر در __DATE__/__TIME__/__TIMESTAMP__ در C/C++ استفاده کنید. و مُهرهای زمانی تعبیه شده در آرشیوها
__DATE__/__TIME__/__TIMESTAMP__ در C/C++
این ماکروها همیشه خروجی های متفاوتی برای ساخت های مختلف تولید می کنند، پس از آنها استفاده نکنید. در اینجا چند گزینه برای حذف این ماکروها وجود دارد:
- آنها را حذف کنید. برای مثال، به https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f مراجعه کنید.
- برای شناسایی منحصر به فرد باینری در حال اجرا، build-id را از هدر ELF بخوانید.
- برای اینکه بدانید چه زمانی سیستم عامل ساخته شده است،
ro.build.date
را بخوانید (این برای همه چیز کار می کند به جز ساخت های افزایشی، که ممکن است این تاریخ را به روز نکنند). برای مثال، به https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84 مراجعه کنید.
مهرهای زمانی تعبیه شده در آرشیوها (زیپ، شیشه)
اندروید 7.0 با اضافه کردن -X
به همه کاربردهای دستور zip
، مشکل زمانبندی جاسازی شده در بایگانیهای فشرده را برطرف کرد. با این کار UID/GID سازنده و مُهر زمانی Unix توسعه یافته از فایل فشرده حذف شد.
یک ابزار جدید به نام ziptime
(واقع در /platform/build/+/main/tools/ziptime/
) مُهرهای زمانی عادی را در هدرهای فشرده بازنشانی میکند. برای جزئیات، به فایل README مراجعه کنید.
ابزار signapk
مهرهای زمانی را برای فایلهای APK تنظیم میکند که ممکن است بسته به منطقه زمانی سرور متفاوت باشد. برای جزئیات، به CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028 مراجعه کنید.
ابزار signapk
مهرهای زمانی را برای فایلهای APK تنظیم میکند که ممکن است بسته به منطقه زمانی سرور متفاوت باشد. برای جزئیات، به CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028 مراجعه کنید.
رشته های نسخه
مشکل: رشتههای نسخه APK اغلب دارای BUILD_NUMBER
به نسخههای کدگذاریشده خود اضافه میشوند. حتی اگر هیچ چیز دیگری در APK تغییر نکرده باشد، در نتیجه APK همچنان متفاوت خواهد بود.
راه حل: شماره ساخت را از رشته نسخه APK حذف کنید.
مثال ها:
- https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27
- https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c
محاسبه صحت روی دستگاه را فعال کنید
اگر dm-verity در دستگاه شما فعال باشد، ابزار OTA به طور خودکار پیکربندی صحت شما را انتخاب میکند و محاسبه صحت روی دستگاه را فعال میکند. این به جای ذخیره شدن به عنوان بایت های خام در بسته OTA شما، امکان محاسبه بلوک های اعتبار را در دستگاه های اندرویدی فراهم می کند. بلوک های Verity می توانند تقریباً 16 مگابایت برای یک پارتیشن 2 گیگابایتی استفاده کنند.
با این حال، محاسبه صحت روی دستگاه میتواند زمان زیادی طول بکشد. به طور خاص، کد تصحیح خطای فوروارد ممکن است زمان زیادی طول بکشد. در دستگاههای پیکسل، حداکثر 10 دقیقه طول میکشد. در دستگاه های ارزان قیمت ممکن است بیشتر طول بکشد. اگر میخواهید محاسبه صحت روی دستگاه را غیرفعال کنید، اما همچنان dm-verity را فعال کنید، میتوانید این کار را با ارسال --disable_fec_computation
به ابزار ota_from_target_files
هنگام ایجاد بهروزرسانی OTA انجام دهید. این پرچم محاسبات صحت روی دستگاه را در طول بهروزرسانی OTA غیرفعال میکند. زمان نصب OTA را کاهش می دهد، اما اندازه بسته OTA را افزایش می دهد. اگر دستگاه شما dm-verity را فعال نکرده باشد، ارسال این پرچم هیچ تاثیری ندارد.
ابزارهای ساخت منسجم
مشکل: ابزارهایی که فایل های نصب شده را تولید می کنند باید سازگار باشند (یک ورودی داده شده باید همیشه خروجی یکسانی تولید کند).
راهحلها/مثالها: تغییراتی در ابزارهای ساخت زیر لازم بود:
- NOTICE سازنده فایل . ایجاد کننده فایل NOTICE برای ایجاد مجموعه های NOTICE قابل تکرار تغییر کرد. به CL مراجعه کنید: https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64 .
- کیت کامپایلر اندروید جاوا (جک) . زنجیره ابزار جک برای رسیدگی به تغییرات گاه به گاه در سفارش سازنده ایجاد شده به به روز رسانی نیاز داشت. دسترسیهای قطعی برای سازندهها به زنجیره ابزار اضافه شد: https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b .
- کامپایلر ART AOT (dex2oat) . باینری کامپایلر ART یک بهروزرسانی دریافت کرد که گزینهای برای ایجاد یک تصویر قطعی اضافه کرد: https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9 .
- فایل libpac.so (V8) . هر بیلد یک فایل
/system/lib/libpac.so
متفاوت ایجاد می کند زیرا عکس فوری V8 برای هر بیلد تغییر می کند. راه حل حذف عکس فوری بود: https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29 . - فایل های پیش از dexopt (.odex) برنامه . فایلهای پیش از dexopt (odex.) حاوی padding غیر اولیه در سیستمهای 64 بیتی بودند. این اصلاح شد: https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029 .
از ابزار build diff استفاده کنید
برای مواردی که امکان حذف تغییرات فایل مربوط به ساخت وجود ندارد، AOSP یک ابزار build diff به نام target_files_diff.py
برای استفاده در مقایسه دو بسته فایل دارد. این ابزار یک تفاوت بازگشتی بین دو بیلد انجام می دهد، به استثنای تغییرات رایج فایل مربوط به ساخت، مانند
- تغییرات مورد انتظار در خروجی ساخت (مثلاً به دلیل تغییر شماره ساخت).
- تغییرات به دلیل مشکلات شناخته شده در سیستم ساخت فعلی.
برای استفاده از ابزار build diff دستور زیر را اجرا کنید:
target_files_diff.py dir1 dir2
dir1
و dir2
دایرکتوری های پایه ای هستند که حاوی فایل های هدف استخراج شده برای هر ساخت هستند.
تخصیص بلوک را ثابت نگه دارید
برای یک فایل مشخص، اگرچه محتویات آن بین دو بیلد یکسان باقی میماند، بلوکهای واقعی که دادهها را نگه میدارند ممکن است تغییر کرده باشند. در نتیجه، بهروزرسانیکننده باید I/O غیرضروری را برای جابجایی بلوکها برای بهروزرسانی OTA انجام دهد.
در یک بهروزرسانی مجازی A/B OTA، I/O غیرضروری میتواند فضای ذخیرهسازی مورد نیاز برای ذخیره عکس فوری کپی در نوشتن را تا حد زیادی افزایش دهد. در یک بهروزرسانی غیرA/B OTA، جابجایی بلوکها برای بهروزرسانی OTA به زمان بهروزرسانی کمک میکند، زیرا به دلیل جابجایی بلوک، ورودی/خروجی بیشتری وجود دارد.
برای رفع این مشکل، گوگل در اندروید 7.0 ابزار make_ext4fs
را برای ثابت نگه داشتن تخصیص بلوک ها در بین ساخت ها گسترش داد. ابزار make_ext4fs
یک پرچم اختیاری -d base_fs
را میپذیرد که سعی میکند فایلها را در هنگام تولید یک تصویر ext4
به همان بلوکها اختصاص دهد. میتوانید فایلهای نگاشت بلوک (مانند فایلهای نقشه base_fs
) را از فایل فشرده فایلهای هدف ساخت قبلی استخراج کنید. برای هر پارتیشن ext4
، یک فایل .map
در دایرکتوری IMAGES
وجود دارد (برای مثال، IMAGES/system.map
مربوط به پارتیشن system
است). سپس میتوان این فایلهای base_fs
را از طریق PRODUCT_<partition>_BASE_FS_PATH
بررسی و مشخص کرد، مانند این مثال:
PRODUCT_SYSTEM_BASE_FS_PATH := path/to/base_fs_files/base_system.map PRODUCT_SYSTEM_EXT_BASE_FS_PATH := path/to/base_fs_files/base_system_ext.map PRODUCT_VENDOR_BASE_FS_PATH := path/to/base_fs_files/base_vendor.map PRODUCT_PRODUCT_BASE_FS_PATH := path/to/base_fs_files/base_product.map PRODUCT_ODM_BASE_FS_PATH := path/to/base_fs_files/base_odm.map
اگرچه این به کاهش اندازه کلی بسته OTA کمک نمی کند، اما با کاهش مقدار I/O، عملکرد به روز رسانی OTA را بهبود می بخشد. برای بهروزرسانیهای A/B مجازی، فضای ذخیرهسازی مورد نیاز برای اعمال OTA را به شدت کاهش میدهد.
از به روز رسانی برنامه ها خودداری کنید
علاوه بر به حداقل رساندن تفاوتهای ساخت، میتوانید اندازه بهروزرسانی OTA را با حذف بهروزرسانیهای برنامههایی که از طریق فروشگاههای برنامه بهروزرسانی دریافت میکنند، کاهش دهید. APK ها اغلب بخش قابل توجهی از پارتیشن های مختلف یک دستگاه را تشکیل می دهند. گنجاندن آخرین نسخههای برنامههایی که توسط فروشگاههای برنامه در بهروزرسانی OTA بهروزرسانی میشوند، ممکن است تأثیر بزرگی بر بستههای OTA داشته باشد و سود کمی برای کاربر ایجاد کند. تا زمانی که کاربران بسته OTA را دریافت کنند، ممکن است برنامه به روز شده یا حتی نسخه جدیدتر آن را مستقیماً از فروشگاه های برنامه دریافت کرده باشند.