GKI এর জন্য কার্নেল কোড তৈরি করুন

জেনেরিক কার্নেল ইমেজ (GKI) আপস্ট্রিম লিনাক্স কার্নেলের সাথে ঘনিষ্ঠভাবে সামঞ্জস্য রেখে কার্নেল ফ্র্যাগমেন্টেশন হ্রাস করে। তবে, কিছু প্যাচ আপস্ট্রিমে গ্রহণ না করার পেছনে বৈধ কারণ থাকে এবং পণ্যের সময়সূচীও মেনে চলতে হয়, তাই কিছু প্যাচ অ্যান্ড্রয়েড কমন কার্নেল (ACK) সোর্সে রক্ষণাবেক্ষণ করা হয়, যেখান থেকে GKI তৈরি করা হয়।

ডেভেলপারদের অবশ্যই প্রথম পছন্দ হিসেবে লিনাক্স কার্নেল মেইলিং লিস্ট (LKML) ব্যবহার করে আপস্ট্রিমে কোড পরিবর্তন জমা দিতে হবে এবং শুধুমাত্র যখন আপস্ট্রিমে কোড জমা দেওয়া সম্ভব নয় এমন কোনো জোরালো কারণ থাকবে, তখনই ACK android-mainline ব্রাঞ্চে কোড পরিবর্তন জমা দিতে হবে। বৈধ কারণগুলোর উদাহরণ এবং সেগুলো কীভাবে সামলাতে হবে তা নিচে তালিকাভুক্ত করা হলো।

  • প্যাচটি LKML-এ জমা দেওয়া হয়েছিল, কিন্তু প্রোডাক্ট রিলিজের জন্য সময়মতো গৃহীত হয়নি। এই প্যাচটি পরিচালনা করতে:

    • প্যাচটি যে LKML-এ জমা দেওয়া হয়েছে এবং এর জন্য প্রাপ্ত মন্তব্যগুলোর প্রমাণ দিন, অথবা প্যাচটি আপস্ট্রিমে জমা দেওয়ার একটি আনুমানিক সময়সীমা জানান।
    • প্যাচটি ACK-তে অন্তর্ভুক্ত করা, আপস্ট্রিম থেকে এর অনুমোদন নেওয়া এবং চূড়ান্ত আপস্ট্রিম সংস্করণটি ACK-তে মার্জ হয়ে গেলে প্যাচটি ACK থেকে সরিয়ে ফেলার জন্য একটি কর্মপন্থা স্থির করুন।
  • প্যাচটি একটি ভেন্ডর মডিউলের জন্য EXPORT_SYMBOLS_GPL() সংজ্ঞায়িত করে, কিন্তু এটি আপস্ট্রিমে জমা দেওয়া যায়নি কারণ এমন কোনো ইন-ট্রি মডিউল নেই যা ঐ সিম্বলটি ব্যবহার করে। এই প্যাচটি গ্রহণ করার জন্য, আপনার মডিউলটি কেন আপস্ট্রিমে জমা দেওয়া যাচ্ছে না এবং এই অনুরোধটি করার আগে আপনি কী কী বিকল্প বিবেচনা করেছিলেন, সে সম্পর্কে বিস্তারিত তথ্য দিন।

  • প্যাচটি আপস্ট্রিমের জন্য যথেষ্ট জেনেরিক নয় এবং প্রোডাক্ট রিলিজের আগে এটি রিফ্যাক্টর করার মতো সময় নেই। এই প্যাচটি হ্যান্ডেল করার জন্য, একটি আনুমানিক সময় জানান যার মধ্যে একটি রিফ্যাক্টর করা প্যাচ আপস্ট্রিমে জমা দেওয়া হবে (রিভিউয়ের জন্য আপস্ট্রিমে একটি রিফ্যাক্টর করা প্যাচ জমা দেওয়ার পরিকল্পনা ছাড়া প্যাচটি ACK-তে গ্রহণ করা হবে না)।

  • প্যাচটি আপস্ট্রিম গ্রহণ করতে পারছে না কারণ... <এখানে কারণ উল্লেখ করুন> । এই প্যাচটি নিয়ে কাজ করার জন্য, অ্যান্ড্রয়েড কার্নেল টিমের সাথে যোগাযোগ করুন এবং প্যাচটি রিফ্যাক্টর করার বিকল্পগুলো নিয়ে আমাদের সাথে কাজ করুন, যাতে এটি পর্যালোচনার জন্য জমা দেওয়া যায় এবং আপস্ট্রিমে গৃহীত হয়।

