एक कर्नेल रूट विभाजन को कैसे माउंट करता है?


29

मेरा प्रश्न एक अलग / बूट विभाजन से लिनक्स सिस्टम को बूट करने के संबंध में है। यदि अधिकांश कॉन्फ़िगरेशन फ़ाइलें एक अलग / विभाजन पर स्थित हैं, तो कर्नेल बूट समय पर इसे सही ढंग से कैसे माउंट करता है?

इस पर कोई भी विस्तार बहुत अच्छा होगा। मुझे लगता है जैसे मुझे कुछ बुनियादी याद आ रहा है। मैं ज्यादातर संचालन की प्रक्रिया और व्यवस्था से चिंतित हूं।

धन्यवाद!

संपादित करें: मुझे लगता है कि मुझे जो पूछना चाहिए वह रूट कर्नेल पैरामीटर में उपयोग की जाने वाली देव फ़ाइल की रेखाओं के साथ अधिक था। उदाहरण के लिए, मान लें कि मैं अपने मूल को रूट = / dev / sda2 के रूप में देता हूं। कर्नेल के पास / dev / sda2 फ़ाइल की मैपिंग कैसे होती है?


हालांकि नीचे के लोग initrd को कवर करते हैं, फिर भी इस बारे में बहुत कम चर्चा होती है कि initrd का उपयोग क्यों किया जाता है। मेरी धारणा यह है कि क्योंकि डिबियन जैसे वितरण एक ही वास्तुकला के कई अलग-अलग मशीनों पर एक कर्नेल का उपयोग करना चाहते हैं, लेकिन संभवतः व्यापक रूप से अलग हार्डवेयर। यह कर्नेल मॉड्यूल के माध्यम से हार्डवेयर समर्थन को संशोधित करके संभव बनाया गया है। Initrd को बूट करने के लिए बहुत अधिक हार्डवेयर समर्थन की आवश्यकता नहीं है, और एक बार ऐसा करने के बाद, यह आगे बढ़ने के लिए आवश्यक हार्डवेयर मॉड्यूल को लोड करता है। इसको विस्तार / सुधार की सराहना की जाती है।
फहीम मीठा

आप पहले / माउंट किए बिना / बूट माउंट नहीं कर सकते हैं, क्योंकि / के बिना कोई बूट निर्देशिका नहीं है।
15

जवाबों:


20

लिनक्स प्रारंभ में एक रैमडिस्क के साथ बूट करता है (जिसे initrd"INITial रामडिस्क" के रूप में कहा जाता है) /। यह डिस्क इस पर पर्याप्त है कि वास्तविक रूट विभाजन (किसी भी ड्राइवर और फाइलसिस्टम मॉड्यूल सहित) को खोजने में सक्षम हो। यह पर एक अस्थायी बिंदु माउंट पर जड़ विभाजन mounts initrd, तो invokes pivot_root(8), जड़ और अस्थायी माउंट पॉइंट स्वैप करने के लिए छोड़ रहा है initrdएक स्थिति होने के लिए में umountएड और पर वास्तविक जड़ फाइल सिस्टम /


2
क्या होगा यदि आपके पास LFS (linuxfromscratch.org) की तरह एक initrd नहीं है?
श्री शिखाडांस

@श्री। Shickadance: एलएफएस चीजों को कैसे देखा जाता है, इस पर ध्यान नहीं देने पर, मुझे लगता है कि वे सुनिश्चित करेंगे कि कर्नेल में सभी आवश्यक मॉड्यूल संकलित हैं (या GRUB 2 के माध्यम से लोड किया गया है, जो संभावना काफी नया है कि कई वितरणों ने अभी तक इस पर ध्यान नहीं दिया है) वास्तविक रूट विभाजन पर शुरू हो सकता है।
गाइकोसॉरस

4
@श्री। Shickadance। यह सिर्फ एलएफएस नहीं है जिसमें एक initrd नहीं है। जो कोई भी अपने कर्नेल को संकलित करता है, उसके पास initrd का उपयोग न करने का विकल्प होता है, जो कि मैं Gentoo पर करता हूं।
जॉन्सकब

