लिनक्स 'initrd' छवि को कैसे लोड करता है?


13

मैं बूटिंग प्रक्रिया को समझने की कोशिश कर रहा हूं, लेकिन मेरे सिर पर बस एक चीज है।

जैसे ही लिनक्स कर्नेल को बूट किया गया है और रूट फाइल सिस्टम (/) माउंट किया गया है, प्रोग्राम चलाए जा सकते हैं और अतिरिक्त कार्यों को प्रदान करने के लिए आगे कर्नेल मॉड्यूल को एकीकृत किया जा सकता है। रूट फाइल सिस्टम को माउंट करने के लिए कुछ शर्तों को पूरा करना होगा। कर्नेल को उस डिवाइस तक पहुंचने के लिए संबंधित ड्राइवरों की आवश्यकता होती है जिस पर रूट फ़ाइल सिस्टम स्थित है (विशेष रूप से SCSI ड्राइवर)। कर्नेल में फ़ाइल सिस्टम (ext2, reiserfs, romfs, आदि) को पढ़ने के लिए आवश्यक कोड भी होना चाहिए। यह भी बोधगम्य है कि रूट फाइल सिस्टम पहले से ही एन्क्रिप्टेड है। इस स्थिति में, फ़ाइल सिस्टम को माउंट करने के लिए एक पासवर्ड की आवश्यकता होती है।

प्रारंभिक रैमडिस्क (जिसे इनिटडिस्क या इनिटर्ड भी कहा जाता है) ऊपर वर्णित समस्याओं को ठीक करता है। लिनक्स कर्नेल एक छोटे फ़ाइल सिस्टम को रैम डिस्क पर लोड करने और वास्तविक रूट फ़ाइल सिस्टम के माउंट होने से पहले वहां प्रोग्राम चलाने का विकल्प प्रदान करता है। Initrd का लोडिंग बूट लोडर (GRUB, LILO, आदि) द्वारा नियंत्रित किया जाता है। बूट लोडर को बूट माध्यम से डेटा लोड करने के लिए केवल BIOS रूटीन की आवश्यकता होती है। यदि बूट लोडर कर्नेल को लोड करने में सक्षम है, तो यह प्रारंभिक रैमडिस्क को भी लोड कर सकता है। विशेष ड्राइवरों की आवश्यकता नहीं है।

यदि / बूट एक अलग विभाजन नहीं है, लेकिन / विभाजन में मौजूद है, तो क्या बूट लोडर को SCSI चालकों की आवश्यकता नहीं है, ताकि 'initrd' छवि और कर्नेल छवि का उपयोग किया जा सके? यदि आप छवियों को सीधे एक्सेस कर सकते हैं, तो हमें SCSI ड्राइवरों की आवश्यकता क्यों है ??

जवाबों:


20

निगरफ, मैं आपके प्रश्न का उत्तर देने की कोशिश करूंगा, लेकिन बूट प्रक्रिया के अधिक व्यापक वर्णन के लिए, आईबीएम लेख का प्रयास करें

ठीक है, मेरा मानना ​​है कि आप स्पष्टीकरण के लिए GRUB या GRUB2 को अपने बूटलोडर के रूप में उपयोग कर रहे हैं। सबसे पहले, जब BIOS बूटलोडर को लोड करने के लिए आपकी डिस्क तक पहुंचता है, तो यह डिस्क एक्सेस के लिए अपने अंतर्निहित रूटीन का उपयोग करता है, जो कि प्रसिद्ध 13h रुकावट में संग्रहीत होते हैं। बूट लोडर (और सेटअप चरण में कर्नेल) डिस्क का उपयोग करते समय उन दिनचर्या का उपयोग करते हैं। ध्यान दें कि प्रोसेसर के वास्तविक मोड (16 बिट) में BIOS चलता है, इस प्रकार यह 2 ^ 20 बाइट से अधिक रैम को संबोधित नहीं कर सकता (2 ^ 20 नहीं 2 ^ 16) क्योंकि वास्तविक मोड में प्रत्येक पता सेगमेंट_ड्रेस * 16 + ऑफसेट से मिलकर बनता है , जहां दोनों खंड पते और ऑफसेट 16-बिट हैं, http://en.wikipedia.org/wiki/X86_memory_segmentation देखें )। इस प्रकार, ये रूटीन 1 MiB से अधिक रैम तक नहीं पहुंच सकते हैं, जो एक सख्त सीमा और एक बड़ी असुविधा है।