আরও অনেক সম্ভাব্য যুক্তি রয়েছে। যখন আপনি আপনার বাগ বা প্যাচ জমা দেবেন, তখন একটি বৈধ যুক্তি অন্তর্ভুক্ত করুন এবং কিছু পুনরাবৃত্তি ও আলোচনার জন্য প্রস্তুত থাকুন। আমরা স্বীকার করি যে ACK-তে কিছু প্যাচ থাকে, বিশেষ করে GKI-এর প্রাথমিক পর্যায়ে যখন সবাই আপস্ট্রিমে কাজ করা শিখছে, কিন্তু তা করার জন্য প্রোডাক্টের সময়সূচী শিথিল করা যায় না। সময়ের সাথে সাথে আপস্ট্রিমিংয়ের প্রয়োজনীয়তা আরও কঠোর হবে বলে আশা করা যায়।

প্যাচের প্রয়োজনীয়তা

প্যাচগুলি আপস্ট্রিমে বা ACK-তে জমা দেওয়া হোক না কেন, সেগুলিকে অবশ্যই লিনাক্স সোর্স ট্রি- তে বর্ণিত লিনাক্স কার্নেল কোডিং স্ট্যান্ডার্ড মেনে চলতে হবে। scripts/checkpatch.pl স্ক্রিপ্টটি Gerrit প্রিসাবমিট টেস্টিং-এর অংশ হিসেবে চালানো হয়, তাই এটি পাস করছে কিনা তা নিশ্চিত করতে আগে থেকেই এটি চালান। প্রিসাবমিট টেস্টিং-এর মতো একই কনফিগারেশনে চেকপ্যাচ স্ক্রিপ্টটি চালাতে, //build/kernel/static_analysis:checkpatch_presubmit ব্যবহার করুন। বিস্তারিত জানতে, build/kernel/kleaf/docs/checkpatch.md দেখুন।

ACK প্যাচগুলি

ACK-তে জমা দেওয়া প্যাচ অবশ্যই লিনাক্স কার্নেল কোডিং স্ট্যান্ডার্ড এবং কন্ট্রিবিউশন গাইডলাইন মেনে চলতে হবে। আপনাকে কমিট মেসেজে অবশ্যই একটি Change-Id ট্যাগ অন্তর্ভুক্ত করতে হবে; যদি আপনি প্যাচটি একাধিক ব্রাঞ্চে (উদাহরণস্বরূপ, android-mainline এবং android12-5.4 ) জমা দেন, তবে প্যাচটির সমস্ত ক্ষেত্রে আপনাকে একই Change-Id ব্যবহার করতে হবে।

আপস্ট্রিম পর্যালোচনার জন্য প্রথমে LKML-এর কাছে প্যাচ জমা দিন। যদি প্যাচটি হয়:

  • আপস্ট্রিম থেকে গৃহীত হওয়ায়, এটি স্বয়ংক্রিয়ভাবে android-mainline -এ মার্জ হয়ে যায়।
  • আপস্ট্রিমে গৃহীত না হলে, আপস্ট্রিম সাবমিশনের রেফারেন্স সহ অথবা LKML-এ কেন জমা দেওয়া হয়নি তার ব্যাখ্যা দিয়ে এটি android-mainline এ জমা দিন।

কোনো প্যাচ আপস্ট্রিম বা android-mainline গৃহীত হওয়ার পর, সেটিকে উপযুক্ত LTS-ভিত্তিক ACK-তে (যেমন অ্যান্ড্রয়েড-নির্দিষ্ট কোড সংশোধনকারী প্যাচগুলির জন্য android12-5.4 এবং android11-5.4 ) ব্যাকপোর্ট করা যেতে পারে। android-mainline এ জমা দিলে নতুন আপস্ট্রিম রিলিজ ক্যান্ডিডেটগুলির সাথে পরীক্ষা করা সম্ভব হয় এবং এটি নিশ্চিত করে যে প্যাচটি পরবর্তী LTS-ভিত্তিক ACK-তে অন্তর্ভুক্ত থাকবে। এর ব্যতিক্রম হলো সেইসব ক্ষেত্র, যেখানে একটি আপস্ট্রিম প্যাচ android12-5.4 এ ব্যাকপোর্ট করা হয় (কারণ প্যাচটি সম্ভবত ইতিমধ্যেই android-mainline এ অন্তর্ভুক্ত থাকে)।

আপস্ট্রিম প্যাচগুলি