1
@ फहीम: ग्रब 2 मॉड्यूल कर्नेल मॉड्यूल के समान नहीं हैं। मैं कर्नेल मॉड्यूल को लोड करने के लिए grub2 के लिए कुछ क्षमता देखता हूं, लेकिन एक बात मुझे नहीं पता है कि क्या यह लिनक्स कर्नेल के लिए काम करेगा या केवल * BSD के लिए (जहां बूटलोडर लोडिंग कर्नेल मॉड्यूल सामान्य है)। मुझे संदेह है कि कर्नेल को सिखाया जाना चाहिए जहां लोड किए गए मॉड्यूल के लिए पता मानचित्र ढूंढना है, और सभी को grub2 पर स्थानांतरित करने की आवश्यकता है (कुछ वितरणों में grub1 अभी भी मानक है)।
गीकॉर्स

1
Initrd को initramfs द्वारा बदल दिया गया है, क्योंकि pivot_root को एक गंदे हैक माना जाता था।
Psusi

41

प्राचीन समय में, कर्नेल को डिवाइस के रूट एफ / एफ की बड़ी / छोटी संख्या जानने के लिए हार्ड कोडित किया गया था और सभी डिवाइस ड्राइवरों को आरम्भ करने के बाद उस डिवाइस को माउंट किया गया था, जो कर्नेल में बनाए गए थे। rdevउपयोगिता यह पुन: संयोजित किए बिना गिरी छवि में जड़ डिवाइस संख्या को संशोधित करने के लिए इस्तेमाल किया जा सकता है।

आखिरकार बूट लोडर साथ आए और कर्नेल को कमांड लाइन दे सकते हैं। यदि root=तर्क पारित किया गया था, तो उस कर्नेल को बताया जहां मूल fs के बजाय मूल्य में बनाया गया था। ड्राइवरों को एक्सेस करने की आवश्यकता थी जो अभी भी कर्नेल में बनाए जाने थे। हालांकि तर्क /devनिर्देशिका में एक सामान्य डिवाइस नोड की तरह दिखता है , जाहिर है /devकि रूट एफएस माउंट होने से पहले कोई निर्देशिका नहीं है, इसलिए कर्नेल वहां एक देव नोड नहीं देख सकता है। इसके बजाय, कुछ अच्छी तरह से ज्ञात डिवाइस नाम कर्नेल में कठिन कोडित हैं ताकि स्ट्रिंग को डिवाइस नंबर में अनुवाद किया जा सके। इस वजह से, कर्नेल चीजों को पहचान सकता है /dev/sda1, लेकिन अधिक विदेशी चीजें जैसे कि /dev/mapper/vg0-rootया वॉल्यूम यूयूआईडी नहीं।

बाद initrdमें, तस्वीर में आया। कर्नेल के साथ, बूट लोडर initrdछवि को लोड करेगा , जो कुछ प्रकार की संपीड़ित फाइलसिस्टम छवि थी (gzipped ext2 image, gzipped romfs image, squashfs अंत में प्रमुख बन गई)। कर्नेल इस छवि को एक रैमडिस्क में विघटित कर देगा और रूटडिस्क के रूप में रैमडिस्क को माउंट करेगा। इस छवि में असली के बजाय कुछ अतिरिक्त ड्राइवर और बूट स्क्रिप्ट थे init। इन बूट लिपियों ने हार्डवेयर को पहचानने, छापेखाने और एलवीएम जैसी चीजों को सक्रिय करने, यूयूआईडी का पता लगाने और असली रूट को खोजने के लिए कर्नेल कमांड लाइन को पार्स करने के लिए विभिन्न कार्य किए, जो अब यूयूआईडी, वॉल्यूम लेबल और अन्य उन्नत चीजों द्वारा निर्दिष्ट किए जा सकते हैं। यह तो असली जड़ FS घुड़सवार /initrd, तो मार डाला pivot_rootसिस्टम कॉल गिरी स्वैप करने के लिए /और/initrd, तब /sbin/initअसली जड़ पर अमल करें, जो तब बेकाबू हो जाएगा /initrdऔर रैमडिस्क को मुक्त कर देगा।

अंत में, आज हमारे पास है initramfs। यह एक समान है initrd, लेकिन एक संपीड़ित फाइलसिस्टम छवि होने के बजाय जो कि रैमडिस्क में लोड है, यह एक संकुचित cpio संग्रह है। एक tmpfs को रूट के रूप में माउंट किया जाता है, और संग्रह को वहां निकाला जाता है। उपयोग करने के बजाय pivot_root, जिसे एक गंदे हैक के रूप में माना जाता था, initramfsबूट स्क्रिप्ट वास्तविक रूट को माउंट करते हैं /root, सभी फाइलों को tmpfs रूट में हटाते हैं , और फिर निष्पादित chrootकरते हैं ।/root/sbin/init


