कर्नेल बनाना

इस पेज पर, Android डिवाइसों के लिए कस्टम कर्नल बनाने की प्रोसेस के बारे में बताया गया है. इन निर्देशों में, सही सोर्स चुनने, कर्नल बनाने, और Android Open Source Project (AOSP) से बनाई गई सिस्टम इमेज में नतीजों को एम्बेड करने की प्रोसेस के बारे में बताया गया है.

सोर्स डाउनलोड करना और टूल बनाना

हाल ही के कर्नल के लिए, सोर्स, टूलचेन, और बिल्ड स्क्रिप्ट डाउनलोड करने के लिए, repo का इस्तेमाल करें. कुछ कर्नल (उदाहरण के लिए, Pixel 3 के कर्नल) के लिए, कई गिट रिपॉज़िटरी से सोर्स की ज़रूरत होती है. वहीं, अन्य कर्नल (उदाहरण के लिए, सामान्य कर्नल) के लिए सिर्फ़ एक सोर्स की ज़रूरत होती है. repo अप्रोच का इस्तेमाल करने से, सोर्स डायरेक्ट्री को सही तरीके से सेट अप किया जा सकता है.

सही ब्रांच के लिए सोर्स डाउनलोड करें:

mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync

पिछले `repo init` कमांड के साथ इस्तेमाल की जा सकने वाली रीपो ब्रांच (BRANCH) की सूची देखने के लिए, कर्नेल ब्रांच और उनके बिल्ड सिस्टम देखें.

Pixel डिवाइसों के लिए कर्नल डाउनलोड करने और कंपाइल करने के बारे में जानकारी के लिए, Pixel कर्नल बनाना लेख पढ़ें.

कर्नल बनाना

Bazel (Kleaf) की मदद से बनाना

Android 13 में, Bazel की मदद से कर्नल बनाने की सुविधा जोड़ी गई है.

aarch64 आर्किटेक्चर के लिए GKI कर्नल का डिस्ट्रिब्यूशन बनाने के लिए, Android 13 या इसके बाद के Android Common Kernel की किसी ब्रांच को देखें. इसके बाद, यह कमांड चलाएं:

tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]

इसके बाद, कर्नल बाइनरी, मॉड्यूल, और उनसे जुड़ी इमेज, $DIST_DIR डायरेक्ट्री में मौजूद होती हैं. अगर --destdir की जानकारी नहीं दी गई है, तो आर्टफ़ैक्ट की जगह के लिए, कमांड का आउटपुट देखें. ज़्यादा जानकारी के लिए, AOSP के दस्तावेज़ देखें.

build.sh (लेगसी) की मदद से बनाना

Android 12 या इससे पहले के वर्शन वाले डिवाइसों के लिए, या Kleaf के बिना काम करने वाले डिवाइसों के लिए:

build/build.sh

कर्नल बाइनरी, मॉड्यूल, और इससे जुड़ी इमेज, out/BRANCH/dist डायरेक्ट्री में मौजूद होती हैं.

वर्चुअल डिवाइस के लिए वेंडर मॉड्यूल बनाना

Android 13 में, कर्नेल बनाने के लिए Bazel (Kleaf) का इस्तेमाल किया गया है. इसने build.sh की जगह ले ली है.

virtual_device के मॉड्यूल के लिए डिस्ट्रिब्यूशन बनाने के लिए, यह कमांड चलाएं:

tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist [-- --destdir=$DIST_DIR]

Bazel की मदद से Android कर्नल बनाने के बारे में ज़्यादा जानकारी के लिए, यह लेख पढ़ें. Kleaf - Bazel की मदद से Android कर्नेल बनाना.

अलग-अलग आर्किटेक्चर के लिए Kleaf की सहायता से जुड़ी जानकारी के लिए, डिवाइसों और कर्नल के लिए Kleaf की सहायता लेख पढ़ें.

build.sh (लेगसी) की मदद से, वर्चुअल डिवाइस के लिए वेंडर मॉड्यूल बनाना