অবদান নির্দেশিকায় যেমন উল্লেখ করা হয়েছে, ACK কার্নেলের জন্য নির্ধারিত আপস্ট্রিম প্যাচগুলি নিম্নলিখিত গোষ্ঠীগুলির অন্তর্ভুক্ত (গৃহীত হওয়ার সম্ভাবনার ক্রমানুসারে তালিকাভুক্ত)।

  • UPSTREAM: - 'android-mainline' থেকে বেছে নেওয়া প্যাচগুলো, যদি এর কোনো যুক্তিসঙ্গত ব্যবহারক্ষেত্র থাকে, তাহলে ACK-তে গৃহীত হওয়ার সম্ভাবনা রয়েছে।
  • BACKPORT: - আপস্ট্রিম থেকে আসা যে প্যাচগুলো সহজে চেরিপিক হয় না এবং পরিবর্তনের প্রয়োজন হয়, সেগুলোরও যুক্তিসঙ্গত ব্যবহারিক ক্ষেত্র থাকলে গৃহীত হওয়ার সম্ভাবনা রয়েছে।
  • FROMGIT: - লিনাক্স মেইনলাইনে জমা দেওয়ার প্রস্তুতির জন্য কোনো মেইনটেইনার ব্রাঞ্চ থেকে চেরিপিক করা প্যাচ গ্রহণ করা হতে পারে, যদি কোনো আসন্ন ডেডলাইন থাকে। এগুলোর বিষয়বস্তু এবং সময়সূচী উভয়ের জন্যই যৌক্তিকতা থাকতে হবে।
  • FROMLIST: - যে প্যাচগুলি LKML-এ জমা দেওয়া হয়েছে কিন্তু এখনও কোনো মেইনটেইনার ব্রাঞ্চে গৃহীত হয়নি, সেগুলি গৃহীত হওয়ার সম্ভাবনা কম, যদি না এর সপক্ষে যথেষ্ট জোরালো যুক্তি থাকে যে প্যাচটি আপস্ট্রিম লিনাক্সে অন্তর্ভুক্ত হোক বা না হোক, তা গৃহীত হবে (আমরা ধরে নিচ্ছি যে এটি হবে না)। অ্যান্ড্রয়েড কার্নেল টিমের সাথে আলোচনা সহজ করার জন্য FROMLIST প্যাচগুলির সাথে অবশ্যই একটি ইস্যু যুক্ত থাকতে হবে।

অ্যান্ড্রয়েড-নির্দিষ্ট প্যাচ

আপনি যদি আপস্ট্রিমে প্রয়োজনীয় পরিবর্তনগুলো অন্তর্ভুক্ত করতে না পারেন, তাহলে সরাসরি ACK-তে আউট-অফ-ট্রি প্যাচ জমা দেওয়ার চেষ্টা করতে পারেন। আউট-অফ-ট্রি প্যাচ জমা দেওয়ার জন্য আপনাকে IT-তে একটি ইস্যু তৈরি করতে হবে, যেখানে প্যাচটির উল্লেখ থাকবে এবং কেন এটি আপস্ট্রিমে জমা দেওয়া যাচ্ছে না তার কারণও জানাতে হবে (উদাহরণস্বরূপ পূর্ববর্তী তালিকাটি দেখুন)। তবে, এমন কিছু ক্ষেত্র রয়েছে যেখানে কোড আপস্ট্রিমে জমা দেওয়া যায় না। এই ক্ষেত্রগুলো নিম্নরূপ এবং এগুলোর ক্ষেত্রে অবশ্যই অ্যান্ড্রয়েড-নির্দিষ্ট প্যাচের জন্য কন্ট্রিবিউশন নির্দেশিকা অনুসরণ করতে হবে ও সাবজেক্টে ANDROID: প্রিফিক্স দিয়ে ট্যাগ করতে হবে।

gki_defconfig-এ পরিবর্তন

gki_defconfig এর সমস্ত CONFIG পরিবর্তন arm64 এবং x86 উভয় সংস্করণে প্রয়োগ করতে হবে, যদি না CONFIG টি আর্কিটেকচার-নির্দিষ্ট হয়। কোনো CONFIG সেটিং পরিবর্তনের অনুরোধ করতে, পরিবর্তনটি নিয়ে আলোচনার জন্য IT-তে একটি ইস্যু তৈরি করুন। কোনো CONFIG পরিবর্তন যা কার্নেল মডিউল ইন্টারফেস (KMI)-কে প্রভাবিত করে, তা একবার চূড়ান্ত হয়ে গেলে বাতিল করা হয়। যেসব ক্ষেত্রে অংশীদাররা একটিমাত্র কনফিগের জন্য পরস্পরবিরোধী সেটিংসের অনুরোধ করেন, আমরা সংশ্লিষ্ট বাগগুলো নিয়ে আলোচনার মাধ্যমে দ্বন্দ্ব নিরসন করি।

যে কোড আপস্ট্রিমে বিদ্যমান নেই