1
चुरोट के बाद, क्या tmpfs स्वचालित रूप से अनमाउंट है? क्या यह सिर्फ गायब हो जाता है?
जिगगंजर

@jiggunjer, नहीं, यह अभी भी वहां है, यह सिर्फ खाली है (एक तरफ / रूट निर्देशिका से युक्त), और अब उपयोग नहीं किया जाता है।
Psusi

मैंने रूट एफएस के हर पुनरावृत्ति के बारे में कुछ नया सीखा है जिसका आपने उल्लेख किया है। बहुत बढ़िया जवाब!
jpaugh

3

ऐसा लगता है जैसे आप पूछ रहे हैं कि कर्नेल "पता" कैसे करता है कि कौन सा विभाजन रूट विभाजन है, बिना विन्यास फाइल के एक्सेस / आदि पर।

कर्नेल किसी भी अन्य प्रोग्राम की तरह कमांड लाइन तर्क स्वीकार कर सकता है। GRUB, या अधिकांश अन्य बूटलोडर कमांड लाइन तर्कों को उपयोगकर्ता इनपुट के रूप में स्वीकार कर सकते हैं, या उन्हें स्टोर कर सकते हैं और एक मेनू के माध्यम से उपलब्ध कमांड लाइन तर्कों के विभिन्न संयोजन बना सकते हैं। बूटलोडर कर्नेल को कमांड लाइन तर्क देता है जब वह इसे लोड करता है (मुझे इस सम्मेलन का नाम या मैकेनिक्स नहीं पता है, लेकिन यह संभवत: इसी तरह है कि कैसे एक आवेदन एक चालू कर्नेल में कॉलिंग प्रक्रिया से कमांड लाइन के तर्क प्राप्त करता है)।

उन कमांड लाइन विकल्पों में से एक है root, जहां आप रूट फाइलसिस्टम को निर्दिष्ट कर सकते हैं, अर्थात root=/dev/sda1

यदि कर्नेल एक initrd का उपयोग करता है, तो बूटलोडर कर्नेल को यह बताने के लिए ज़िम्मेदार होता है कि वह कहाँ है, या initrd को एक मानक मेमोरी लोकेशन में डालता है (मुझे लगता है) - यह कम से कम मेरे गुरुप्लग पर काम करने का तरीका है।

यह पूरी तरह से संभव है कि एक को निर्दिष्ट न करें और फिर शिकायत शुरू करने के तुरंत बाद अपनी कर्नेल घबराहट करें कि यह रूट फाइल सिस्टम नहीं मिल सकता है।

कर्नेल में इस विकल्प को पारित करने के अन्य तरीके हो सकते हैं।


3
यह सही स्पष्टीकरण है जब कोई initrd / initramfs नहीं है, लेकिन यह पहेली का एक टुकड़ा याद कर रहा है। आम तौर पर कर्नेल एक डिवाइस की पहचान करता है, /dev/sda1क्योंकि यह एक फाइल सिस्टम में एक प्रविष्टि है। आप कर सकते हैं cp -p /dev/sda1 /tmp/fooऔर /tmp/fooएक ही उपकरण का प्रतिनिधित्व करेंगे। कर्नेल कमांड लाइन पर, कर्नेल एक बिल्ट-इन पार्सर का उपयोग करता है जो सामान्य डिवाइस नामकरण सम्मेलन का अनुसरण करता है: का sda1अर्थ है पहला SCSI- डिस्क का पहला विभाजन।
गिल्स एसओ- बुराई को रोकना '

@ इतने आधुनिक गुठली अभी भी UUID के आधार पर एक वॉल्यूम बढ़ते को संभाल नहीं सकते हैं? बिना initrdया initramfsमेरा मतलब है। यह /dev/sdxफॉर्म में "सरल" विभाजन होना है ?
जिगगंजर

1
@jiggunjer आधुनिक गुठली UUID द्वारा एक मात्रा के लिए खोज का समर्थन करते हैं। देख लो init/do_mounts.c
गिल्स एसओ- बुराई को रोकना

1

ग्रब /bootविभाजन को मापता है और फिर कर्नेल को निष्पादित करता है। ग्रब के कॉन्फ़िगरेशन में, यह कर्नेल को बताता है कि रूट डिवाइस के रूप में क्या उपयोग करना है।

उदाहरण के लिए ग्रब में menu.lst:

kernel /boot/linux root=/dev/sda2

1

