অ্যান্ড্রয়েড ১২-তে, GKI 2.0 নিম্নলিখিত কারণে ION অ্যালোকেটরকে DMA-BUF হিপ দিয়ে প্রতিস্থাপন করে:
- নিরাপত্তা: যেহেতু প্রতিটি DMA-BUF হিপ একটি পৃথক ক্যারেক্টার ডিভাইস, তাই প্রতিটি হিপের অ্যাক্সেস sepolicy ব্যবহার করে আলাদাভাবে নিয়ন্ত্রণ করা যেতে পারে। ION এর মাধ্যমে এটি সম্ভব ছিল না কারণ যেকোনো হিপ থেকে বরাদ্দের জন্য শুধুমাত্র
/dev/ionডিভাইসে অ্যাক্সেসের প্রয়োজন ছিল। - ABI স্থিতিশীলতা: ION এর বিপরীতে, DMA-BUF হিপস ফ্রেমওয়ার্কের IOCTL ইন্টারফেস ABI স্থিতিশীল কারণ এটি আপস্ট্রিম লিনাক্স কার্নেলে রক্ষণাবেক্ষণ করা হয়।
- স্ট্যান্ডার্ডাইজেশন: DMA-BUF হিপস ফ্রেমওয়ার্ক একটি সু-সংজ্ঞায়িত UAPI অফার করে। ION কাস্টম ফ্ল্যাগ এবং হিপ আইডিগুলিকে অনুমতি দেয় যা একটি সাধারণ পরীক্ষার কাঠামো তৈরি করতে বাধা দেয় কারণ প্রতিটি ডিভাইসের ION বাস্তবায়ন ভিন্নভাবে আচরণ করতে পারে।
অ্যান্ড্রয়েড কমন কার্নেলের android12-5.10 শাখা ১ মার্চ, ২০২১ তারিখে CONFIG_ION অক্ষম করে।
পটভূমি
নিচে ION এবং DMA-BUF হিপের মধ্যে একটি সংক্ষিপ্ত তুলনা দেওয়া হল।
ION এবং DMA-BUF হিপস ফ্রেমওয়ার্কের মধ্যে মিল
- ION এবং DMA-BUF হিপস ফ্রেমওয়ার্ক উভয়ই হিপ-ভিত্তিক DMA-BUF রপ্তানিকারক।
- তারা উভয়ই প্রতিটি হিপকে তার নিজস্ব অ্যালোকেটর এবং DMA-BUF অপারেশন সংজ্ঞায়িত করতে দেয়।
- বরাদ্দের কর্মক্ষমতা একই রকম কারণ উভয় প্রকল্পের বরাদ্দের জন্য একটি একক IOCTL প্রয়োজন।
ION এবং DMA-BUF হিপস ফ্রেমওয়ার্কের মধ্যে পার্থক্য
| আইওন গাদা | DMA-BUF হিপস |
|---|---|
সমস্ত ION বরাদ্দ /dev/ion দিয়ে করা হয়। | প্রতিটি DMA-BUF হিপ হল একটি ক্যারেক্টার ডিভাইস যা /dev/dma_heap/<heap_name> এ উপস্থিত থাকে। |
| ION হিপ প্রাইভেট ফ্ল্যাগ সমর্থন করে। | DMA-BUF হিপগুলি হিপ প্রাইভেট ফ্ল্যাগ সমর্থন করে না। প্রতিটি ভিন্ন ধরণের বরাদ্দকরণ ভিন্ন হিপ থেকে করা হয়। উদাহরণস্বরূপ, ক্যাশেড এবং আনক্যাশেড সিস্টেম হিপ ভেরিয়েন্টগুলি /dev/dma_heap/system এবং /dev/dma_heap/system_uncached এ অবস্থিত পৃথক হিপ। |
| বরাদ্দের জন্য হিপ আইডি/মাস্ক এবং পতাকা নির্দিষ্ট করতে হবে। | বরাদ্দের জন্য হিপ নামটি ব্যবহার করা হয়। |
নিম্নলিখিত বিভাগগুলিতে ION-এর সাথে সম্পর্কিত উপাদানগুলির তালিকা দেওয়া হয়েছে এবং কীভাবে সেগুলিকে DMA-BUF হিপস ফ্রেমওয়ার্কে স্যুইচ করতে হয় তা বর্ণনা করা হয়েছে।
ION থেকে DMA-BUF হিপগুলিতে কার্নেল ড্রাইভারগুলির রূপান্তর
ION হিপ বাস্তবায়নকারী কার্নেল ড্রাইভার
ION এবং DMA-BUF উভয় হিপই প্রতিটি হিপকে তার নিজস্ব অ্যালোকেটর এবং DMA-BUF অপারেশন বাস্তবায়নের অনুমতি দেয়। তাই আপনি হিপ নিবন্ধনের জন্য বিভিন্ন API ব্যবহার করে ION হিপ বাস্তবায়ন থেকে DMA-BUF হিপ বাস্তবায়নে স্যুইচ করতে পারেন। এই টেবিলে ION হিপ নিবন্ধন API এবং তাদের সমতুল্য DMA-BUF হিপ API দেখানো হয়েছে।
| আইওন গাদা | DMA-BUF হিপস |
|---|---|
void ion_device_add_heap(struct ion_heap *heap) | struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info); |
void ion_device_remove_heap(struct ion_heap *heap) | void dma_heap_put(struct dma_heap *heap); |
DMA-BUF হিপগুলি হিপ প্রাইভেট ফ্ল্যাগ সমর্থন করে না। তাই হিপের প্রতিটি ভেরিয়েন্টকে dma_heap_add() API ব্যবহার করে পৃথকভাবে নিবন্ধিত করতে হবে। কোড শেয়ারিং সহজতর করার জন্য, একই ড্রাইভারের মধ্যে একই হিপের সমস্ত ভেরিয়েন্ট নিবন্ধিত করার পরামর্শ দেওয়া হচ্ছে। এই dma-buf: system_heap উদাহরণটি সিস্টেম হিপের ক্যাশেড এবং আনক্যাশেড ভেরিয়েন্টগুলির বাস্তবায়ন দেখায়।
শুরু থেকে একটি DMA-BUF হিপ তৈরি করতে এই dma-buf: heaps: উদাহরণ টেমপ্লেটটি ব্যবহার করুন।
ION হিপ থেকে সরাসরি বরাদ্দ করা কার্নেল ড্রাইভার
DMA-BUF হিপস ফ্রেমওয়ার্ক ইন-কার্নেল ক্লায়েন্টদের জন্য একটি অ্যালোকেশন ইন্টারফেসও অফার করে। অ্যালোকেশনের ধরণ নির্বাচন করার জন্য হিপ মাস্ক এবং ফ্ল্যাগ নির্দিষ্ট করার পরিবর্তে, DMA-BUF হিপস দ্বারা প্রদত্ত ইন্টারফেস ইনপুট হিসাবে একটি হিপ নাম গ্রহণ করে।
নিম্নলিখিতটি ইন-কার্নেল ION অ্যালোকেশন API এবং এর সমতুল্য DMA-BUF হিপ অ্যালোকেশন API গুলি দেখায়। কার্নেল ড্রাইভাররা একটি হিপের অস্তিত্ব জিজ্ঞাসা করতে dma_heap_find() API ব্যবহার করতে পারে। API struct dma_heap এর একটি উদাহরণে একটি পয়েন্টার ফেরত দেয়, যা পরে dma_heap_buffer_alloc() API তে একটি আর্গুমেন্ট হিসাবে পাস করা যেতে পারে।
| আইওন গাদা | DMA-BUF হিপস |
|---|---|
struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) | |
DMA-BUF ব্যবহার করে এমন কার্নেল ড্রাইভার
শুধুমাত্র DMA-BUF আমদানিকারী ড্রাইভারগুলির জন্য কোনও পরিবর্তনের প্রয়োজন নেই, কারণ একটি ION হিপ থেকে বরাদ্দ করা একটি বাফার একটি সমতুল্য DMA-BUF হিপ থেকে বরাদ্দ করা বাফারের মতোই আচরণ করে।
ION-এর ইউজার-স্পেস ক্লায়েন্টগুলিকে DMA-BUF হিপগুলিতে রূপান্তর করুন
ION-এর ইউজার-স্পেস ক্লায়েন্টদের জন্য ট্রানজিশন সহজ করার জন্য, libdmabufheap নামক একটি অ্যাবস্ট্রাকশন লাইব্রেরি উপলব্ধ। libdmabufheap DMA-BUF হিপ এবং ION হিপগুলিতে বরাদ্দকরণ সমর্থন করে। এটি প্রথমে পরীক্ষা করে যে নির্দিষ্ট নামের একটি DMA-BUF হিপ বিদ্যমান কিনা এবং যদি না থাকে, তাহলে সমতুল্য ION হিপে ফিরে যায়, যদি থাকে।
ক্লায়েন্টদের /dev/ion using ion_open() খোলার পরিবর্তে তাদের ইনিশিয়ালাইজেশনের সময় একটি BufferAllocator অবজেক্ট ইনিশিয়ালাইজ করা উচিত। এর কারণ হল /dev/ion এবং /dev/dma_heap/<heap_name> খোলার মাধ্যমে তৈরি ফাইল বর্ণনাকারীগুলি BufferAllocator অবজেক্ট দ্বারা অভ্যন্তরীণভাবে পরিচালিত হয়।
libion থেকে libdmabufheap এ স্যুইচ করতে, ক্লায়েন্টদের আচরণ নিম্নরূপ পরিবর্তন করুন:
- হেড আইডি/মাস্ক এবং হিপ ফ্ল্যাগের পরিবর্তে বরাদ্দের জন্য ব্যবহার করা হিপ নামের উপর নজর রাখুন।
-
ion_alloc_fd()API, যা একটি হিপ মাস্ক এবং ফ্ল্যাগ আর্গুমেন্ট নেয়, তার পরিবর্তেBufferAllocator::Alloc()API ব্যবহার করুন, যা একটি হিপ নাম নেয়।
এই টেবিলটি এই পরিবর্তনগুলি চিত্রিত করে দেখায় যে কীভাবে libion এবং libdmabufheap একটি আনক্যাশেড সিস্টেম হিপ বরাদ্দ করে।
| বরাদ্দের ধরণ | লিবিয়ন | অনুসরণ |
|---|---|---|
| সিস্টেম হিপ থেকে ক্যাশেড অ্যালোকেশন | ion_alloc_fd(ionfd, size, 0, ION_HEAP_SYSTEM, ION_FLAG_CACHED, &fd) | allocator->Alloc("system", size) |
| সিস্টেম হিপ থেকে আনক্যাশেড অ্যালোকেশন | ion_alloc_fd(ionfd, size, 0, ION_HEAP_SYSTEM, 0, &fd) | allocator->Alloc("system-uncached", size) |
আনক্যাশেড সিস্টেম হিপ ভেরিয়েন্টটি আপস্ট্রিমের অনুমোদনের অপেক্ষায় রয়েছে তবে এটি ইতিমধ্যেই android12-5.10 শাখার অংশ।
আপগ্রেডিং ডিভাইসগুলিকে সমর্থন করার জন্য, MapNameToIonHeap() API একটি হিপ নামকে ION হিপ প্যারামিটারে (হিপ নাম বা মাস্ক এবং ফ্ল্যাগ) ম্যাপ করার অনুমতি দেয় যাতে সেই ইন্টারফেসগুলি নাম-ভিত্তিক বরাদ্দ ব্যবহার করতে পারে। এখানে একটি নাম-ভিত্তিক বরাদ্দের উদাহরণ দেওয়া হল।
libdmabufheap দ্বারা প্রকাশিত প্রতিটি API- এর ডকুমেন্টেশন উপলব্ধ। লাইব্রেরিটি C ক্লায়েন্টদের ব্যবহারের জন্য একটি হেডার ফাইলও প্রকাশ করে।
রেফারেন্স গ্র্যালোক বাস্তবায়ন
Hikey960 gralloc বাস্তবায়ন libdmabufheap ব্যবহার করে, তাই আপনি এটিকে একটি রেফারেন্স বাস্তবায়ন হিসেবে ব্যবহার করতে পারেন।
প্রয়োজনীয় সংযোজন
যেকোনো নতুন ডিভাইস-নির্দিষ্ট DMA-BUF হিপ তৈরির জন্য, ডিভাইসের ueventd.rc ফাইলে একটি নতুন এন্ট্রি যোগ করুন। DMA-BUF হিপস সমর্থন করার জন্য ueventd-এর এই সেটআপটি উদাহরণে দেখানো হয়েছে যে DMA-BUF সিস্টেম হিপের জন্য এটি কীভাবে করা হয়েছে।
প্রয়োজনীয় সিপলিসি সংযোজন
একটি নতুন DMA-BUF হিপ অ্যাক্সেস করার জন্য একটি ইউজারস্পেস ক্লায়েন্টকে সক্ষম করতে sepolicy অনুমতি যোগ করুন। এই প্রয়োজনীয় অনুমতি যোগ করার উদাহরণটি বিভিন্ন ক্লায়েন্টদের DMA-BUF সিস্টেম হিপ অ্যাক্সেস করার জন্য তৈরি sepolicy অনুমতিগুলি দেখায়।
ফ্রেমওয়ার্ক কোড থেকে ভেন্ডর হিপস অ্যাক্সেস করুন
ট্রেবল সম্মতি নিশ্চিত করার জন্য, ফ্রেমওয়ার্ক কোড শুধুমাত্র পূর্ব-অনুমোদিত বিক্রেতা হিপ বিভাগ থেকে বরাদ্দ করা যেতে পারে।
অংশীদারদের কাছ থেকে প্রাপ্ত প্রতিক্রিয়ার উপর ভিত্তি করে, গুগল দুটি ধরণের ভেন্ডর হিপ চিহ্নিত করেছে যা ফ্রেমওয়ার্ক কোড থেকে অ্যাক্সেস করতে হবে:
- ডিভাইস বা SoC-নির্দিষ্ট কর্মক্ষমতা অপ্টিমাইজেশন সহ সিস্টেম হিপের উপর ভিত্তি করে তৈরি হিপ।
- সুরক্ষিত মেমরি থেকে বরাদ্দ করার জন্য প্রচুর পরিমাণে।
ডিভাইস বা SoC-নির্দিষ্ট কর্মক্ষমতা অপ্টিমাইজেশন সহ সিস্টেম হিপের উপর ভিত্তি করে হিপস
এই ব্যবহারের ক্ষেত্রে সমর্থন করার জন্য, ডিফল্ট DMA-BUF হিপ সিস্টেমের হিপ বাস্তবায়ন ওভাররাইড করা যেতে পারে।
-
gki_defconfigএCONFIG_DMABUF_HEAPS_SYSTEMবন্ধ করা আছে যাতে এটি একটি বিক্রেতা মডিউল হতে পারে। - VTS কমপ্লায়েন্স পরীক্ষা নিশ্চিত করে যে হিপটি
/dev/dma_heap/systemএ বিদ্যমান। পরীক্ষাগুলি আরও যাচাই করে যে হিপটি থেকে বরাদ্দ করা যেতে পারে এবং ফিরে আসা ফাইল বর্ণনাকারী (fd) ব্যবহারকারীর স্থান থেকে মেমরি-ম্যাপ করা (mmapped) করা যেতে পারে।
পূর্ববর্তী বিষয়গুলি সিস্টেম হিপের আনক্যাশেড ভেরিয়েন্টের ক্ষেত্রেও সত্য, যদিও সম্পূর্ণ IO-সুসঙ্গত ডিভাইসের জন্য এর অস্তিত্ব বাধ্যতামূলক নয়।
সুরক্ষিত মেমরি থেকে বরাদ্দ করার জন্য গাদা
সিকিউর হিপ বাস্তবায়ন অবশ্যই বিক্রেতা-নির্দিষ্ট হতে হবে কারণ অ্যান্ড্রয়েড কমন কার্নেল জেনেরিক সিকিউর হিপ বাস্তবায়ন সমর্থন করে না।
- আপনার বিক্রেতা-নির্দিষ্ট বাস্তবায়নগুলিকে
/dev/dma_heap/system-secure<vendor-suffix>হিসাবে নিবন্ধন করুন। - এই হিপ বাস্তবায়নগুলি ঐচ্ছিক।
- যদি স্তূপগুলি বিদ্যমান থাকে, তাহলে VTS পরীক্ষাগুলি নিশ্চিত করে যে সেগুলি থেকে বরাদ্দ করা যেতে পারে।
- ফ্রেমওয়ার্ক উপাদানগুলিকে এই হিপগুলিতে অ্যাক্সেস দেওয়া হয় যাতে তারা Codec2 HAL/নন-বাইন্ডারাইজড, একই-প্রক্রিয়া HAL-এর মাধ্যমে হিপ ব্যবহার সক্ষম করতে পারে। তবে, জেনেরিক অ্যান্ড্রয়েড ফ্রেমওয়ার্ক বৈশিষ্ট্যগুলি তাদের বাস্তবায়নের বিবরণের পরিবর্তনশীলতার কারণে তাদের উপর নির্ভর করতে পারে না। ভবিষ্যতে যদি একটি জেনেরিক সুরক্ষিত হিপ বাস্তবায়ন অ্যান্ড্রয়েড কমন কার্নেলে যোগ করা হয়, তাহলে আপগ্রেডিং ডিভাইসগুলির সাথে দ্বন্দ্ব এড়াতে এটিকে একটি ভিন্ন ABI ব্যবহার করতে হবে।
DMA-BUF হিপের জন্য কোডেক 2 অ্যালোকেটর
AOSP-তে DMA-BUF হিপস ইন্টারফেসের জন্য একটি codec2 অ্যালোকেটর উপলব্ধ।
C2 DMA-BUF হিপ অ্যালোকেটরের সাথে কম্পোনেন্ট স্টোর ইন্টারফেস উপলব্ধ যা C2 HAL থেকে হিপ প্যারামিটার নির্দিষ্ট করার অনুমতি দেয়।
একটি ION হিপের জন্য নমুনা রূপান্তর প্রবাহ
ION থেকে DMA-BUF হিপগুলিতে রূপান্তর মসৃণ করার জন্য, libdmabufheap একবারে একটি হিপ স্যুইচ করার অনুমতি দেয়। নিম্নলিখিত পদক্ষেপগুলি my_heap নামক একটি নন-লেগেসি ION হিপ রূপান্তরের জন্য একটি প্রস্তাবিত কর্মপ্রবাহ প্রদর্শন করে যা একটি পতাকা, ION_FLAG_MY_FLAG সমর্থন করে।
ধাপ ১: DMA-BUF ফ্রেমওয়ার্কে ION হিপের সমতুল্য তৈরি করুন। এই উদাহরণে, যেহেতু ION হিপ my_heap একটি ফ্ল্যাগ ION_FLAG_MY_FLAG সমর্থন করে, আমরা দুটি DMA-BUF হিপ নিবন্ধন করি:
-
my_heapআচরণ ION হিপের আচরণের সাথে হুবহু মিলে যায় যেখানেION_FLAG_MY_FLAGপতাকাটি নিষ্ক্রিয় করা আছে। -
my_heap_specialআচরণION_FLAG_MY_FLAGপতাকা সক্রিয় থাকা ION হিপের আচরণের সাথে হুবহু মিলে যায়।
ধাপ ২: নতুন my_heap এবং my_heap_special DMA-BUF হিপগুলির জন্য ueventd পরিবর্তনগুলি তৈরি করুন। এই মুহুর্তে, হিপগুলি /dev/dma_heap/my_heap এবং /dev/dma_heap/my_heap_special হিসাবে দৃশ্যমান হবে, উদ্দেশ্যমূলক অনুমতি সহ।
ধাপ ৩: যেসব ক্লায়েন্ট my_heap থেকে বরাদ্দ করে, তাদের makefiles পরিবর্তন করে libdmabufheap এর সাথে লিঙ্ক করুন। ক্লায়েন্ট ইনিশিয়ালাইজেশনের সময়, একটি BufferAllocator অবজেক্ট ইনস্ট্যান্টিয়েট করুন এবং MapNameToIonHeap() API ব্যবহার করে <ION heap name/mask, flag> এর সমতুল্য DMA-BUF heap names এর সাথে সমন্বয় ম্যাপ করুন।
উদাহরণস্বরূপ:
allocator->MapNameToIonHeap("my_heap_special" /* name of DMA-BUF heap */, "my_heap" /* name of the ION heap */, ION_FLAG_MY_FLAG /* ion flags */ )
নাম এবং পতাকা প্যারামিটার সহ MapNameToIonHeap() API ব্যবহার করার পরিবর্তে, আপনি ION হিপ নেম প্যারামিটারটি খালি সেট করে <ION heap mask, flag> থেকে সমতুল্য DMA-BUF হিপ নামের ম্যাপিং তৈরি করতে পারেন।
ধাপ ৪: উপযুক্ত হিপ নাম ব্যবহার করে ion_alloc_fd() ইনভোকেশনগুলিকে BufferAllocator::Alloc() দিয়ে প্রতিস্থাপন করুন।
| বরাদ্দের ধরণ | লিবিয়ন | অনুসরণ |
|---|---|---|
ION_FLAG_MY_FLAG পতাকা সহ my_heap থেকে বরাদ্দ সেট করা হয়নি | ion_alloc_fd(ionfd, size, 0, ION_HEAP_MY_HEAP, 0, &fd) | allocator->Alloc("my_heap", size) |
ION_FLAG_MY_FLAG পতাকা সেট সহ my_heap থেকে বরাদ্দকরণ | ion_alloc_fd(ionfd, size, 0, ION_HEAP_MY_HEAP, ION_FLAG_MY_FLAG, &fd) | allocator->Alloc("my_heap_special", size) |
এই মুহুর্তে, ক্লায়েন্টটি কার্যকরী কিন্তু এখনও ION হিপ থেকে বরাদ্দ করা হচ্ছে কারণ DMA-BUF হিপ খোলার জন্য প্রয়োজনীয় sepolicy অনুমতি এর নেই।
ধাপ ৫: নতুন DMA-BUF হিপ অ্যাক্সেস করার জন্য ক্লায়েন্টের জন্য প্রয়োজনীয় sepolicy অনুমতি তৈরি করুন। ক্লায়েন্ট এখন নতুন DMA-BUF হিপ থেকে বরাদ্দ করার জন্য সম্পূর্ণরূপে প্রস্তুত।
ধাপ ৬: logcat পরীক্ষা করে যাচাই করুন যে নতুন DMA-BUF হিপ থেকে বরাদ্দকরণগুলি ঘটছে।
ধাপ ৭: কার্নেলে ION heap my_heap নিষ্ক্রিয় করুন। যদি ক্লায়েন্ট কোডের আপগ্রেডিং ডিভাইসগুলি সমর্থন করার প্রয়োজন না হয় (যার কার্নেলগুলি কেবল ION heaps সমর্থন করতে পারে), আপনি MapNameToIonHeap() ইনভোকেশনগুলিও সরাতে পারেন।