BIOS एमबीआर से बूट लोडर कोड को सही लोड करता है - आपकी डिस्क के पहले 512 बाइट्स और इसे निष्पादित करता है। यदि आप GRUB का उपयोग कर रहे हैं, तो वह कोड GRUB चरण 1 है। यह कोड GRUB चरण 1.5 को लोड करता है, जो डिस्क स्थान के पहले 32 KiB में स्थित है, जिसे DOS संगतता क्षेत्र कहा जाता है या फ़ाइल सिस्टम के एक निश्चित पते से। इसे करने के लिए फ़ाइल सिस्टम को समझने की आवश्यकता नहीं है, इसका कारण यह भी है कि चरण 1.5 फ़ाइल सिस्टम में है, यह "कच्चा" कोड है और इसे सीधे रैम में लोड किया जा सकता है और निष्पादित किया जा सकता है: http://www.pixelbeat.org/ डॉक्स / डिस्क / । डिस्क से रैम तक स्टेज 1.5 का भार BIOS डिस्क एक्सेस रूटीन का उपयोग करता है।

यहाँ छवि विवरण दर्ज करें

स्टेज 1.5 में फाइलसिस्टम उपयोगिताओं है, ताकि यह फाइलसिस्टम से स्टेज 2 को पढ़ सके (ठीक है, यह अभी भी डिस्क से रैम तक पढ़ने के लिए BIOS 13h का उपयोग करता है, लेकिन अब यह फाइल सिस्टम की जानकारी को इनकोड आदि के बारे में समझा सकता है और कच्चे कोड को प्राप्त कर सकता है) डिस्क)। पुराने BIOS अपने डिस्क एड्रेसिंग मोड में सीमाओं के कारण पूरे एचडी तक नहीं पहुंच सकते हैं - वे सिलेंडर-हेड-सेक्टर सिस्टम का उपयोग कर सकते हैं, जो डिस्क स्थान के पहले 8 GiB से अधिक को संबोधित करने में असमर्थ हैं: http: //en.wikipedia। org / wiki / सिलेंडर-हेड-सेक्टर

स्टेज 2 रैम में कर्नेल को लोड करता है (फिर से, BIOS डिस्क उपयोगिताओं का उपयोग करके)। यदि यह 2.6+ कर्नेल है, तो इसके अंदर इनट्रामर्फ भी संकलित है, इसलिए इसे लोड करने की आवश्यकता नहीं है। यदि यह एक पुराना कर्नेल है, तो बूटलोडर स्टैंडअलोन इनइटर्ड इमेज को मेमोरी में लोड कर देता है, ताकि कर्नेल इसे माउंट कर सके और डिस्क से रियल फाइल सिस्टम को माउंट करने के लिए ड्राइवर प्राप्त कर सके।

समस्या यह है कि कर्नेल (और रैमडिस्क) का वजन 1 MiB से अधिक है, इस प्रकार उन्हें रैम में लोड करने के लिए आपको कर्नेल को पहले 1 MiB पर लोड करना होगा, फिर संरक्षित मोड (32 बिट) पर जाएं, लोड किए गए कर्नेल को उच्च मेमोरी में स्थानांतरित करें (मुफ्त) वास्तविक मोड के लिए पहले 1 MiB), फिर वास्तविक (16 बिट) मोड पर वापस लौटें, डिस्क से रैमडिस्क प्राप्त करें पहले 1 MiB (यदि यह एक अलग initrd और पुराने कर्नेल है), संभवतः संरक्षित (32 बिट) मोड पर फिर से, इसे जहां है, वहां रखें, संभवतः वास्तविक मोड पर वापस जाएं (या नहीं: /programming/4821911/does-grub-switch-to-protected-mode ) और कर्नेल कोड निष्पादित करें। चेतावनी: मैं वर्णन के इस भाग की पूर्णता और सटीकता के बारे में पूरी तरह सुनिश्चित नहीं हूँ।

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


क्या बूटलेडर सिर्फ कर्न्स को संरक्षित मोड में कूदने के बजाय, कर्न्स में लोड नहीं कर सकता है ?? और उस 1 MB को मुक्त करने की क्या आवश्यकता है .. (क्षमा करें .. समझ नहीं सका कि ..)
rpthms

पहले 1MiB को मुक्त करने की आवश्यकता इस प्रकार है: बूटलोडर आपकी हार्ड ड्राइव को केवल वास्तविक मोड में एक्सेस कर सकता है, क्योंकि यह इसे BIOS उपयोगिताओं के साथ एक्सेस करता है, जो वास्तविक-मोड हैं (वे 16-बिट तर्क पर काम करते हैं और 16-बिट ऑपरेशन का उपयोग करते हैं)। वास्तविक मोड सिर्फ पहले 1 MiB को छोड़कर किसी भी रैम को नहीं देखता है। लेकिन आपको रैम में कर्नेल + इनट्रामेफ़्स लोड करने की आवश्यकता है और वे रैम में ~ 5 MiB स्पेस लेते हैं। उन BIOS उपयोगिताओं को पहले 1 MiB में 5 MiB निचोड़ने में सक्षम नहीं किया जाएगा। तो, बूटलोडर को उन्हें डिस्क से पहले 1 MiB पर कॉपी करना होगा, फिर संरक्षित मोड पर जाएं और उन्हें पहली बार 1Mb रैम से उच्चतर RAM पर ले जाएं। क्या यह अब स्पष्ट है? :)
बोरिस बुर्कोव

