हमने Android कर्नेल पर गाइड कवर किए हैं, जैसे "How to Build a Custom Kernel" और "Best Custom Kernels for Android", लेकिन आज हम आपको दिखाएंगे कि अपने कर्नेल को नवीनतम Linux-stable के खिलाफ अपस्ट्रीम कैसे करें।
कृपया जान लें कि यह उन्नत सामान है - यदि आपने पहले कभी कर्नेल कंपाइल नहीं किया है, तो आपको ऊपर लिंक किए गए गाइड "How to Build a Custom Kernel" का पालन करना चाहिए, और इस गाइड में नवीनतम Linux-stable कर्नेल से अपने Android कर्नेल के साथ चेरी-पिकिंग और मर्जिंग कमिट शामिल होंगे इससे पहले कि आप इसे कंपाइल करें।
अपने Android कर्नेल को नवीनतम Linux stable पर अपस्ट्रीम करने के बहुत सारे सकारात्मक लाभ हैं, जैसे नवीनतम सुरक्षा कमिट और बगफिक्स के साथ अद्यतित रहना - हम इस गाइड में बाद में कुछ फायदे और नुकसान समझाएंगे।
Linux-Stable कर्नेल क्या है?
Linux-stable जैसा कि नाम से पता चलता है, Linux कर्नेल का स्थिर शाखा है। दूसरी शाखा को "मेनलाइन" के रूप में जाना जाता है, जो मास्टर ब्रांच है। सभी Linux कर्नेल विकास मेनलाइन में होता है, और आम तौर पर इस प्रक्रिया का पालन करता है:
- Linus Torvalds दो सप्ताह के लिए अपने मेंटेनर्स से पैच का एक गुच्छा लेंगे।
- इस दो सप्ताह के बाद, वे एक rc1 (उदाहरण: 4.14-rc1) कर्नेल जारी करेंगे।
- अगले 6-8 सप्ताह के लिए प्रत्येक सप्ताह, वे एक और RC (उदाहरण: 4.14-rc2, 4.14-rc3, आदि) कर्नेल जारी करेंगे, जिसमें केवल बग और रिग्रेशन फिक्स होते हैं।
- एक बार जब यह स्थिर माना जाता है, तो इसे org पर डाउनलोड के लिए tarball के रूप में जारी किया जाएगा (उदाहरण: 4.14)।
LTS कर्नेल क्या हैं?
हर साल, Greg एक कर्नेल चुनेगा और इसे या तो दो साल (LTS) या छह साल (एक्सटेंडेड LTS) के लिए बनाए रखेगा। ये उन उत्पादों के लिए डिज़ाइन किए गए हैं जिन्हें स्थिरता की आवश्यकता होती है (जैसे Android फोन या अन्य IoT डिवाइस)। प्रक्रिया ऊपर जैसी ही है, यह बस लंबे समय तक होती है। वर्तमान में छह LTS कर्नेल हैं (जिन्हें हमेशा kernel.org रिलीज़ पेज पर देखा जा सकता है):
- 4.14 (LTS), Greg Kroah-Hartman द्वारा अनुरक्षित
- 4.9 (LTS), Greg Kroah-Hartman द्वारा अनुरक्षित
- 4.4 (eLTS), Greg Kroah-Hartman द्वारा अनुरक्षित
- 4.1(LTS), Sasha Levin द्वारा अनुरक्षित
- 3.16 (LTS), Ben Hutchings द्वारा अनुरक्षित
- 3.2 (LTS), Ben Hutchings द्वारा अनुरक्षित
मेरे Android कर्नेल को Linux Stable पर अपस्ट्रीम करने के क्या लाभ हैं?
जब महत्वपूर्ण कमजोरियों का खुलासा/फिक्स किया जाता है, तो स्टेबल कर्नेल उन्हें प्राप्त करने वाले पहले होते हैं। इस प्रकार, आपका Android कर्नेल हमलों, सुरक्षा खामियों, और सामान्य रूप से बग्स के खिलाफ बहुत सुरक्षित होगा।
Linux stable में उन बहुत सारे ड्राइवर्स के लिए फिक्स शामिल हैं जिनका मेरा Android डिवाइस उपयोग नहीं करता, क्या यह ज्यादातर अनावश्यक नहीं है?
हां और नहीं, इस पर निर्भर करता है कि आप "ज्यादातर" को कैसे परिभाषित करते हैं। Linux कर्नेल में बहुत सारा कोड शामिल हो सकता है जो Android सिस्टम में अप्रयुक्त रहता है, लेकिन यह गारंटी नहीं देता कि नए संस्करणों को मर्ज करते समय उन फाइलों से कोई संघर्ष नहीं होगा! समझें कि वस्तुतः कोई भी कर्नेल के हर एक हिस्से को नहीं बनाता, यहां तक कि Ubuntu या Mint जैसे सबसे आम Linux डिस्ट्रोस भी नहीं। इसका मतलब यह नहीं है कि आपको ये फिक्स नहीं लेने चाहिए क्योंकि उन ड्राइवर्स के लिए फिक्स हैं जो आप चलाते हैं। उदाहरण के लिए arm/arm64 और ext4 लें, जो क्रमशः सबसे आम Android आर्किटेक्चर और फाइल सिस्टम हैं। 4.4 में, 4.4.78 (नवीनतम Oreo CAF टैग का संस्करण) से 4.4.121 (नवीनतम अपस्ट्रीम टैग) तक, उन सिस्टम के लिए कमिट्स की निम्नलिखित संख्याएं हैं:
nathan@flashbox ~/kernels/linux-stable (master) $ git log --format=%h v4.4.78..v4.4.121 | wc -l2285 nathan@flashbox ~/kernels/linux-stable (master) $ git log --format=%h v4.4.78..v4.4.121 arch/arm | wc -l58 nathan@flashbox ~/kernels/linux-stable (master) $ git log --format=%h v4.4.78..v4.4.121 arch/arm64 | wc -l22 nathan@flashbox ~/kernels/linux-stable (master) $ git log --format=%h v4.4.78..v4.4.121 fs/ext4 | wc -l18
सबसे समय लेने वाला हिस्सा प्रारंभिक लाना है; एक बार जब आप पूरी तरह से अद्यतित हो जाते हैं, तो एक नए रिलीज़ को मर्ज करने में बिल्कुल भी समय नहीं लगता, जिसमें आमतौर पर 100 से अधिक कमिट नहीं होते। यह लाभ लाता है (आपके उपयोगकर्ताओं के लिए अधिक स्थिरता और बेहतर सुरक्षा) इस प्रक्रिया को आवश्यक बनाना चाहिए।
Linux Stable कर्नेल को Android कर्नेल में कैसे मर्ज करें
सबसे पहले आपको यह पता लगाने की आवश्यकता है कि आपका Android डिवाइस किस कर्नेल संस्करण पर चल रहा है।
जितना तुच्छ यह लगता है, यह जानना आवश्यक है कि आपको कहां से शुरू करने की आवश्यकता है। अपने कर्नेल ट्री में निम्नलिखित कमांड चलाएं:
make kernelversion
यह आपको उस संस्करण को वापस कर देगा जिस पर आप हैं। पहली दो संख्याओं का उपयोग उस शाखा को निर्धारित करने के लिए किया जाएगा जिसकी आपको आवश्यकता है (उदाहरण: किसी भी 4.4 कर्नेल के लिए linux-4.4.y) और अंतिम संख्या का उपयोग यह निर्धारित करने के लिए किया जाएगा कि आपको किस संस्करण से मर्ज करना शुरू करना है (उदाहरण: यदि आप 4.4.21 पर हैं, तो आप अगले 4.4.22 मर्ज करेंगे)।
kernel.org से नवीनतम कर्नेल स्रोत प्राप्त करें
kernel.org linux-stable रिपॉजिटरी में नवीनतम कर्नेल स्रोत रखता है। उस पेज के नीचे, तीन fetch लिंक होंगे। मेरे अनुभव में, Google का मिरर सबसे तेज़ होता है लेकिन आपके परिणाम भिन्न हो सकते हैं। निम्नलिखित कमांड चलाएं:
git remote add linux-stable https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git git fetch linux-stable
तय करें कि आप पूरे कर्नेल को मर्ज करना चाहते हैं या कमिट्स को चेरी-पिक करना चाहते हैं
अगला, आपको यह चुनने की आवश्यकता होगी कि आप कमिट्स को मर्ज करना चाहते हैं या चेरी-पिक करना चाहते हैं। यहां प्रत्येक के फायदे और नुकसान हैं और आप उन्हें कब करना चाह सकते हैं।
नोट: यदि आपका कर्नेल स्रोत tarball के रूप में है, तो आपको सबसे अधिक संभावना चेरी-पिक करने की आवश्यकता होगी, अन्यथा आपको हजारों फाइल संघर्ष मिलेंगे क्योंकि git इतिहास को विशुद्ध रूप से अपस्ट्रीम के आधार पर पॉपुलेट कर रहा है, न कि OEM या CAF ने क्या बदला है। बस चरण 4 पर जाएं।
चेरी-पिकिंग:
फायदे:
- संघर्षों को हल करना आसान है क्योंकि आप जानते हैं कि कौन सा संघर्ष समस्या पैदा कर रहा है।
- रीबेस करना आसान है क्योंकि प्रत्येक कमिट अपने आप में है।
- समस्या होने पर बाइसेक्ट करना आसान है
नुकसान:
- इसमें अधिक समय लगता है क्योंकि प्रत्येक कमिट को व्यक्तिगत रूप से चुना जाना चाहिए।
- पहली नज़र में यह बताना थोड़ा अधिक कठिन है कि कमिट अपस्ट्रीम से है या नहीं
मर्ज
फायदे:
- यह तेज़ है क्योंकि आपको सभी क्लीन पैच के मर्ज होने का इंतजार नहीं करना पड़ता।
- यह देखना आसान है कि कमिट अपस्ट्रीम से कब है क्योंकि आप कमिटर नहीं होंगे, अपस्ट्रीम मेंटेनर होगा।
नुकसान:
- संघर्षों को हल करना थोड़ा अधिक कठिन हो सकता है क्योंकि आपको यह देखने के लिए git log/git blame का उपयोग करके देखना होगा कि कौन सा कमिट संघर्ष पैदा कर रहा है, यह आपको सीधे नहीं बताएगा।
- रीबेस करना कठिन है क्योंकि आप एक मर्ज को रीबेस नहीं कर सकते, यह सभी कमिट्स को व्यक्तिगत रूप से चेरी-पिक करने की पेशकश करेगा। हालांकि, आपको अक्सर रीबेस नहीं करना चाहिए, इसके बजाय जहां संभव हो git revert और git merge का उपयोग करना चाहिए।
मैं प्रारंभ में किसी भी समस्या संघर्ष का पता लगाने के लिए चेरी-पिक करने की सिफारिश करूंगा, एक मर्ज करूंगा, फिर बाद में समस्या कमिट्स को वापस ले लूंगा ताकि अपडेट करना आसान हो (क्योंकि अपडेट होने के बाद मर्ज करना तेज़ है)।
अपने स्रोत में कमिट्स जोड़ें, एक समय में एक संस्करण
इस प्रक्रिया का सबसे महत्वपूर्ण हिस्सा एक समय में एक संस्करण वाला हिस्सा है। आपकी अपस्ट्रीम श्रृंखला में एक समस्या पैच हो सकता है, जो बूटिंग के साथ समस्या पैदा कर सकता है या साउंड या चार्जिंग जैसी किसी चीज़ को तोड़ सकता है (टिप्स और ट्रिक्स सेक्शन में समझाया गया है)। इंक्रीमेंटल संस्करण परिवर्तन करना इस कारण से महत्वपूर्ण है, 50 कमिट्स में समस्या ढूंढना 2000 से अधिक कमिट्स के लिए कुछ संस्करणों की तुलना में आसान है। मैं केवल एक पूर्ण मर्ज करने की सिफारिश करूंगा एक बार जब आप सभी समस्या कमिट्स और संघर्ष समाधान जानते हैं।
चेरी-पिकिंग
प्रारूप:
git cherry-pick..
उदाहरण:
git cherry-pick v3.10.73..v3.10.74
मर्ज
प्रारूप:
git merge
उदाहरण:
git merge v3.10.74
मैं मर्ज कमिट्स में संघर्षों को # मार्कर्स को हटाकर ट्रैक रखने की सिफारिश करता हूं।
संघर्षों को कैसे हल करें
हम हर एक संघर्ष को हल करने के लिए चरण-दर-चरण गाइड नहीं दे सकते, क्योंकि इसमें C भाषा का अच्छा ज्ञान शामिल है, लेकिन यहां कुछ संकेत हैं।
यदि आप मर्ज कर रहे हैं, तो पता लगाएं कि कौन सा कमिट संघर्ष पैदा कर रहा है। आप इसे दो तरीकों में से एक कर सकते हैं:
- git log -p v$(make kernelversion)..
अपने वर्तमान संस्करण और अपस्ट्रीम से नवीनतम के बीच परिवर्तन प्राप्त करने के लिए। -p फ्लैग आपको प्रत्येक कमिट द्वारा किए गए परिवर्तन देगा ताकि आप देख सकें। - फाइल पर git blame चलाकर क्षेत्र में प्रत्येक कमिट के हैश प्राप्त करें। फिर आप git show --format=fuller चला सकते हैं यह देखने के लिए कि कमिटर मेनलाइन/स्टेबल, Google, या CodeAurora से था।
- पता लगाएं कि क्या आपके पास पहले से ही कमिट है। Google या CAF जैसे कुछ वेंडर महत्वपूर्ण बग्स के लिए अपस्ट्रीम देखेंगे, जैसे Dirty COW फिक्स, और उनके बैकपोर्ट्स अपस्ट्रीम के साथ संघर्ष कर सकते हैं। आप git log --grep="
" चला सकते हैं और देख सकते हैं कि क्या यह कुछ लौटाता है। यदि यह करता है, तो आप कमिट को छोड़ सकते हैं (यदि चेरी-पिकिंग कर रहे हैं तो git reset --hard && git cherry-pick --continue) या संघर्षों को अनदेखा करें (<<<<<<< और ======= और >>>>>>> के बीच सब कुछ हटा दें)। - पता लगाएं कि क्या कोई बैकपोर्ट है जो रिजॉल्यूशन को खराब कर रहा है। Google और CAF कुछ पैच को बैकपोर्ट करना पसंद करते हैं जो स्टेबल नहीं करेगा। स्टेबल को अक्सर मेनलाइन कमिट के रिजॉल्यूशन को उन पैच की अनुपस्थिति के अनुकूल बनाने की आवश्यकता होगी जो Google बैकपोर्ट करना चुनता है। आप git show
चलाकर मेनलाइन कमिट को देख सकते हैं (मेनलाइन हैश स्टेबल कमिट के कमिट संदेश में उपलब्ध होगा)। यदि कोई बैकपोर्ट इसे खराब कर रहा है, तो आप या तो परिवर्तनों को त्याग सकते हैं या आप मेनलाइन संस्करण का उपयोग कर सकते हैं (जो आमतौर पर आपको करना होगा)। - पढ़ें कि कमिट क्या करने की कोशिश कर रहा है और देखें कि क्या समस्या पहले से ही हल हो चुकी है। कभी-कभी CAF अपस्ट्रीम से स्वतंत्र रूप से बग ठीक कर सकता है, जिसका अर्थ है कि आप या तो उनके फिक्स को अपस्ट्रीम के लिए ओवरराइट कर सकते हैं या इसे त्याग सकते हैं, ऊपर की तरह।
अन्यथा, यह केवल CAF/Google/OEM जोड़ का परिणाम हो सकता है, जिस स्थिति में आपको बस कुछ चीजों को इधर-उधर करने की आवश्यकता है।
यहां linux-stable kernel.org रिपॉजिटरी का एक मिरर GitHub पर है, जो कमिट लिस्ट और संघर्ष रिजॉल्यूशन के लिए डिफ्स को देखने के लिए आसान हो सकता है। मैं पहले कमिट लिस्ट व्यू पर जाने और समस्या कमिट का पता लगाने की सिफारिश करता हूं ताकि मूल डिफ को अपने साथ तुलना करने के लिए देख सकें।
उदाहरण URL: https://github.com/nathanchance/linux-stable/commits/linux-3.10.y/arch/arm64/mm/mmu.c
आप इसे कमांड लाइन के माध्यम से भी कर सकते हैं:
git log.. git show
रिजॉल्यूशन हल करना पूरी तरह से संदर्भ के बारे में है। आपको हमेशा यह सुनिश्चित करना चाहिए कि आपका अंतिम डिफ अपस्ट्रीम के साथ मेल खाता है निम्नलिखित कमांड को दो अलग-अलग विंडो में चलाकर:
git diff HEAD git diff v$(make kernelversion)..$(git tag --sort=-taggerdate -l v$(make kernelversion | cut -d . -f 1,2)* | head -n1)
rerere सक्षम करें
Git में rerere (Reuse Recorded Resolution के लिए खड़ा है) नामक एक विशेषता है, जिसका अर्थ है कि जब यह एक संघर्ष का पता लगाता है, तो यह रिकॉर्ड करेगा कि आपने इसे कैसे हल किया ताकि आप बाद में इसका पुन: उपयोग कर सकें। यह विशेष रूप से क्रॉनिक रीबेसर्स के लिए मर्जिंग और चेरी-पिकिंग दोनों के साथ सहायक है क्योंकि आपको केवल git add . && git
इसे अपने कर्नेल रेपो में निम्नलिखित कमांड चलाकर सक्षम किया जा सकता है:
git config rerere.enabled true
कंपाइलर या रनटाइम त्रुटि में चलने पर git bisect कैसे करें
चूंकि आप एक बड़ी संख्या में कमिट्स जोड़ रहे होंगे, यह बहुत संभव है कि आप एक कंपाइलर या रनटाइम त्रुटि पेश करेंगे। बस हार मानने के बजाय, आप git के बिल्ट-इन बाइसेक्ट टूल का उपयोग करके समस्या का मूल कारण जान सकते हैं! आदर्श रूप से, आप हर एक कर्नेल संस्करण को बिल्ड और फ्लैश करेंगे जैसे ही आप इसे जोड़ते हैं ताकि बाइसेक्टिंग में कम समय लगे यदि आवश्यक हो लेकिन आप बिना किसी समस्या के 5000 कमिट्स को बाइसेक्ट कर सकते हैं।
git bisect क्या करेगा वह कमिट्स की एक रेंज लेगा, जहां से समस्या मौजूद है जहां यह मौजूद नहीं थी, और फिर कमिट रेंज को आधा करना शुरू कर देगा, जिससे आप बिल्ड और टेस्ट कर सकेंगे और इसे बता सकेंगे कि यह अच्छा है या नहीं। यह तब तक जारी रहेगा जब तक यह आपके मुद्दे का कारण बनने वाला कमिट नहीं निकाल देता। उस बिंदु पर, आप या तो इसे ठीक कर सकते हैं या इसे वापस ले सकते हैं।
- बाइसेक्टिंग शुरू करें: git bisect start
- वर्तमान रिवीजन को खराब के रूप में लेबल करें: git bisect bad
- एक रिवीजन को अच्छे के रूप में लेबल करें: git bisect good
- नए रिवीजन के साथ बिल्ड करें
- परिणाम के आधार पर (यदि समस्या मौजूद है या नहीं), git को बताएं: git bisect good OR git bisect bad
- चरण 4-5 को तब तक दोहराएं जब तक समस्या कमिट न मिल जाए!
- समस्या कमिट को वापस लें या ठीक करें।
नोट: मर्जर्स को अस्थायी रूप से git rebase -i
अपस्ट्रीम अपडेट्स को स्क्वैश न करें
बहुत सारे नए डेवलपर्स ऐसा करने के लिए ललचाते हैं क्योंकि यह "क्लीनर" और "आसान" है प्रबंधन करने के लिए। यह कुछ कारणों से भयानक है:
- लेखकत्व खो जाता है। अन्य डेवलपर्स के लिए उनके काम के लिए क्रेडिट छीन लिया जाना अनुचित है।
- बाइसेक्टिंग असंभव है। यदि आप कमिट्स की एक श्रृंखला को स्क्वैश करते हैं और उस श्रृंखला में कुछ समस्या है, तो स्क्वैश में कौन सा कमिट समस्या पैदा करता है यह बताना असंभव है।
- भविष्य के चेरी-पिक्स कठिन हैं। यदि आपको स्क्वैश की गई श्रृंखला के साथ रीबेस करने की आवश्यकता है, तो यह बताना मुश्किल/असंभव है कि संघर्ष कहां से परिणामित होता है।
समय पर अपडेट के लिए Linux Kernel मेलिंग लिस्ट की सदस्यता लें
जब भी कोई अपस्ट्रीम अपडेट होता है तो सूचित होने के लिए, linux-kernel-announce सूची की सदस्यता लें। यह आपको हर बार ईमेल प्राप्त करने की अनुमति देगा जब एक नया कर्नेल जारी किया जाता है ताकि आप अपडेट कर सकें और जितनी जल्दी हो सके पुश कर सकें।