Android 12 में, Cuttlefish और Goldfish एक साथ काम करते हैं. इसलिए, ये एक ही कर्नेल का इस्तेमाल करते हैं: virtual_device. उस कर्नेल के मॉड्यूल बनाने के लिए, इस बिल्ड कॉन्फ़िगरेशन का इस्तेमाल करें:

BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh

Android 11 में जीकेआई की सुविधा जोड़ी गई है. इसमें कर्नेल को Google के बनाए हुए कर्नेल इमेज और वेंडर के बनाए हुए मॉड्यूल में अलग किया जाता है. इन दोनों को अलग-अलग बनाया जाता है.

इस उदाहरण में, कर्नल इमेज कॉन्फ़िगरेशन दिखाया गया है:

BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh

इस उदाहरण में, मॉड्यूल कॉन्फ़िगरेशन (Cuttlefish और Emulator) दिखाया गया है:

BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh

कर्नेल चलाना

कस्टम-बिल्ट कर्नल को चलाने के कई तरीके हैं. यहां कुछ ऐसे तरीके दिए गए हैं जो डेवलपमेंट के अलग-अलग चरणों के लिए सही हैं.

Android इमेज बिल्ड में एंबेड करना

Image.lz4-dtb को AOSP ट्री में मौजूद, कर्नेल बाइनरी की जगह पर कॉपी करें. इसके बाद, बूट इमेज को फिर से बनाएं.

इसके अलावा, make bootimage का इस्तेमाल करते समय TARGET_PREBUILT_KERNEL वैरिएबल को तय करें. इसके लिए, make bootimage या बूट इमेज बनाने वाली कोई अन्य make कमांड लाइन का इस्तेमाल करें. यह वैरिएबल सभी डिवाइसों पर काम करता है, क्योंकि इसे device/common/populate-new-device.sh के ज़रिए सेट अप किया जाता है. उदाहरण के लिए:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

fastboot का इस्तेमाल करके, कर्नेल फ़्लैश और बूट करना

हाल ही के ज़्यादातर डिवाइसों में बूटलोडर एक्सटेंशन होता है. इससे बूट इमेज जनरेट करने और बूट करने की प्रोसेस को आसान बनाया जा सकता है.

फ़्लैश किए बिना कर्नल बूट करने के लिए:

adb reboot bootloader
fastboot boot Image.lz4-dtb

इस तरीके का इस्तेमाल करने पर, कर्नल को असल में फ़्लैश नहीं किया जाता. साथ ही, रीबूट करने पर यह बना नहीं रहता.

Cuttlefish पर कर्नल चलाना

Cuttlefish डिवाइसों पर, अपनी पसंद के आर्किटेक्चर में कर्नल चलाए जा सकते हैं.

किसी खास कर्नल आर्टफ़ैक्ट के सेट के साथ Cuttlefish डिवाइस को बूट करने के लिए, cvd create कमांड को टारगेट कर्नल आर्टफ़ैक्ट के साथ पैरामीटर के तौर पर चलाएं. नीचे दिए गए उदाहरण में, common-android14-6.1 कर्नल मेनिफ़ेस्ट से arm64 टारगेट के लिए कर्नल आर्टफ़ैक्ट का इस्तेमाल किया गया है.

cvd create \
    -kernel_path=/$PATH/$TO/common-android14-6.1/out/android14-6.1/dist/Image \
    -initramfs_path=/$PATH/$TO/common-android14-6.1/out/android14-6.1/dist/initramfs.img

ज़्यादा जानकारी के लिए, Cuttlefish पर कर्नल डेवलप करना लेख पढ़ें.

कर्नेल बिल्ड को पसंद के मुताबिक बनाना

Kleaf बिल्ड के लिए कर्नल बिल्ड को पसंद के मुताबिक बनाने के लिए, Kleaf का दस्तावेज़ देखें.

build.sh (लेगसी) की मदद से, कर्नल बिल्ड को अपनी पसंद के मुताबिक बनाना