1
पूरे चरण 1 / 1.5 / 2 सामान ग्रब विरासत है।
Psusi

1
@CMCDragonkai हां, स्टेज 2 बूटलोडर फाइल सिस्टम में है (अर्थात्, /bootविभाजन में)। कर्नेल को इस बिंदु पर लोड नहीं किया गया है - यह ग्रब के स्टेज 1.5 है, जो अपने न्यूनतर फाइल सिस्टम ड्राइवरों के माध्यम से /bootफाइलसिस्टम (जैसे /boot/grubफ़ाइल में) में स्टेज 2 तक पहुंच रहा है । कर्नेल /bootविभाजन से भी पढ़ने में सक्षम होगा , लेकिन यह बाद में होगा, ग्रब 2 कोड के निष्पादन और कर्नेल के लोड के बाद और कर्नेल initramfs को पढ़ता है। क्या आप init.shinitramfs की बात कर रहे हैं ? यह /bootआपकी हार्ड ड्राइव के विभाजन में रहता है , फिर ग्रब का स्टेज 2 इसे रैम में डालता है और कर्नेल इसे रैम से पढ़ता है।
बोरिस बुर्कोव

1
Initrd को एक अलग फ़ाइल बनना था । नए initramfs को कर्नेल से जोड़ा जा सकता है , लेकिन इसका होना आवश्यक नहीं है - इसे बूटलोडर द्वारा एक अलग फाइल के रूप में लोड किया जा सकता है। चूंकि initramfs फ़ाइल को cpio अभिलेखागार के अनुक्रम के रूप में परिभाषित किया गया है, इसलिए कुछ बूटलोडर्स (जैसे iPXE) कई initramfs फ़ाइलों को भी अनुमति देते हैं , जिन्हें एक के बाद एक मेमोरी में लोड किया जाएगा। इसके अलावा, कुछ लिनक्स वितरण बैकवर्ड संगतता के लिए initrd-style फ़ाइल नामों का उपयोग करते हैं, हालांकि उपयोग की जाने वाली वास्तविक तकनीक अब initramfs है।
टेल्कोम

1

मेरा मानना ​​है, यह विशेष रूप से बूटलोडर का समर्थन करता है जो करने के लिए नीचे फोड़े। उदाहरण के लिए। यह आपके संयुक्त (बूट + रूट) विभाजन के विशेष फाइल सिस्टम को जानने की जरूरत नहीं है। उस स्थिति में आप बस एक अलग बूट विभाजन स्थिति में बनाते हैं जैसे कि यह आपके बूटलोडर के साथ काम करता है, और अपने रूट विभाजन को कैसे माउंट किया जाए इसकी कोई भी जटिलता बूट पार्टीशन से बूट किए गए कर्नेल और initrd छवि पर छोड़ दी जाती है। बूटलोडर को पता है कि एससीएसआई उपकरणों (और अन्य उपकरणों को भी कैसे एक्सेस किया जाए, जो कि बूटलोडर का उपयोग किया जाता है) पर निर्भर करता है या तो वह स्वयं ड्राइवरों का उपयोग करके या BIOS रूटीन का उपयोग करके। इसके अलावा, यह जानता है कि कुछ फाइलसिस्टम कैसे पढ़ें, आदि।

उदाहरण पर विचार करें। बूट करने का यूईएफआई तरीका, जहां वास्तव में यूईएफआई फर्मवेयर पहले से ही जानता है कि ईएफआई विभाजन का उपयोग कैसे करें, इसे पढ़ें और मध्यवर्ती बूटलोडर की आवश्यकता के बिना वहां से लिनक्स कर्नेल लोड करें। उस स्थिति में लिनक्स छवि रूट विभाजन से अलग हो जाती है और यूईएफआई फर्मवेयर को इसे एक्सेस करने के लिए सभी विदेशी फाइल सिस्टम को जानने की जरूरत नहीं है। मेरा मानना ​​है कि "बूट" छवियों को "रूट" विभाजन से अलग करने से बड़ा अर्थ होता है। यदि किसी और चीज़ के लिए नहीं है तो रूट फाइलसिस्टम एन्क्रिप्शन की स्थापना करते समय यह आवश्यक है।


0

सिर्फ रिकॉर्ड के लिए, अगर एक बूटलोडर initrd को लोड नहीं करता है तो यह किसी अन्य बूटलोडर का परीक्षण करने के लिए सार्थक है; मैं अभी इस तरह की स्थिति में आया हूं, जब LILO ने चुपचाप मध्यम आकार के एक उचित रूप से निर्दिष्ट initrd (<4Mb; एकल SATA SSD; GPT) पर एकल ext4 रूटफुट को अनदेखा किया और GRUB 2.00 सफल रहा।

बूट प्रक्रिया एक ठेठ के साथ जल्दी से समाप्त हो गई

RAMDISK: Couldn't find valid RAM disk image starting at 0.
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,3)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.