ION ABI تغییر می کند

دستگاه‌هایی که هسته 4.14 و بالاتر را ارسال می‌کنند، تحت‌تأثیر بازسازی عمده ماژول هسته ION قرار می‌گیرند، که بسیاری از پیاده‌سازی لایه انتزاعی سخت‌افزار (HAL) تخصیص‌دهنده حافظه گرافیکی فروشنده (gralloc) برای تخصیص بافرهای حافظه مشترک فراخوانی می‌کنند. این صفحه راهنمایی در مورد انتقال کد فروشنده قدیمی به نسخه جدید ION ارائه می دهد و در مورد خرابی های احتمالی رابط باینری برنامه (ABI) در آینده بحث می کند.

درباره ION

ION بخشی از درخت مرحله‌بندی کار در حال انجام هسته بالادست است. در حین مرحله‌بندی، ABI فضای کاربر به هسته ION ممکن است بین نسخه‌های اصلی هسته شکسته شود. در حالی که خرابی‌های ION ABI مستقیماً بر برنامه‌های معمولی یا دستگاه‌هایی که قبلاً راه‌اندازی شده‌اند تأثیر نمی‌گذارد ، فروشندگانی که به نسخه‌های اصلی هسته جدید مهاجرت می‌کنند ممکن است با تغییراتی مواجه شوند که بر فراخوانی کد فروشنده به ION تأثیر بگذارد. علاوه بر این، زمانی که تیم سیستم‌های Android با upstream کار می‌کنند تا ION را از درخت مرحله‌بندی خارج کنند، ممکن است خرابی‌های ABI در آینده رخ دهد.

تغییرات اندروید 4.14

Kernel 4.12 به شدت کد هسته ION را بازسازی کرد و بخش‌هایی از ION را که با سایر چارچوب‌های هسته همپوشانی داشتند، پاکسازی و حذف کرد. در نتیجه، بسیاری از ioctl های قدیمی ION دیگر مرتبط نیستند و حذف شده اند.

حذف کلاینت ها و دسته های ION

قبل از کرنل 4.12، باز کردن /dev/ion یک کلاینت ION را اختصاص داد. ION_IOC_ALLOC ioctl یک بافر جدید اختصاص داد و آن را به عنوان یک دسته ION به فضای کاربر برگرداند (یک عدد صحیح مات که فقط برای مشتری ION که آن را اختصاص داده معنادار است). برای نگاشت بافرها در فضای کاربر یا به اشتراک گذاری آنها با سایر فرآیندها، دسته های ION به صورت fds dma-buf با استفاده از ION_IOC_SHARE ioctl دوباره صادر شدند.

در هسته 4.12، ION_IOC_ALLOC ioctl مستقیماً dma-buf fds را خروجی می‌دهد. حالت میانی دسته ION، همراه با تمام ioctlهایی که دستگیره های ION را مصرف یا تولید می کنند، حذف شده است. از آنجایی که dma-buf fds به کلاینت های ION خاصی متصل نیست، دیگر به ION_IOC_SHARE ioctl نیازی نیست و تمام زیرساخت های مشتری ION حذف شده است.

افزودن ioctlهای کش-همسویی

قبل از کرنل 4.12، ION یک ioctl ION_IOC_SYNC برای همگام سازی توصیفگر فایل با حافظه ارائه می کرد. این ioctl مستند ضعیف و غیر قابل انعطاف بود. در نتیجه، بسیاری از فروشندگان ioctls سفارشی را برای انجام نگهداری حافظه پنهان پیاده سازی کردند.

هسته 4.12 جایگزین ION_IOC_SYNC با DMA_BUF_IOCTL_SYNC ioctl تعریف شده در linux/dma-buf.h شد. DMA_BUF_IOCTL_SYNC را در ابتدا و انتهای هر دسترسی به CPU، با پرچم‌هایی که مشخص می‌کنند این دسترسی‌ها خواندن و/یا نوشتن هستند تماس بگیرید. اگرچه DMA_BUF_IOCTL_SYNC پرمخاطب تر از ION_IOC_SYNC است، اما به فضای کاربران کنترل بیشتری بر عملیات نگهداری حافظه پنهان می دهد.

DMA_BUF_IOCTL_SYNC بخشی از ABI پایدار هسته است و با تمام fds های dma-buf قابل استفاده است، خواه توسط ION تخصیص داده شده باشند یا نه.

انتقال کد فروشنده به android-4.12+

برای مشتریان فضای کاربری ، تیم سیستم‌های اندروید قویاً استفاده از فراخوان‌های ioctl() libion ​​را به جای کدگذاری باز تشویق می‌کنند. از اندروید 9، لیبیون به طور خودکار ION ABI را در زمان اجرا شناسایی می‌کند و سعی می‌کند هر گونه تفاوت بین هسته‌ها را پنهان کند. با این حال، هر توابع libion ​​که دسته‌های ion_user_handle_t را تولید یا مصرف می‌کند، بعد از کرنل 4.12 دیگر کار نمی‌کند. می‌توانید این توابع را با عملیات‌های معادل زیر در dma-buf fds جایگزین کنید، که روی تمام نسخه‌های هسته تا به امروز کار می‌کنند.