build/build.sh के लिए, एनवायरमेंट वैरिएबल से बिल्ड प्रोसेस और नतीजे पर असर पड़ सकता है. इनमें से ज़्यादातर विकल्प इस्तेमाल करना ज़रूरी नहीं है. साथ ही, हर कर्नल ब्रांच में डिफ़ॉल्ट कॉन्फ़िगरेशन होना चाहिए. सबसे ज़्यादा इस्तेमाल किए जाने वाले फ़िल्टर यहां दिए गए हैं. पूरी और अप-टू-डेट लिस्ट देखने के लिए, build/build.sh पर जाएं.

एनवायरमेंट वैरिएबल ब्यौरा उदाहरण
BUILD_CONFIG कॉन्फ़िगरेशन फ़ाइल बनाएं, जहां से बिल्ड एनवायरमेंट को शुरू किया जाता है. जगह की जानकारी, Repo root डायरेक्ट्री के हिसाब से तय की जानी चाहिए. यह डिफ़ॉल्ट रूप से build.config पर सेट होता है.
सामान्य कर्नल के लिए ज़रूरी है.
BUILD_CONFIG=common/build.config.gki.aarch64
CC इस्तेमाल किए जाने वाले कंपाइलर को बदलें. यह build.config में तय किए गए डिफ़ॉल्ट कंपाइलर पर वापस आ जाता है. CC=clang
DIST_DIR कर्नेल डिस्ट्रिब्यूशन के लिए, आउटपुट की मूल डायरेक्ट्री. DIST_DIR=/path/to/my/dist
OUT_DIR यह कर्नल बिल्ड के लिए बेस आउटपुट डायरेक्ट्री है. OUT_DIR=/path/to/my/out
SKIP_DEFCONFIG make defconfig स्किप करें SKIP_DEFCONFIG=1
SKIP_MRPROPER make mrproper स्किप करें SKIP_MRPROPER=1

लोकल बिल्ड के लिए कस्टम कर्नल कॉन्फ़िगरेशन

Android 14 और इसके बाद के वर्शन में, कर्नल कॉन्फ़िगरेशन को पसंद के मुताबिक बनाने के लिए, defconfig फ़्रैगमेंट का इस्तेमाल किया जा सकता है. defconfig फ़्रैगमेंट के बारे में Kleaf का दस्तावेज़ देखें.

स्थानीय बिल्ड के लिए कस्टम कर्नल कॉन्फ़िगरेशन, जिसमें बिल्ड कॉन्फ़िगरेशन (लेगसी) शामिल हैं

Android 13 और इससे पुराने वर्शन में, यहां दिया गया तरीका अपनाएं.

अगर आपको कर्नल कॉन्फ़िगरेशन के किसी विकल्प को नियमित तौर पर बदलना है, तो उदाहरण के लिए, किसी सुविधा पर काम करते समय या अगर आपको डेवलपमेंट के मकसद से किसी विकल्प को सेट करना है, तो आपके पास यह सुविधा है. इसके लिए, आपको बिल्ड कॉन्फ़िगरेशन में स्थानीय बदलाव करना होगा या उसकी कॉपी बनानी होगी.

वैरिएबल POST_DEFCONFIG_CMDS को ऐसे स्टेटमेंट पर सेट करें जिसका आकलन, सामान्य make defconfig चरण के पूरा होने के तुरंत बाद किया जाता है. build.config फ़ाइलों को बिल्ड एनवायरमेंट में सोर्स किया जाता है. इसलिए, build.config में तय किए गए फ़ंक्शन को post-defconfig कमांड के हिस्से के तौर पर कॉल किया जा सकता है.

इसका एक सामान्य उदाहरण यह है कि डेवलपमेंट के दौरान, क्रॉसहैच कर्नेल के लिए लिंक टाइम ऑप्टिमाइज़ेशन (एलटीओ) को बंद कर दिया जाता है. एलटीओ, रिलीज़ किए गए कर्नल के लिए फ़ायदेमंद है. हालांकि, बिल्ड टाइम में ओवरहेड काफ़ी ज़्यादा हो सकता है. स्थानीय build.config में जोड़े गए इस स्निपेट से, build/build.sh का इस्तेमाल करते समय LTO हमेशा के लिए बंद हो जाता है.

