ION থেকে DMA-BUF হিপসে রূপান্তর

অ্যান্ড্রয়েড 12-এ, GKI 2.0 নিম্নলিখিত কারণগুলির জন্য DMA-BUF হিপগুলির সাথে ION বরাদ্দকারীকে প্রতিস্থাপন করে:

  • নিরাপত্তা: যেহেতু প্রতিটি DMA-BUF হিপ একটি পৃথক অক্ষর ডিভাইস, তাই প্রতিটি হিপে অ্যাক্সেস সেপলিসি দিয়ে আলাদাভাবে নিয়ন্ত্রণ করা যেতে পারে। এটি ION এর সাথে সম্ভব ছিল না কারণ যেকোন হিপ থেকে বরাদ্দের জন্য শুধুমাত্র /dev/ion ডিভাইসে অ্যাক্সেস প্রয়োজন।
  • ABI স্থিতিশীলতা: ION এর বিপরীতে, DMA-BUF heaps ফ্রেমওয়ার্কের IOCTL ইন্টারফেস ABI স্থিতিশীল হওয়ার গ্যারান্টিযুক্ত কারণ এটি আপস্ট্রিম লিনাক্স কার্নেলে রক্ষণাবেক্ষণ করা হয়।
  • স্ট্যান্ডার্ডাইজেশন: DMA-BUF হিপস ফ্রেমওয়ার্ক একটি সু-সংজ্ঞায়িত UAPI অফার করে। ION কাস্টম পতাকা এবং হিপ আইডিগুলিকে অনুমতি দেয় যা একটি সাধারণ পরীক্ষার কাঠামোর বিকাশকে বাধা দেয় কারণ প্রতিটি ডিভাইসের ION বাস্তবায়ন ভিন্নভাবে আচরণ করতে পারে৷

অ্যান্ড্রয়েড কমন কার্নেলের android12-5.10 শাখাটি 1 মার্চ, 2021-CONFIG_ION অক্ষম করেছে।

পটভূমি

নিম্নলিখিতটি ION এবং DMA-BUF হিপগুলির মধ্যে একটি সংক্ষিপ্ত তুলনা।

ION এবং DMA-BUF হিপস ফ্রেমওয়ার্কের মধ্যে মিল

  • আইওন এবং ডিএমএ-বিউএফ হিপস ফ্রেমওয়ার্ক উভয়ই হিপ-ভিত্তিক ডিএমএ-বিউএফ রপ্তানিকারক।
  • তারা উভয়ই প্রতিটি হিপকে তার নিজস্ব বরাদ্দকারী এবং DMA-BUF অপ্সকে সংজ্ঞায়িত করতে দেয়।
  • বরাদ্দের কার্যকারিতা একই কারণ উভয় স্কিম বরাদ্দের জন্য একটি একক IOCTL প্রয়োজন।

ION এবং DMA-BUF হিপস ফ্রেমওয়ার্কের মধ্যে পার্থক্য

ION স্তূপ 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গুলি দেখায়৷

ION স্তূপ 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 হিপস ফ্রেমওয়ার্ক ইন-কার্নেল ক্লায়েন্টদের জন্য একটি বরাদ্দ ইন্টারফেসও অফার করে। বরাদ্দের ধরন নির্বাচন করতে হিপ মাস্ক এবং পতাকা নির্দিষ্ট করার পরিবর্তে, ডিএমএ-বিইউএফ হিপস দ্বারা অফার করা ইন্টারফেসটি ইনপুট হিসাবে একটি হিপ নাম নেয়।

নিম্নলিখিত ইন-কার্নেল ION বরাদ্দ API এবং এর সমতুল্য DMA-BUF হিপ বরাদ্দ APIগুলি দেখায়৷ কার্নেল ড্রাইভার dma_heap_find() API ব্যবহার করে একটি হিপের অস্তিত্ব অনুসন্ধান করতে পারে। API struct dma_heap- এর একটি উদাহরণে একটি পয়েন্টার প্রদান করে, যা dma_heap_buffer_alloc() API-তে একটি আর্গুমেন্ট হিসাবে পাস করা যেতে পারে।

ION স্তূপ DMA-BUF স্তূপ
struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags)

struct dma_heap *dma_heap_find(const char *name)

struct dma_buf *struct dma_buf *dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, unsigned int fd_flags, unsigned int heap_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 একটি আনক্যাশড সিস্টেম হিপ বরাদ্দ করে এই টেবিলটি এই পরিবর্তনগুলিকে চিত্রিত করে।

বরাদ্দের ধরন 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 ক্লায়েন্টদের দ্বারা ব্যবহারের জন্য একটি হেডার ফাইলও প্রকাশ করে।

রেফারেন্স Gralloc বাস্তবায়ন

Hikey960 gralloc বাস্তবায়ন libdmabufheap ব্যবহার করে, তাই আপনি এটি একটি রেফারেন্স বাস্তবায়ন হিসাবে ব্যবহার করতে পারেন।