चलो, GRUB "माउंट" / बूट नहीं करता है, यह सिर्फ 'menu.lst' और कुछ मॉड्यूल को पढ़ता है, यह LINUX कर्नेल का हिस्सा नहीं है। जब आप कर्नेल को कॉल करते हैं, तो आप रूट विभाजन के साथ "रूट" तर्क पास करेंगे। सबसे बुरी तरह से, कर्नेल जानता है कि बस / बूट माउंट किया गया है (एलओएल)।

अगला: geekosaur सही है, लिनक्स संपीड़ित छवि प्रारूप में एक प्रारंभिक रैमडिस्क का उपयोग करता है, और फिर कॉल करके वास्तविक रूट फाइल सिस्टम को मापता है pivot_root। तो लिनक्स एक छवि से चलना शुरू होता है, और फिर आपके स्थानीय डिस्क ड्राइव से।


1
ग्रब सबसे निश्चित रूप से एक फाइलसिस्टम को 'माउंट' करने की क्षमता रखता है, खासकर ग्रब 2 में। बेशक, यह सब करने / करने में सक्षम है / इसके साथ एक पट्टी या किसी अन्य के बूट करने योग्य गुठली की तलाश है, लेकिन यह अभी भी बढ़ रहा है। जब तक कि आपके कर्नेल ने आपके हार्ड ड्राइव को मॉड्यूल के रूप में संकलित नहीं किया है, तब भी लिनक्स को एक initrd की आवश्यकता नहीं है
शादुर

5
ibm.com/developerworks/linux/library/l-linuxboot यह बूट करने पर लिनक्स कर्नेल क्या करता है, इसका एक संक्षिप्त संक्षिप्त सारांश है।
jsbillings 12

2
@ बहादुर, माउंट मैनपेज से: यूनिक्स प्रणाली में सुलभ सभी फाइलें एक बड़े पेड़, फ़ाइल पदानुक्रम, / पर रूट की गई हैं। इन फ़ाइलों को कई उपकरणों में फैलाया जा सकता है। माउंट कमांड कुछ डिवाइस पर मिली फाइल सिस्टम को बड़ी फाइल ट्री में अटैच करने का काम करता है। - चूंकि GRUB द्वारा प्रयुक्त फाइल सिस्टम फाइल पदानुक्रम से संलग्न नहीं है, इसलिए यह बढ़ते नहीं है ।
D4RIO

1
@ बहादुर, BTW: यह स्पष्ट है कि initrd आवश्यक नहीं है क्योंकि यह सिर्फ एक और रूट फाइलसिस्टम है, लेकिन इसे आमतौर पर छोटे बूट-टाइम रूट के रूप में उपयोग किया जाता है, क्योंकि कर्नेल बूट करने के लिए आवश्यक लोड करता है, फिर बूट करता है, और अंत में बाकी सब लोड करता है।
D4RIO

1
@ d4rio वे GRUB द्वारा माउंट किए गए हैं, न कि लिनक्स - यह समझने में आसान हो जाता है जब आप ग्रब को सिर्फ एक बूटलोडर के बजाय अपने आप के माइक्रोक्राइन ओएस के रूप में मानते हैं।
Shadur

1

बूट लोडर, यह ग्रब या लिलो या जो कुछ भी हो, कर्नेल को root=ध्वज के साथ देखने के लिए बताता है , और initrdकर्नेल को बूट करने से पहले वैकल्पिक रूप से एक प्रारंभिक रैमडिस्क को मेमोरी में लोड करता है ।

कर्नेल तब अपने हार्डवेयर और डिवाइस ड्राइवरों को लोड करता है, परीक्षण करता है और सिस्टम के चारों ओर देखता है कि यह क्या देख सकता है (आप टाइप करके इस डायग्नोस्टिक जानकारी की समीक्षा कर सकते हैं dmesg; आजकल यह देखने में बहुत तेजी से स्क्रॉल करता है) फिर इसमें बताए गए विभाजन को माउंट करने का प्रयास करता है। root=पैरामीटर।

यदि एक initrd मौजूद है, तो इसे पहले माउंट किया जाता है और रूट फाइल सिस्टम के माउंट होने से पहले इस पर किसी भी मॉड्यूल / डिवाइस ड्राइवर को लोड और जांच किया जाता है। इस तरह आप अपने हार्ड ड्राइव के लिए ड्राइवरों को मॉड्यूल के रूप में संकलित कर सकते हैं और अभी भी बूट करने में सक्षम हो सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.