कर्नेल बनाना

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

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

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

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

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

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

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 में GKIकी सुविधा जोड़ी गई है. इससे कर्नेल को, Google के बनाए कर्नेल इमेज और वेंडर के बनाए मॉड्यूल में बांटा जाता है. इन्हें अलग-अलग बनाया जाता है.

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

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

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

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

कर्नेल चलाना

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

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

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

इसके अलावा, 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 की रूट डायरेक्ट्री के हिसाब से, जगह तय की जानी चाहिए. डिफ़ॉल्ट तौर पर, 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 में तय किए गए फ़ंक्शन को, पोस्ट-defconfig कमांड के तौर पर कॉल किया जा सकता है.

इसका एक सामान्य उदाहरण, डेवलपमेंट के दौरान crosshatch कर्नेल के लिए, लिंक टाइम ऑप्टिमाइज़ेशन (LTO) को बंद करना है. LTO, रिलीज़ किए गए कर्नेल के लिए फ़ायदेमंद है. हालांकि, बिल्ड के दौरान इसका ओवरहेड काफ़ी ज़्यादा हो सकता है. स्थानीय 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 ट्री से कर्नेल वर्शन

AOSP ट्री में, कर्नेल के पहले से बने वर्शन शामिल होते हैं. Git लॉग में, कमिट मैसेज के हिस्से के तौर पर सही वर्शन दिखता है:

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` पार्टिशन के बिना वाले डिवाइसों के लिए, ramdisk बाइनरी की ज़रूरत होती है. इसेGKI बूट इमेज डाउनलोड करके और अनपैक करके हासिल किया जा सकता है. एसोसिएटेड Android रिलीज़ की कोई भी GKI बूट इमेज काम करेगी.

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

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

अगर AOSP के सबसे नए रिलीज़ ब्रांच के साथ डेवलपमेंट किया जा रहा है, तो ramdisk-recovery.img बिल्ड आर्टफ़ैक्ट को ci.android.com पर aosp_arm64 बिल्ड से डाउनलोड किया जा सकता है. इसके बाद, इसे 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 पर मौजूद होती है.