প্রয়োজনীয় ueventd সংযোজন

যে কোনো নতুন ডিভাইস-নির্দিষ্ট DMA-BUF হিপ তৈরির জন্য, ডিভাইসের ueventd.rc ফাইলে একটি নতুন এন্ট্রি যোগ করুন। এই সেটআপটি DMA-BUF হিপসকে সমর্থন করার জন্য ueventd উদাহরণ প্রদর্শন করে যে এটি DMA-BUF সিস্টেম হিপের জন্য কীভাবে করা হয়েছে।

প্রয়োজনীয় সেপলিসি সংযোজন

একটি ইউজারস্পেস ক্লায়েন্টকে একটি নতুন DMA-BUF হিপ অ্যাক্সেস করতে সক্ষম করতে সেপলিসি অনুমতি যোগ করুন। এটি প্রয়োজনীয় অনুমতি যোগ করার উদাহরণ বিভিন্ন ক্লায়েন্টদের জন্য DMA-BUF সিস্টেম হিপ অ্যাক্সেস করার জন্য তৈরি সেপলিসি অনুমতিগুলি দেখায়।

ফ্রেমওয়ার্ক কোড থেকে ভেন্ডর হিপস অ্যাক্সেস করা হচ্ছে

Treble সম্মতি নিশ্চিত করার জন্য, ফ্রেমওয়ার্ক কোড শুধুমাত্র বিক্রেতার স্তূপের প্রাক-অনুমোদিত বিভাগ থেকে বরাদ্দ করতে পারে।

অংশীদারদের কাছ থেকে প্রাপ্ত প্রতিক্রিয়ার উপর ভিত্তি করে, Google বিক্রেতার স্তূপের দুটি বিভাগ সনাক্ত করেছে যেগুলি অবশ্যই ফ্রেমওয়ার্ক কোড থেকে অ্যাক্সেস করতে হবে:

  1. ডিভাইস বা SoC-নির্দিষ্ট পারফরম্যান্স অপ্টিমাইজেশান সহ সিস্টেম হিপের উপর ভিত্তি করে হিপ।
  2. সুরক্ষিত মেমরি থেকে বরাদ্দ করার জন্য গাদা।

ডিভাইস বা SoC-নির্দিষ্ট পারফরম্যান্স অপ্টিমাইজেশান সহ সিস্টেম হিপের উপর ভিত্তি করে হিপ

এই ব্যবহারের ক্ষেত্রে সমর্থন করার জন্য, ডিফল্ট DMA-BUF হিপ সিস্টেমের হিপ বাস্তবায়ন ওভাররাইড করা যেতে পারে।

  • CONFIG_DMABUF_HEAPS_SYSTEM একটি বিক্রেতা মডিউল হতে অনুমতি দিতে gki_defconfig এ বন্ধ করা হয়েছে।
  • VTS কমপ্লায়েন্স পরীক্ষা নিশ্চিত করে যে হিপটি /dev/dma_heap/system এ বিদ্যমান। পরীক্ষাগুলিও যাচাই করে যে হিপটি থেকে বরাদ্দ করা যেতে পারে এবং ফেরত ফাইলের বর্ণনাকারী ( fd ) ব্যবহারকারীর স্থান থেকে মেমরি-ম্যাপ করা (mmapped) হতে পারে।

পূর্ববর্তী পয়েন্টগুলি সিস্টেম হিপের আনক্যাশড ভেরিয়েন্টের জন্যও সত্য, যদিও এটির অস্তিত্ব সম্পূর্ণ IO-সঙ্গত ডিভাইসের জন্য বাধ্যতামূলক নয়।

সুরক্ষিত মেমরি থেকে বরাদ্দ করার জন্য গাদা

সুরক্ষিত হিপ বাস্তবায়ন অবশ্যই বিক্রেতা-নির্দিষ্ট হতে হবে কারণ অ্যান্ড্রয়েড কমন কার্নেল একটি সাধারণ সুরক্ষিত হিপ বাস্তবায়ন সমর্থন করে না।

  • আপনার বিক্রেতা-নির্দিষ্ট বাস্তবায়নগুলিকে /dev/dma_heap/system-secure<vendor-suffix> হিসেবে নিবন্ধন করুন।
  • এই গাদা বাস্তবায়ন ঐচ্ছিক.
  • যদি গাদা বিদ্যমান থাকে, VTS পরীক্ষাগুলি নিশ্চিত করে যে তাদের থেকে বরাদ্দ করা যেতে পারে।
  • ফ্রেমওয়ার্কের উপাদানগুলিকে এই হিপগুলিতে অ্যাক্সেস দেওয়া হয় যাতে তারা কোডেক2 HAL/নন-বাইন্ডারাইজড, একই-প্রক্রিয়া HAL-এর মাধ্যমে হিপস ব্যবহার সক্ষম করতে পারে। যাইহোক, জেনেরিক অ্যান্ড্রয়েড ফ্রেমওয়ার্ক বৈশিষ্ট্যগুলি তাদের বাস্তবায়নের বিবরণে পরিবর্তনশীলতার কারণে তাদের উপর নির্ভরশীল হতে পারে না। যদি ভবিষ্যতে Android কমন কার্নেলে একটি জেনেরিক সুরক্ষিত হিপ ইমপ্লিমেন্টেশন যোগ করা হয়, তবে আপগ্রেড করার ডিভাইসগুলির সাথে দ্বন্দ্ব এড়াতে এটি অবশ্যই একটি ভিন্ন ABI ব্যবহার করবে।