ইতিমধ্যে অ্যান্ড্রয়েড-নির্দিষ্ট কোডের কোনো পরিবর্তন আপস্ট্রিমে পাঠানো যায় না। উদাহরণস্বরূপ, যদিও বাইন্ডার ড্রাইভারটি আপস্ট্রিমে রক্ষণাবেক্ষণ করা হয়, বাইন্ডার ড্রাইভারের প্রায়োরিটি ইনহেরিটেন্স ফিচারগুলোর পরিবর্তন আপস্ট্রিমে পাঠানো যায় না, কারণ সেগুলো অ্যান্ড্রয়েড-নির্দিষ্ট। আপনার বাগ এবং প্যাচে স্পষ্টভাবে উল্লেখ করুন কেন কোডটি আপস্ট্রিমে পাঠানো যাবে না। সম্ভব হলে, প্যাচগুলোকে এমন অংশে ভাগ করুন যা আপস্ট্রিমে জমা দেওয়া যায় এবং অ্যান্ড্রয়েড-নির্দিষ্ট অংশ যা আপস্ট্রিমে জমা দেওয়া যায় না, যাতে ACK-তে রক্ষণাবেক্ষণ করা আউট-অফ-ট্রি কোডের পরিমাণ কমানো যায়।

এই বিভাগের অন্যান্য পরিবর্তনগুলির মধ্যে রয়েছে KMI রিপ্রেজেন্টেশন ফাইল, KMI সিম্বল লিস্ট, gki_defconfig , বিল্ড স্ক্রিপ্ট বা কনফিগারেশন, অথবা আপস্ট্রিমে নেই এমন অন্যান্য স্ক্রিপ্টের আপডেট।

গাছের বাইরের মডিউল

আপস্ট্রিম লিনাক্স ট্রি-এর বাইরের মডিউল তৈরির সমর্থনকে সক্রিয়ভাবে নিরুৎসাহিত করে। এটি একটি যুক্তিসঙ্গত অবস্থান, কারণ লিনাক্স রক্ষণাবেক্ষণকারীরা কার্নেলের ভেতরের সোর্স বা বাইনারি সামঞ্জস্যতা সম্পর্কে কোনো নিশ্চয়তা দেন না এবং ট্রি-এর বাইরে থাকা কোডকে সমর্থন করতে চান না। তবে, GKI ভেন্ডর মডিউলগুলোর জন্য ABI নিশ্চয়তা প্রদান করে , যা নিশ্চিত করে যে একটি কার্নেলের সমর্থিত জীবনকাল জুড়ে KMI ইন্টারফেসগুলো স্থিতিশীল থাকবে। সুতরাং, ভেন্ডর মডিউলগুলোকে সমর্থন করার জন্য এমন এক ধরনের পরিবর্তন রয়েছে যা ACK-এর জন্য গ্রহণযোগ্য হলেও আপস্ট্রিমের জন্য গ্রহণযোগ্য নয়।

উদাহরণস্বরূপ, এমন একটি প্যাচের কথা ভাবুন যা EXPORT_SYMBOL_GPL() ম্যাক্রো যোগ করে, যেখানে এক্সপোর্ট ব্যবহারকারী মডিউলগুলো সোর্স ট্রি-তে নেই। যদিও আপনাকে অবশ্যই আপস্ট্রিম থেকে EXPORT_SYMBOL_GPL() অনুরোধ করার চেষ্টা করতে হবে এবং নতুন এক্সপোর্ট করা সিম্বলটি ব্যবহার করে এমন একটি মডিউল সরবরাহ করতে হবে, যদি মডিউলটি আপস্ট্রিমে জমা না দেওয়ার কোনো বৈধ কারণ থাকে, তবে আপনি এর পরিবর্তে প্যাচটি ACK-তে জমা দিতে পারেন। মডিউলটি কেন আপস্ট্রিম করা যাচ্ছে না, সেই কারণটি আপনাকে ইস্যুটির মধ্যে অন্তর্ভুক্ত করতে হবে। (নন-GPL ভ্যারিয়েন্ট, EXPORT_SYMBOL() , অনুরোধ করবেন না।)

লুকানো কনফিগারেশন

কিছু ইন-ট্রি মডিউল স্বয়ংক্রিয়ভাবে এমন হিডেন কনফিগ নির্বাচন করে যা gki_defconfig এ নির্দিষ্ট করা যায় না। উদাহরণস্বরূপ, যখন CONFIG_SND_SOC_SOF=y কনফিগার করা থাকে, তখন CONFIG_SND_SOC_TOPOLOGY স্বয়ংক্রিয়ভাবে নির্বাচিত হয়। আউট-অফ-ট্রি মডিউল বিল্ড করার সুবিধার্থে, GKI-তে হিডেন কনফিগ সক্রিয় করার একটি ব্যবস্থা রয়েছে।

একটি লুকানো কনফিগারেশন সক্রিয় করতে, init/Kconfig.gki তে একটি select স্টেটমেন্ট যোগ করুন, যাতে এটি gki_defconfig এ সক্রিয় করা CONFIG_GKI_HACKS_TO_FIX কার্নেল কনফিগারেশনের উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে নির্বাচিত হয়। এই পদ্ধতিটি শুধুমাত্র লুকানো কনফিগারেশনের জন্য ব্যবহার করুন; যদি কনফিগারেশনটি লুকানো না থাকে, তবে এটিকে অবশ্যই gki_defconfig এ স্পষ্টভাবে অথবা একটি ডিপেন্ডেন্সি হিসেবে উল্লেখ করতে হবে।