تماس قدیمی ion_user_handle_t فراخوانی معادل dma-buf fd
ion_alloc(ion_fd, …, &buf_handle) ion_alloc_fd(ion_fd, ..., &buf_fd)
ion_share(ion_fd, buf_handle, &buf_fd) N/A (این تماس با fds dma-buf مورد نیاز نیست)
ion_map(ion_fd, buf_handle, ...) mmap(buf_fd, ...)
ion_free(ion_fd, buf_handle) close(buf_fd)
ion_import(ion_fd, buf_fd, &buf_handle) N/A (این تماس با fds dma-buf مورد نیاز نیست)
ion_sync_fd(ion_fd, buf_fd)
If (ion_is_legacy(ion_fd))
    ion_sync_fd(ion_fd, buf_fd);
else
    ioctl(buf_fd, DMA_BUF_IOCTL_SYNC, ...);

برای کلاینت‌های درون هسته ، چون ION دیگر هیچ API رو به هسته صادر نمی‌کند، درایورهایی که قبلاً از API هسته ION درون هسته با ion_import_dma_buf_fd() استفاده می‌کردند باید برای استفاده از API dma-buf درون هسته با dma_buf_get() تبدیل شوند.

ION ABI آینده خراب می شود

قبل از اینکه بتوان ION را از درخت مرحله‌بندی خارج کرد، ممکن است نسخه‌های هسته آینده نیاز به شکستن مجدد ION ABI داشته باشند. تیم سیستم‌های اندروید انتظار ندارند این تغییرات روی دستگاه‌هایی که با نسخه اندروید بعدی راه‌اندازی می‌شوند تأثیر بگذارد، اما چنین تغییراتی ممکن است دستگاه‌هایی را که با نسخه‌های اندروید بعدی راه‌اندازی می‌شوند تحت تأثیر قرار دهد.

برای مثال، جامعه بالادستی پیشنهاد کرده است که گره /dev/ion منفرد را به چندین گره در هر هیپ (به عنوان مثال /dev/ion/heap0 ) تقسیم کند تا دستگاه‌ها بتوانند سیاست‌های SELinux مختلف را برای هر پشته اعمال کنند. اگر این تغییر در نسخه بعدی هسته اجرا شود، ION ABI را می شکند.

،

دستگاه‌هایی که هسته 4.14 و بالاتر را ارسال می‌کنند، تحت‌تأثیر بازسازی عمده ماژول هسته ION قرار می‌گیرند، که بسیاری از پیاده‌سازی لایه انتزاعی سخت‌افزار (HAL) تخصیص‌دهنده حافظه گرافیکی فروشنده (gralloc) برای تخصیص بافرهای حافظه مشترک فراخوانی می‌کنند. این صفحه راهنمایی در مورد انتقال کد فروشنده قدیمی به نسخه جدید ION ارائه می دهد و در مورد خرابی های احتمالی رابط باینری برنامه (ABI) در آینده بحث می کند.

درباره ION

ION بخشی از درخت مرحله‌بندی کار در حال انجام هسته بالادست است. در حین مرحله‌بندی، ABI فضای کاربر به هسته ION ممکن است بین نسخه‌های اصلی هسته شکسته شود. در حالی که خرابی‌های ION ABI مستقیماً بر برنامه‌های معمولی یا دستگاه‌هایی که قبلاً راه‌اندازی شده‌اند تأثیر نمی‌گذارد ، فروشندگانی که به نسخه‌های اصلی هسته جدید مهاجرت می‌کنند ممکن است با تغییراتی مواجه شوند که بر فراخوانی کد فروشنده به ION تأثیر بگذارد. علاوه بر این، زمانی که تیم سیستم‌های Android با upstream کار می‌کنند تا ION را از درخت مرحله‌بندی خارج کنند، ممکن است خرابی‌های ABI در آینده رخ دهد.

تغییرات اندروید 4.14

Kernel 4.12 به شدت کد هسته ION را بازسازی کرد و بخش‌هایی از ION را که با سایر چارچوب‌های هسته همپوشانی داشتند، پاکسازی و حذف کرد. در نتیجه، بسیاری از ioctl های قدیمی ION دیگر مرتبط نیستند و حذف شده اند.

حذف کلاینت ها و دسته های ION

قبل از کرنل 4.12، باز کردن /dev/ion یک کلاینت ION را اختصاص داد. ION_IOC_ALLOC ioctl یک بافر جدید اختصاص داد و آن را به عنوان یک دسته ION به فضای کاربر برگرداند (یک عدد صحیح مات که فقط برای مشتری ION که آن را اختصاص داده معنادار است). برای نگاشت بافرها در فضای کاربر یا به اشتراک گذاری آنها با سایر فرآیندها، دسته های ION به صورت fds dma-buf با استفاده از ION_IOC_SHARE ioctl دوباره صادر شدند.