DMA-BUF স্তূপের জন্য কোডেক 2 বরাদ্দকারী

DMA-BUF হিপস ইন্টারফেসের জন্য একটি কোডেক2 বরাদ্দকারী AOSP-এ উপলব্ধ।

কম্পোনেন্ট স্টোর ইন্টারফেস যা হিপ প্যারামিটারগুলিকে C2 HAL থেকে নির্দিষ্ট করার অনুমতি দেয় C2 DMA-BUF হিপ অ্যালোকেটারের সাথে উপলব্ধ।

একটি ION হিপের জন্য নমুনা রূপান্তর প্রবাহ

ION থেকে DMA-BUF হিপগুলিতে রূপান্তরটি মসৃণ করতে, libdmabufheap সময়ে একটি হিপ পরিবর্তন করার অনুমতি দেয়৷ নিম্নলিখিত পদক্ষেপগুলি my_heap নামে একটি অ-লেগ্যাসি ION হিপ যা একটি পতাকা সমর্থন করে, ION_FLAG_MY_FLAG ট্রানজিশন করার জন্য একটি প্রস্তাবিত ওয়ার্কফ্লো প্রদর্শন করে।

ধাপ1: DMA-BUF ফ্রেমওয়ার্কে ION হিপের সমতুল্য তৈরি করুন। এই উদাহরণে, যেহেতু ION heap my_heap একটি পতাকা ION_FLAG_MY_FLAG সমর্থন করে, আমরা দুটি DMA-BUF হিপ নিবন্ধন করি:

  • my_heap আচরণ ION_FLAG_MY_FLAG নিষ্ক্রিয় পতাকা সহ ION হিপের আচরণের সাথে হুবহু মিলে যায়৷
  • my_heap_special আচরণ ION_FLAG_MY_FLAG সক্রিয় ফ্ল্যাগ সহ ION হিপের আচরণের সাথে হুবহু মিলে যায়।

ধাপ 2: নতুন my_heap এবং my_heap_special DMA-BUF হিপগুলির জন্য ueventd পরিবর্তনগুলি তৈরি করুন। এই মুহুর্তে, হিপগুলি /dev/dma_heap/my_heap এবং /dev/dma_heap/my_heap_special হিসাবে দৃশ্যমান হয়, উদ্দেশ্যমূলক অনুমতিগুলির সাথে।

ধাপ 3: my_heap থেকে বরাদ্দ করা ক্লায়েন্টদের জন্য, libdmabufheap লিঙ্ক করতে তাদের মেকফাইলগুলি পরিবর্তন করুন। ক্লায়েন্ট ইনিশিয়ালাইজেশনের সময়, একটি BufferAllocator অবজেক্ট ইনস্ট্যান্টিয়েট করুন এবং MapNameToIonHeap() API ব্যবহার করুন <ION heap name/mask, flag> সমন্বয়কে সমতুল্য DMA-BUF হিপ নামের সাথে ম্যাপ করতে।

উদাহরণ স্বরূপ:

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 হিপ নামগুলিতে ম্যাপিং তৈরি করতে পারেন।

ধাপ 4: উপযুক্ত হিপ নাম ব্যবহার করে BufferAllocator::Alloc() দিয়ে ion_alloc_fd() আহ্বান প্রতিস্থাপন করুন।

বরাদ্দের ধরন libion libdmabufheap
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 হিপ খোলার জন্য প্রয়োজনীয় সেপলিসি অনুমতি নেই৷

ধাপ 5: নতুন DMA-BUF হিপস অ্যাক্সেস করার জন্য ক্লায়েন্টের জন্য প্রয়োজনীয় সেপলিসি অনুমতি তৈরি করুন। ক্লায়েন্ট এখন নতুন DMA-BUF হিপ থেকে বরাদ্দ করার জন্য সম্পূর্ণরূপে সজ্জিত।

ধাপ 6: logcat পরীক্ষা করে যাচাই করুন যে বরাদ্দগুলি নতুন DMA-BUF হিপ থেকে হচ্ছে৷

ধাপ 7: কার্নেলে ION heap my_heap নিষ্ক্রিয় করুন। যদি ক্লায়েন্ট কোডের আপগ্রেডিং ডিভাইসগুলিকে সমর্থন করার প্রয়োজন না হয় (যার কার্নেলগুলি শুধুমাত্র ION হিপগুলিকে সমর্থন করতে পারে), আপনি MapNameToIonHeap() আহ্বানগুলিও সরাতে পারেন৷