POST_DEFCONFIG_CMDS="check_defconfig && update_debug_config"
function update_debug_config() {
    ${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \
         -d LTO \
         -d LTO_CLANG \
         -d CFI \
         -d CFI_PERMISSIVE \
         -d CFI_CLANG
    (cd ${OUT_DIR} && \
     make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig)
}

कर्नेल वर्शन की पहचान करना

बनाने के लिए सही वर्शन की पहचान दो सोर्स से की जा सकती है: एओएसपी ट्री और सिस्टम इमेज.

AOSP ट्री से कर्नेल वर्शन

AOSP ट्री में, पहले से बने कर्नल वर्शन मौजूद होते हैं. git log से, कमिट मैसेज के हिस्से के तौर पर सही वर्शन का पता चलता है:

cd $AOSP/device/VENDOR/NAME
git log --max-count=1

अगर कर्नल का वर्शन, git लॉग में नहीं दिया गया है, तो इसे सिस्टम इमेज से हासिल करें. इसके लिए, यहां दिया गया तरीका अपनाएं.

सिस्टम इमेज का कर्नेल वर्शन

सिस्टम इमेज में इस्तेमाल किए गए कर्नल वर्शन का पता लगाने के लिए, कर्नल फ़ाइल के ख़िलाफ़ यह कमांड चलाएं:

file kernel

Image.lz4-dtb फ़ाइलों के लिए, यह कमांड चलाएं:

grep -a 'Linux version' Image.lz4-dtb

बूट इमेज बनाना

कर्नल बिल्ड एनवायरमेंट का इस्तेमाल करके, बूट इमेज बनाई जा सकती है.

init_boot सुविधा वाले डिवाइसों के लिए बूट इमेज बनाना

init_boot पार्टीशन वाले डिवाइसों के लिए, बूट इमेज को कर्नेल के साथ बनाया जाता है. initramfs इमेज, बूट इमेज में एम्बेड नहीं की गई है.

उदाहरण के लिए, Kleaf की मदद से GKI बूट इमेज को इन कमांड के साथ बनाया जा सकता है:

tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]

build/build.sh (लेगसी) की मदद से, GKI बूट इमेज को इन चीज़ों के साथ बनाया जा सकता है:

BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh

GKI बूट इमेज, $DIST_DIR में मौजूद होती है.

init_boot (लेगसी) के बिना डिवाइसों के लिए बूट इमेज बनाना

जिन डिवाइसों में init_boot पार्टिशन नहीं है उनके लिए, आपको रैमडिस्क बाइनरी की ज़रूरत होगी. इसे पाने के लिए, GKI बूट इमेज डाउनलोड करें और उसे अनपैक करें. Android के वर्शन से जुड़ी कोई भी GKI बूट इमेज काम करेगी.

tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv $KERNEL_ROOT/out/ramdisk gki-ramdisk.lz4

टारगेट फ़ोल्डर, कर्नल ट्री की टॉप-लेवल डायरेक्ट्री होती है. यह मौजूदा वर्किंग डायरेक्ट्री होती है.

अगर AOSP की नई रिलीज़ ब्रांच का इस्तेमाल किया जा रहा है, तो ci.android.com पर aosp_arm64 बिल्ड से ramdisk-recovery.img बिल्ड आर्टफ़ैक्ट डाउनलोड करें. इसके बाद, इसे ramdisk बाइनरी के तौर पर इस्तेमाल करें.

अगर आपके पास ramdisk बाइनरी है और आपने इसे कर्नल बिल्ड की रूट डायरेक्ट्री में gki-ramdisk.lz4 पर कॉपी कर दिया है, तो बूट इमेज जनरेट की जा सकती है. इसके लिए, यह कमांड चलाएं:

BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=Image GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh

अगर आपको x86 पर आधारित आर्किटेक्चर का इस्तेमाल करना है, तो Image को bzImage से और aarch64 को x86_64 से बदलें:

BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=bzImage GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh

यह फ़ाइल, आर्टफ़ैक्ट डायरेक्ट्री $KERNEL_ROOT/out/$KERNEL_VERSION/dist में मौजूद है.

बूट इमेज, out/<kernel branch>/dist/boot.img पर मौजूद है.