লোডযোগ্য গভর্নর

যেসব কার্নেল ফ্রেমওয়ার্ক (যেমন cpufreq ) লোডেবল গভর্নর সমর্থন করে, সেগুলোর ক্ষেত্রে আপনি ডিফল্ট গভর্নরকে (যেমন cpufreq এর schedutil গভর্নর) ওভাররাইড করতে পারেন। যেসব ফ্রেমওয়ার্ক (যেমন থার্মাল ফ্রেমওয়ার্ক) লোডেবল গভর্নর বা ড্রাইভার সমর্থন করে না, কিন্তু একটি ভেন্ডর-নির্দিষ্ট ইমপ্লিমেন্টেশনের প্রয়োজন হয়, সেগুলোর ক্ষেত্রে IT বিভাগে একটি ইস্যু তৈরি করুন এবং অ্যান্ড্রয়েড কার্নেল টিমের সাথে পরামর্শ করুন।

প্রয়োজনীয় সাপোর্ট যোগ করার জন্য আমরা আপনার এবং আপস্ট্রিম মেইনটেইনারদের সাথে কাজ করব।

বিক্রেতার হুক

পূর্ববর্তী রিলিজগুলিতে, আপনি সরাসরি কোর কার্নেলে ভেন্ডর-নির্দিষ্ট পরিবর্তন যোগ করতে পারতেন। GKI 2.0-তে এটি সম্ভব নয়, কারণ প্রোডাক্ট-নির্দিষ্ট কোড অবশ্যই মডিউলের মধ্যে ইমপ্লিমেন্ট করতে হবে এবং তা কোর কার্নেলের আপস্ট্রিম বা ACK-তে গৃহীত হবে না। কোর কার্নেল কোডের উপর ন্যূনতম প্রভাব ফেলে পার্টনারদের নির্ভর করা ভ্যালু-অ্যাডেড ফিচারগুলো সক্রিয় করার জন্য, GKI ভেন্ডর হুক গ্রহণ করে, যা কোর কার্নেল কোড থেকে মডিউলগুলোকে কল করার সুযোগ দেয়। এছাড়াও, এই ফিচারগুলো ইমপ্লিমেন্ট করার জন্য ভেন্ডর-নির্দিষ্ট ডেটা সংরক্ষণের উদ্দেশ্যে উপলব্ধ ভেন্ডর ডেটা ফিল্ড দিয়ে মূল ডেটা স্ট্রাকচারগুলোকে প্যাড করা যেতে পারে।

ভেন্ডর হুক দুই ধরনের (সাধারণ এবং সীমাবদ্ধ) হয়ে থাকে, যা ট্রেসপয়েন্টের (ট্রেস ইভেন্টের নয়) উপর ভিত্তি করে তৈরি এবং ভেন্ডর মডিউলগুলো এগুলোর সাথে সংযুক্ত হতে পারে। উদাহরণস্বরূপ, টাস্ক শেষ হওয়ার সময় হিসাব রাখার জন্য একটি নতুন sched_exit() ফাংশন যোগ করার পরিবর্তে, ভেন্ডররা do_exit() ফাংশনে একটি হুক যোগ করতে পারে, যার সাথে একটি ভেন্ডর মডিউল প্রসেসিংয়ের জন্য সংযুক্ত হতে পারে। একটি উদাহরণ বাস্তবায়নে নিম্নলিখিত ভেন্ডর হুকগুলো অন্তর্ভুক্ত রয়েছে।

  • সাধারণ ভেন্ডর হুকগুলো DECLARE_HOOK() ব্যবহার করে trace_ name নামের একটি ট্রেসপয়েন্ট ফাংশন তৈরি করে, যেখানে name হলো ট্রেসটির জন্য একটি অনন্য শনাক্তকারী। প্রচলিত নিয়ম অনুযায়ী, সাধারণ ভেন্ডর হুকের নাম android_vh দিয়ে শুরু হয়, তাই sched_exit() হুকটির নাম হবে android_vh_sched_exit
  • শিডিউলার হুকের মতো ক্ষেত্রে রেস্ট্রিকটেড ভেন্ডর হুকের প্রয়োজন হয়, যেখানে সিপিইউ অফলাইন থাকলেও সংযুক্ত ফাংশনটিকে কল করতে হয় অথবা একটি নন-অ্যাটমিক কনটেক্সটের প্রয়োজন হয়। রেস্ট্রিকটেড ভেন্ডর হুক ডিটাচ করা যায় না, তাই যে মডিউলগুলো একটি রেস্ট্রিকটেড হুকের সাথে সংযুক্ত হয়, সেগুলো কখনোই আনলোড হতে পারে না। রেস্ট্রিকটেড ভেন্ডর হুকের নাম android_rvh দিয়ে শুরু হয়।