در هسته 4.12، ION_IOC_ALLOC ioctl مستقیماً dma-buf fds را خروجی می‌دهد. حالت میانی دسته ION، همراه با تمام ioctlهایی که دستگیره های ION را مصرف یا تولید می کنند، حذف شده است. از آنجایی که dma-buf fds به کلاینت های ION خاصی متصل نیست، دیگر به ION_IOC_SHARE ioctl نیازی نیست و تمام زیرساخت های مشتری ION حذف شده است.

افزودن ioctlهای کش-همسویی

قبل از کرنل 4.12، ION یک ioctl ION_IOC_SYNC برای همگام سازی توصیفگر فایل با حافظه ارائه می کرد. این ioctl مستند ضعیف و غیر قابل انعطاف بود. در نتیجه، بسیاری از فروشندگان ioctls سفارشی را برای انجام نگهداری حافظه پنهان پیاده سازی کردند.

هسته 4.12 جایگزین ION_IOC_SYNC با DMA_BUF_IOCTL_SYNC ioctl تعریف شده در linux/dma-buf.h شد. DMA_BUF_IOCTL_SYNC را در ابتدا و انتهای هر دسترسی به CPU، با پرچم‌هایی که مشخص می‌کنند این دسترسی‌ها خواندن و/یا نوشتن هستند تماس بگیرید. اگرچه DMA_BUF_IOCTL_SYNC پرمخاطب تر از ION_IOC_SYNC است، اما به فضای کاربران کنترل بیشتری بر عملیات نگهداری حافظه پنهان می دهد.

DMA_BUF_IOCTL_SYNC بخشی از ABI پایدار هسته است و با تمام fds های dma-buf قابل استفاده است، خواه توسط ION تخصیص داده شده باشند یا نه.

انتقال کد فروشنده به android-4.12+

برای مشتریان فضای کاربری ، تیم سیستم‌های اندروید قویاً استفاده از فراخوان‌های ioctl() libion ​​را به جای کدگذاری باز تشویق می‌کنند. از اندروید 9، لیبیون به طور خودکار ION ABI را در زمان اجرا شناسایی می‌کند و سعی می‌کند هر گونه تفاوت بین هسته‌ها را پنهان کند. با این حال، هر توابع libion ​​که دسته‌های ion_user_handle_t را تولید یا مصرف می‌کند، بعد از کرنل 4.12 دیگر کار نمی‌کند. می‌توانید این توابع را با عملیات‌های معادل زیر در dma-buf fds جایگزین کنید، که روی تمام نسخه‌های هسته تا به امروز کار می‌کنند.

تماس قدیمی ion_user_handle_t فراخوانی معادل dma-buf fd
ion_alloc(ion_fd, …, &buf_handle) ion_alloc_fd(ion_fd, ..., &buf_fd)
ion_share(ion_fd, buf_handle, &buf_fd) N/A (این تماس با fds dma-buf مورد نیاز نیست)
ion_map(ion_fd, buf_handle, ...) mmap(buf_fd, ...)
ion_free(ion_fd, buf_handle) close(buf_fd)
ion_import(ion_fd, buf_fd, &buf_handle) N/A (این تماس با fds dma-buf مورد نیاز نیست)
ion_sync_fd(ion_fd, buf_fd)
If (ion_is_legacy(ion_fd))
    ion_sync_fd(ion_fd, buf_fd);
else
    ioctl(buf_fd, DMA_BUF_IOCTL_SYNC, ...);

برای کلاینت‌های درون هسته ، چون ION دیگر هیچ API رو به هسته صادر نمی‌کند، درایورهایی که قبلاً از API هسته ION درون هسته با ion_import_dma_buf_fd() استفاده می‌کردند باید برای استفاده از API dma-buf درون هسته با dma_buf_get() تبدیل شوند.

ION ABI آینده خراب می شود

قبل از اینکه بتوان ION را از درخت مرحله‌بندی خارج کرد، ممکن است نسخه‌های هسته آینده نیاز به شکستن مجدد ION ABI داشته باشند. تیم سیستم‌های اندروید انتظار ندارند این تغییرات روی دستگاه‌هایی که با نسخه اندروید بعدی راه‌اندازی می‌شوند تأثیر بگذارد، اما چنین تغییراتی ممکن است دستگاه‌هایی را که با نسخه‌های اندروید بعدی راه‌اندازی می‌شوند تحت تأثیر قرار دهد.

برای مثال، جامعه بالادستی پیشنهاد کرده است که گره /dev/ion منفرد را به چندین گره در هر هیپ (به عنوان مثال /dev/ion/heap0 ) تقسیم کند تا دستگاه‌ها بتوانند سیاست‌های SELinux مختلف را برای هر پشته اعمال کنند. اگر این تغییر در نسخه بعدی هسته اجرا شود، ION ABI را می شکند.