बिल्ड कर्नेल

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

Repo का इस्तेमाल करके, हाल ही के कर्नेल सोर्स हासिल किए जा सकते हैं. साथ ही, सोर्स चेकआउट के रूट से build/build.sh को चलाकर, उन्हें बिना किसी कॉन्फ़िगरेशन के बनाए जा सकते हैं.

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

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

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

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

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

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

कर्नेल बनाएं

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

Android 13 में, Baze के साथ बिल्डिंग कर्नेल पेश किए गए.

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 में, build.sh की जगह Bazel (Kleaf) का इस्तेमाल करके, कर्नेल बनाने की सुविधा जोड़ी गई है.

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

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

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

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

बिल्ड.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 और Emulator) दिखाया गया है:

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

कर्नेल चलाना

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

Android इमेज बिल्ड में जोड़ना

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

इसके अलावा, make bootimage (या बूट इमेज बनाने वाली किसी भी make कमांड लाइन) का इस्तेमाल करते समय, TARGET_PREBUILT_KERNEL वैरिएबल तय करें. यह वैरिएबल सभी डिवाइसों पर काम करता है, क्योंकि इसे 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

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

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

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

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

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

एनवायरमेंट वैरिएबल ब्यौरा उदाहरण
BUILD_CONFIG वह कॉन्फ़िगरेशन फ़ाइल जहां से बिल्ड एनवायरमेंट को शुरू किया जाता है. जगह को रिपॉज़िटरी की रूट डायरेक्ट्री के हिसाब से तय करना चाहिए. डिफ़ॉल्ट तौर पर, यह build.config पर सेट होता है.
सामान्य कर्नेल के लिए ज़रूरी है.
BUILD_CONFIG=common/build.config.gki.aarch64
CC इस्तेमाल किए जाने वाले कंपाइलर को बदलें. build.config से तय किए गए डिफ़ॉल्ट compilers पर वापस आ जाता है. 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 कमांड के हिस्से के तौर पर कॉल किया जा सकता है.

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

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)
}

kernel वर्शन की पहचान करना

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

AOSP ट्री से लिया गया kernel वर्शन

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

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

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

सिस्टम इमेज से Kernel वर्शन

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

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 main का इस्तेमाल करके डेवलप किया जा रहा है, तो इसके बजाय ci.android.com पर, ramdisk-recovery.img 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 पर मौजूद है.