ভেন্ডর হুক যোগ করতে, IT-তে একটি ইস্যু ফাইল করুন এবং প্যাচ জমা দিন (সমস্ত অ্যান্ড্রয়েড-নির্দিষ্ট প্যাচের মতোই, একটি ইস্যু থাকতে হবে এবং আপনাকে এর যৌক্তিকতা প্রদান করতে হবে)। ভেন্ডর হুকের সাপোর্ট শুধুমাত্র ACK-তে রয়েছে, তাই এই প্যাচগুলি আপস্ট্রিম লিনাক্সে পাঠাবেন না।

কাঠামোতে বিক্রেতা ক্ষেত্রগুলি যোগ করুন

ANDROID_VENDOR_DATA() ম্যাক্রো ব্যবহার করে android_vendor_data ফিল্ড যোগ করার মাধ্যমে আপনি কী ডেটা স্ট্রাকচারের সাথে ভেন্ডর ডেটা যুক্ত করতে পারেন। উদাহরণস্বরূপ, ভ্যালু-অ্যাডেড ফিচার সমর্থন করার জন্য, নিম্নলিখিত কোড স্যাম্পলে দেখানো অনুযায়ী স্ট্রাকচারগুলিতে ফিল্ড যুক্ত করুন।

ভেন্ডরদের প্রয়োজনীয় ফিল্ড এবং OEM-দের প্রয়োজনীয় ফিল্ডের মধ্যে সম্ভাব্য দ্বন্দ্ব এড়ানোর জন্য, OEM-দের কখনোই ANDROID_VENDOR_DATA() ম্যাক্রো ব্যবহার করে ডিক্লেয়ার করা ফিল্ড ব্যবহার করা উচিত নয়। এর পরিবর্তে, OEM-দের android_oem_data ফিল্ড ডিক্লেয়ার করার জন্য ANDROID_OEM_DATA() ব্যবহার করতে হবে।

#include <linux/android_vendor.h>
...
struct important_kernel_data {
  [all the standard fields];
  /* Create vendor data for use by hook implementations. The
   * size of vendor data is based on vendor input. Vendor data
   * can be defined as single u64 fields like the following that
   * declares a single u64 field named "android_vendor_data1" :
   */
  ANDROID_VENDOR_DATA(1);

  /*
   * ...or an array can be declared. The following is equivalent to
   * u64 android_vendor_data2[20]:
   */
  ANDROID_VENDOR_DATA_ARRAY(2, 20);

  /*
   * SoC vendors must not use fields declared for OEMs and
   * OEMs must not use fields declared for SoC vendors.
   */
  ANDROID_OEM_DATA(1);

  /* no further fields */
}

ভেন্ডর হুক সংজ্ঞায়িত করুন

DECLARE_HOOK() বা DECLARE_RESTRICTED_HOOK() ব্যবহার করে ভেন্ডর হুক ঘোষণা করুন এবং তারপরে সেগুলিকে কোডে ট্রেসপয়েন্ট হিসাবে যুক্ত করুন। উদাহরণস্বরূপ, বিদ্যমান do_exit() কার্নেল ফাংশনে trace_android_vh_sched_exit() যুক্ত করতে:

#include <trace/hooks/exit.h>
void do_exit(long code)
{
    struct task_struct *tsk = current;
    ...
    trace_android_vh_sched_exit(tsk);
    ...
}

trace_android_vh_sched_exit() ফাংশনটি প্রাথমিকভাবে শুধু পরীক্ষা করে দেখে যে কিছু সংযুক্ত আছে কিনা। তবে, যদি কোনো ভেন্ডর মডিউল register_trace_android_vh_sched_exit() ব্যবহার করে একটি হ্যান্ডলার রেজিস্টার করে, তাহলে রেজিস্টার করা ফাংশনটি কল করা হয়। হ্যান্ডলারটিকে ধারণ করা লক, RCS অবস্থা এবং অন্যান্য বিষয় সম্পর্কিত প্রেক্ষাপট সম্পর্কে সচেতন থাকতে হবে। হুকটি অবশ্যই include/trace/hooks ডিরেক্টরির একটি হেডার ফাইলে সংজ্ঞায়িত করতে হবে।

উদাহরণস্বরূপ, নিম্নলিখিত কোডটি include/trace/hooks/exit.h ফাইলে trace_android_vh_sched_exit() এর একটি সম্ভাব্য ডিক্লারেশন প্রদান করে।

