इस पेज पर, Android डिवाइसों के लिए कस्टम कर्नल बनाने की प्रोसेस के बारे में बताया गया है. इन निर्देशों में, सही सोर्स चुनने, कर्नेल बनाने, और Android Open Source Project (AOSP) से बनाई गई सिस्टम इमेज में नतीजों को जोड़ने की प्रोसेस के बारे में बताया गया है.
Repo का इस्तेमाल करके, ज़्यादा नए कर्नेल सोर्स हासिल किए जा सकते हैं. साथ ही, सोर्स चेकआउट के रूट से build/build.sh
को चलाकर, उन्हें बिना किसी कॉन्फ़िगरेशन के बिल्ड किया जा सकता है.
सोर्स और बिल्ड टूल डाउनलोड करना
हाल ही के कर्नेल के लिए, सोर्स, टूलचेन, और बिल्ड स्क्रिप्ट डाउनलोड करने के लिए, repo
का इस्तेमाल करें.
कुछ कर्नेल (उदाहरण के लिए, Pixel 3 के कर्नेल) के लिए, कई git रिपॉज़िटरी के सोर्स की ज़रूरत होती है. वहीं, कुछ अन्य कर्नेल (उदाहरण के लिए, सामान्य कर्नेल) के लिए, सिर्फ़ एक सोर्स की ज़रूरत होती है. 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 में, 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 में, build.sh
की जगह Bazel (Kleaf) का इस्तेमाल करके, कर्नेल बनाने की सुविधा जोड़ी गई है.
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 में, कटलफ़िश और गोल्डफ़िश एक साथ काम करते हैं. इसलिए, वे एक ही कर्नेल का इस्तेमाल करते हैं: 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
ज़्यादा जानकारी के लिए, Cuttlefish पर कर्नेल डेवलप करना लेख पढ़ें.
कर्नेल बिल्ड को पसंद के मुताबिक बनाना
Kleaf बिल्ड के लिए, पसंद के मुताबिक कर्नेल बिल्ड बनाने के लिए, Kleaf दस्तावेज़ देखें.
build.sh (लेगसी) की मदद से, अपनी पसंद के मुताबिक कर्नेल बिल्ड करना
build/build.sh
के लिए, बिल्ड प्रोसेस और नतीजे पर, एनवायरमेंट वैरिएबल का असर पड़ सकता है.
इनमें से ज़्यादातर विकल्प ज़रूरी नहीं हैं. साथ ही, हर कर्नेल ब्रैंच के साथ सही डिफ़ॉल्ट कॉन्फ़िगरेशन होना चाहिए. सबसे ज़्यादा इस्तेमाल किए जाने वाले विकल्पों की सूची यहां दी गई है. पूरी (और अप-टू-डेट) सूची देखने के लिए, build/build.sh
पर जाएं.
एनवायरमेंट वैरिएबल | ब्यौरा | उदाहरण |
---|---|---|
BUILD_CONFIG |
वह कॉन्फ़िगरेशन फ़ाइल जिससे बिल्ड एनवायरमेंट को शुरू किया जाता है.
जगह को रिपॉज़िटरी की रूट डायरेक्ट्री के हिसाब से तय करना चाहिए. डिफ़ॉल्ट रूप से, यह 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 कमांड के हिस्से के तौर पर कॉल किया जा सकता है.
इसका एक सामान्य उदाहरण, डेवलपमेंट के दौरान क्रॉसहैच
केर्नेल के लिए, लिंक टाइम ऑप्टिमाइज़ेशन (एलटीओ) को बंद करना है. 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)
}
kernel वर्शन की पहचान करना
बिल्ड करने के लिए सही वर्शन की पहचान, दो सोर्स से की जा सकती है: 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
पार्टीशन नहीं है उनके लिए, आपको रैमडिस्क बाइनरी की ज़रूरत होगी. इसे पाने के लिए, 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 बाइनरी हो और आपने उसे kernel build की रूट डायरेक्ट्री में 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
पर मौजूद है.