/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM sched
#define TRACE_INCLUDE_PATH trace/hooks

#if !defined(_TRACE_HOOK_SCHED_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_SCHED_H
#include <trace/hooks/vendor_hooks.h>
/*
 * Following tracepoints are not exported in tracefs and provide a
 * mechanism for vendor modules to hook and extend functionality
 */

struct task_struct;

DECLARE_HOOK(android_vh_sched_exit,
             TP_PROTO(struct task_struct *p),
             TP_ARGS(p));

#endif /* _TRACE_HOOK_SCHED_H */

/* This part must be outside protection */
#include <trace/define_trace.h>

ভেন্ডর হুকের জন্য প্রয়োজনীয় ইন্টারফেসগুলো ইনস্ট্যানশিয়েট করতে, হুক ডিক্লারেশনসহ হেডার ফাইলটি drivers/android/vendor_hooks.c তে যোগ করুন এবং সিম্বলগুলো এক্সপোর্ট করুন। উদাহরণস্বরূপ, নিচের কোডটি android_vh_sched_exit() হুকের ডিক্লারেশন সম্পন্ন করে।

#ifndef __GENKSYMS__
/* struct task_struct */
#include <linux/sched.h>
#endif

#define CREATE_TRACE_POINTS
#include <trace/hooks/vendor_hooks.h>
#include <trace/hooks/exit.h>
/*
 * Export tracepoints that act as a bare tracehook (i.e. have no trace
 * event associated with them) to allow external modules to probe
 * them.
 */
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sched_exit);

দ্রষ্টব্য : ABI স্থিতিশীলতা নিশ্চিত করার জন্য হুক ডিক্লারেশনের মধ্যে ব্যবহৃত ডেটা স্ট্রাকচারগুলোকে সম্পূর্ণরূপে সংজ্ঞায়িত করতে হবে। অন্যথায়, অপেক পয়েন্টারগুলোকে ডিরেফারেন্স করা বা সাইজড কনটেক্সটে স্ট্রাকচারটি ব্যবহার করা অনিরাপদ। এই ধরনের ডেটা স্ট্রাকচারের সম্পূর্ণ সংজ্ঞা প্রদানকারী include ফাইলটি drivers/android/vendor_hooks.c ফাইলের #ifndef __GENKSYMS__ সেকশনের ভিতরে থাকা উচিত। include/trace/hooks এর হেডার ফাইলগুলোতে টাইপ ডেফিনিশনসহ কার্নেল হেডার ফাইলটি অন্তর্ভুক্ত করা উচিত নয়, যাতে CRC পরিবর্তনের কারণে KMI ভেঙে না যায়। এর পরিবর্তে, টাইপগুলোকে ফরওয়ার্ড ডিক্লেয়ার করুন।

ভেন্ডর হুকগুলির সাথে সংযুক্ত করুন

ভেন্ডর হুক ব্যবহার করার জন্য, ভেন্ডর মডিউলকে হুকটির জন্য একটি হ্যান্ডলার রেজিস্টার করতে হয় (যা সাধারণত মডিউল ইনিশিয়ালাইজেশনের সময় করা হয়)। উদাহরণস্বরূপ, নিচের কোডটি foo.ko মডিউলের trace_android_vh_sched_exit() হ্যান্ডলারটি দেখাচ্ছে।

#include <trace/hooks/sched.h>
...
static void foo_sched_exit_handler(void *data, struct task_struct *p)
{
    foo_do_exit_accounting(p);
}
...
static int foo_probe(..)
{
    ...
    rc = register_trace_android_vh_sched_exit(foo_sched_exit_handler, NULL);
    ...
}

হেডার ফাইল থেকে ভেন্ডর হুক ব্যবহার করুন

হেডার ফাইল থেকে ভেন্ডর হুক ব্যবহার করার জন্য, আপনাকে ভেন্ডর হুক হেডার ফাইলটি আপডেট করে TRACE_INCLUDE_PATH অসংজ্ঞায়িত করতে হতে পারে, যাতে ট্রেস পয়েন্ট হেডার ফাইল খুঁজে না পাওয়ার কারণে সৃষ্ট বিল্ড এরর এড়ানো যায়। উদাহরণস্বরূপ,

In file included from .../common/init/main.c:111:
In file included from .../common/include/trace/events/initcall.h:74:
.../common/include/trace/define_trace.h:95:10: fatal error: 'trace/hooks/initcall.h' file not found
   95 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../common/include/trace/define_trace.h:90:32: note: expanded from macro 'TRACE_INCLUDE'
   90 | # define TRACE_INCLUDE(system) __TRACE_INCLUDE(system)
      |                                ^~~~~~~~~~~~~~~~~~~~~~~
.../common/include/trace/define_trace.h:87:34: note: expanded from macro '__TRACE_INCLUDE'
   87 | # define __TRACE_INCLUDE(system) __stringify(TRACE_INCLUDE_PATH/system.h)
      |                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../common/include/linux/stringify.h:10:27: note: expanded from macro '__stringify'
   10 | #define __stringify(x...)       __stringify_1(x)
      |                                 ^~~~~~~~~~~~~~~~
.../common/include/linux/stringify.h:9:29: note: expanded from macro '__stringify_1'
    9 | #define __stringify_1(x...)     #x
      |                                 ^~
<scratch space>:14:1: note: expanded from here
   14 | "trace/hooks/initcall.h"
      | ^~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

এই ধরনের বিল্ড ত্রুটি সমাধান করতে, আপনার অন্তর্ভুক্ত করা ভেন্ডর হুক হেডার ফাইলে সমতুল্য সমাধানটি প্রয়োগ করুন। অতিরিক্ত তথ্যের জন্য, https://r.android.com/3066703 দেখুন।

diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h
index bc6de7e53d66..039926f7701d 100644
--- a/include/trace/hooks/mm.h
+++ b/include/trace/hooks/mm.h
@@ -2,7 +2,10 @@
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM mm

+#ifdef CREATE_TRACE_POINTS
 #define TRACE_INCLUDE_PATH trace/hooks
+#define UNDEF_TRACE_INCLUDE_PATH
+#endif

UNDEF_TRACE_INCLUDE_PATH নির্ধারণ করে দিলে, ট্রেস পয়েন্ট তৈরি করার পর include/trace/define_trace.h ফাইলটিকে TRACE_INCLUDE_PATH কে অনির্ধারিত করে দেওয়ার নির্দেশ দেওয়া হয়।

কোর কার্নেল বৈশিষ্ট্য

যদি পূর্ববর্তী কোনো পদ্ধতিই আপনাকে কোনো মডিউল থেকে একটি ফিচার বাস্তবায়ন করতে সক্ষম না করে, তাহলে আপনাকে অবশ্যই ফিচারটিকে কোর কার্নেলে অ্যান্ড্রয়েড-নির্দিষ্ট পরিবর্তন হিসেবে যুক্ত করতে হবে। আলোচনা শুরু করতে ইস্যু ট্র্যাকারে (আইটি) একটি ইস্যু তৈরি করুন।

ব্যবহারকারী অ্যাপ্লিকেশন প্রোগ্রামিং ইন্টারফেস (UAPI)

  • UAPI হেডার ফাইল। অ্যান্ড্রয়েড-নির্দিষ্ট ইন্টারফেসের পরিবর্তন ছাড়া, UAPI হেডার ফাইলে যেকোনো পরিবর্তন অবশ্যই আপস্ট্রিম থেকে করতে হবে। ভেন্ডর মডিউল এবং ভেন্ডর ইউজারস্পেস কোডের মধ্যে ইন্টারফেস সংজ্ঞায়িত করতে ভেন্ডর-নির্দিষ্ট হেডার ফাইল ব্যবহার করুন।
  • sysfs নোড। GKI কার্নেলে নতুন sysfs নোড যোগ করবেন না (এই ধরনের সংযোজন শুধুমাত্র ভেন্ডর মডিউলের ক্ষেত্রেই বৈধ)। অ্যান্ড্রয়েড ফ্রেমওয়ার্ক গঠনকারী SoC- এবং ডিভাইস-অজ্ঞেয় লাইব্রেরি এবং জাভা কোড দ্বারা ব্যবহৃত sysfs নোডগুলি শুধুমাত্র সামঞ্জস্যপূর্ণ উপায়ে পরিবর্তন করা যেতে পারে এবং যদি সেগুলি অ্যান্ড্রয়েড-নির্দিষ্ট sysfs নোড না হয়, তবে সেগুলিকে অবশ্যই আপস্ট্রিমেই পরিবর্তন করতে হবে। আপনি ভেন্ডর ইউজারস্পেস দ্বারা ব্যবহারের জন্য ভেন্ডর-নির্দিষ্ট sysfs নোড তৈরি করতে পারেন । ডিফল্টরূপে, SELinux ব্যবহার করে ইউজারস্পেস দ্বারা sysfs নোডগুলিতে অ্যাক্সেস অস্বীকার করা হয়। অনুমোদিত ভেন্ডর সফটওয়্যারকে অ্যাক্সেস দেওয়ার জন্য উপযুক্ত SELinux লেবেল যোগ করার দায়িত্ব ভেন্ডরের।
  • DebugFS নোড। ভেন্ডর মডিউলগুলো শুধুমাত্র ডিবাগিংয়ের জন্য debugfs এ নোড সংজ্ঞায়িত করতে পারে (কারণ ডিভাইসের স্বাভাবিক কার্যক্রমের সময় debugfs মাউন্ট করা থাকে না)।