कर्नेल को भौतिक स्मृति आधार पता कैसे पता चलता है?
मैं 2 संबंधित मुद्दों को समझने की कोशिश कर रहा हूं।
कर्नेल कोड जो पोस्ट-बूटलोडर चलाता है और एमएमयू को सक्षम करने से पहले भौतिक / पहचान मैप की गई वर्चुअल मेमोरी में संचालित होता है। इस कोड को विभिन्न सीपीयू के बीच पोर्टेबल बनाया जा सकता है जो विभिन्न भौतिक पता श्रेणियों में DRAM हो सकता है?
पृष्ठ तालिका को प्रबंधित करने के लिए कर्नेल के लिए, यह आवश्यक है कि भौतिक मेमोरी संसाधन पते और उपलब्ध भौतिक मेमोरी सहित भौतिक मेमोरी संसाधनों के बारे में कुछ जागरूकता हो, इसलिए यह उन भौतिक पते को असाइन नहीं करता है जो DRAM रेंज से बाहर हैं।
मुझे लगता है कि यह कुछ हद तक कार्यान्वयन पर निर्भर है, लेकिन विभिन्न आर्किटेक्चर इस समस्या को कैसे संभालते हैं इसकी सराहना की जाएगी। मेरे पास अभी तक कुछ विचार हैं:
भौतिक पता DRAM श्रेणी, या कम से कम आधार पता, कर्नेल संकलन समय पर बेक किया गया है। इसका मतलब है कि अलग-अलग सीपीयू के लिए समान आईएसए के साथ पुनर्संयोजन की आवश्यकता है। यह इस जवाब से प्रेरित है यहां , जो, अगर मैं सही ढंग से समझ रहा हूँ, का वर्णन गिरी आधार पते के लिए एक ही समाधान। चूंकि आधार पता संकलन समय पर जाना जाता है, कर्नेल कोड DRAM / कर्नेल आधार पते से ऑफसेट के बजाय शाब्दिक पते को संदर्भित करता है।
DRAM जानकारी को डिवाइस ट्री से बाकी भौतिक मेमोरी मैप के साथ पढ़ा और सीखा जाता है। कम से कम Xilinx Zynq SoC के लिए यह मेरी धारणा है, इस तरह मंच के पदों पर आधारित है । जबकि यह समाधान अधिक लचीलापन प्रदान करता है और हमें सीपीयू को पोर्ट करने के लिए पूरे कर्नेल के बजाय सिर्फ बूट लोडर को फिर से जोड़ने की अनुमति देता है, यह मुझे यह सोचकर छोड़ देता है कि मेरी एक्स 86 पर्सनल मशीन रन-टाइम में यह पता लगा सकती है कि मैंने कितना ड्रामा स्थापित किया है। कोड को डीआरएएम आधार पते से सिर्फ संदर्भ तालिका के प्रबंधन के लिए कोड और सीपीयू के विभिन्न डीआरएएम भौतिक पता श्रेणियों के साथ पुनर्संयोजन के बिना पोर्टेबल है।
जवाब
संपूर्ण भौतिक मेमोरी DIMM जो बूट-टाइम पर उपलब्ध हैं और आमतौर पर भौतिक मेमोरी एड्रेस स्पेस की एक भी सन्निहित सीमा तक मैप नहीं की जाती हैं, इसलिए कोई "आधार पता नहीं है।" एक हार्ड रीसेट पर, सीपीयू फर्मवेयर निष्पादन पूरा होने के बाद, प्लेटफॉर्म फर्मवेयर, जो आमतौर पर या तो विरासत BIOS या यूईएफआई निष्पादित होता है। एक दिया गया मदरबोर्ड केवल सीपीयू संग्रह के सीमित सेट के साथ संगत है, जिसमें आमतौर पर DIMMs और प्लेटफ़ॉर्म फ़र्मवेयर मेमोरी डिवाइस सहित भौतिक मेमोरी की खोज के लिए एक ही विधि होती है। प्लेटफ़ॉर्म फ़र्मवेयर का एक कार्यान्वयन मेमोरी विवरण प्रविष्टियों की तालिका बनाने के लिए इस पद्धति का उपयोग करता है जहां प्रत्येक प्रविष्टि एक भौतिक मेमोरी एड्रेस रेंज का वर्णन करती है। यह प्रोसेसर कैसा दिखता है, इस बारे में अधिक जानकारी के लिए: कैसे BIOS DRAM को इनिशियलाइज़ करता है? । यह तालिका मुख्य मेमोरी (DIMM) में एक पते पर संग्रहीत की जाती है जो इस उद्देश्य के लिए आरक्षित होने के लिए जानी जाती हैं और वास्तविक मेमोरी द्वारा समर्थित होने वाली हैं (किसी भी DIMM के बिना सिस्टम बूट किया जा सकता है)।
90 के दशक के मध्य से x86 पीसी BIOS के अधिकांश कार्यान्वयन वास्तविक-मोड INT 15h E820h
फ़ंक्शन की पेशकश करते हैं (15h इंटरप्ट नंबर है और E820h AX
रजिस्टर में पारित एक तर्क है )। यह फीनिक्सबीआईओएस v4.0 (1992-1994 में शुरू किया गया एक विक्रेता-विशिष्ट BIOS फ़ंक्शन है, मैं सटीक वर्ष को पिन करने में असमर्थ हूं) और बाद में अन्य BIOS विक्रेताओं द्वारा अपनाया गया। यह इंटरफ़ेस 1996 में जारी एसीपीआई 1.0 विनिर्देश द्वारा विस्तारित किया गया था और बाद में फीनिक्सबीआईओएस के संशोधन ने एसीपीआई का समर्थन किया। संबंधित UEFI इंटरफ़ेस है GetMemoryMap()
, जो UEFI बूट-टाइम सेवा है (जिसका अर्थ है कि इसे केवल बूट-टाइम के रूप में UEFI विनिर्देश में परिभाषित किया जा सकता है)। सभी NUMA नोड्स पर मेमोरी का वर्णन करने वाले एड्रेस मैप को प्राप्त करने के लिए कर्नेल इनमें से एक इंटरफेस का उपयोग कर सकता है। X86 प्लेटफार्मों पर अन्य (पुराने) तरीकों का पता लगाने मेमोरी (x86) पर चर्चा की जाती है । दोनों ACPI विनिर्देश संस्करण के साथ शुरू कर रहे हैं? और UEFI विनिर्देश संस्करण के साथ शुरू हो रहा है? समर्थन DRIM DIMMs और NVDIMMs मेमोरी रेंज प्रकार।
उदाहरण के लिए विचार करें कि एक एसी 86 एसीपीआई-सक्षम BIOS प्लेटफॉर्म पर एसीपीआई-संगत लिनक्स कर्नेल निर्धारित करता है कि भौतिक पता सीमाएं क्या उपलब्ध हैं (यानी, वास्तविक मेमोरी द्वारा समर्थित) और प्रयोग करने योग्य (यानी, नि: शुल्क)। BIOS फर्मवेयर बूटलोडर को निर्दिष्ट बूट करने योग्य स्टोरेज डिवाइस से इस उद्देश्य के लिए समर्पित मेमोरी लोकेशन पर लोड करता है। फर्मवेयर के निष्पादन के पूरा होने के बाद, यह बूटलोडर पर कूदता है जो स्टोरेज मीडिया पर कर्नेल की छवि को ढूंढेगा, इसे मेमोरी में लोड करता है, और कर्नेल पर नियंत्रण स्थानांतरित करता है। बूटलोडर को वर्तमान मेमोरी मैप को जानने और उसके संचालन के लिए कुछ मेमोरी आवंटित करने की आवश्यकता है। यह E820h
फ़ंक्शन को कॉल करके मेमोरी मैप प्राप्त करने की कोशिश करता है और यदि समर्थित नहीं है, तो यह पुराने पीसी BIOS इंटरफेस का सहारा लेगा। कर्नेल बूट प्रोटोकॉल परिभाषित करता है जो स्मृति पर्वतमाला बूट लोडर और जो स्मृति सीमाओं के आधार पर इस्तेमाल किया जा सकता कर्नेल के लिए उपलब्ध छोड़ दिया जाना चाहिए।
बूटलोडर स्वयं मेमोरी मैप को संशोधित नहीं करता है या कर्नेल को मैप प्रदान नहीं करता है। इसके बजाय, जब कर्नेल निष्पादित करना शुरू करता है, तो यह E820h
फ़ंक्शन को कॉल करता है और इसे ES:DI
एक बफर को 20-बिट पॉइंटर (इन ) पास करता है जिसे कर्नेल बूट प्रोटोकॉल के अनुसार x86 प्लेटफार्मों पर मुक्त होना जानता है। प्रत्येक कॉल में एक मेमोरी रेंज डिस्क्रिप्टर होता है जिसका आकार कम से कम 20 बाइट्स होता है। अधिक जानकारी के लिए, एसीपीआई विनिर्देश के नवीनतम संस्करण को देखें। अधिकांश BIOS कार्यान्वयन ACPI का समर्थन करते हैं।
एक लिनक्स कर्नेल को अपस्ट्रीम-डिफॉल्ट बूट मापदंडों के साथ मानकर, आप dmesg | grep 'BIOS-provided\|e820'
मेमोरी रेंज डिस्क्रिप्टर टेबल को वापस देखने के लिए कमांड का उपयोग कर सकते हैं । मेरे सिस्टम पर, यह इस तरह दिखता है:
[ 0.000000] BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x00000000000917ff] usable
[ 0.000000] BIOS-e820: [mem 0x0000000000091800-0x000000000009ffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000000e0000-0x00000000000fffff] reserved
[ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x00000000d2982fff] usable
[ 0.000000] BIOS-e820: [mem 0x00000000d2983000-0x00000000d2989fff] ACPI NVS
[ 0.000000] BIOS-e820: [mem 0x00000000d298a000-0x00000000d2db9fff] usable
[ 0.000000] BIOS-e820: [mem 0x00000000d2dba000-0x00000000d323cfff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000d323d000-0x00000000d7eeafff] usable
[ 0.000000] BIOS-e820: [mem 0x00000000d7eeb000-0x00000000d7ffffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000d8000000-0x00000000d875ffff] usable
[ 0.000000] BIOS-e820: [mem 0x00000000d8760000-0x00000000d87fffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000d8800000-0x00000000d8fadfff] usable
[ 0.000000] BIOS-e820: [mem 0x00000000d8fae000-0x00000000d8ffffff] ACPI data
[ 0.000000] BIOS-e820: [mem 0x00000000d9000000-0x00000000da718fff] usable
[ 0.000000] BIOS-e820: [mem 0x00000000da719000-0x00000000da7fffff] ACPI NVS
[ 0.000000] BIOS-e820: [mem 0x00000000da800000-0x00000000dbe11fff] usable
[ 0.000000] BIOS-e820: [mem 0x00000000dbe12000-0x00000000dbffffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000dd000000-0x00000000df1fffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000f8000000-0x00000000fbffffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000fec00000-0x00000000fec00fff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000fed00000-0x00000000fed03fff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000fed1c000-0x00000000fed1ffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000fee00000-0x00000000fee00fff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000ff000000-0x00000000ffffffff] reserved
[ 0.000000] BIOS-e820: [mem 0x0000000100000000-0x000000041edfffff] usable
[ 0.002320] e820: update [mem 0x00000000-0x00000fff] usable ==> reserved
[ 0.002321] e820: remove [mem 0x000a0000-0x000fffff] usable
[ 0.002937] e820: update [mem 0xdd000000-0xffffffff] usable ==> reserved
[ 0.169287] e820: reserve RAM buffer [mem 0x00091800-0x0009ffff]
[ 0.169288] e820: reserve RAM buffer [mem 0xd2983000-0xd3ffffff]
[ 0.169289] e820: reserve RAM buffer [mem 0xd2dba000-0xd3ffffff]
[ 0.169289] e820: reserve RAM buffer [mem 0xd7eeb000-0xd7ffffff]
[ 0.169289] e820: reserve RAM buffer [mem 0xd8760000-0xdbffffff]
[ 0.169290] e820: reserve RAM buffer [mem 0xd8fae000-0xdbffffff]
[ 0.169291] e820: reserve RAM buffer [mem 0xda719000-0xdbffffff]
[ 0.169291] e820: reserve RAM buffer [mem 0xdbe12000-0xdbffffff]
[ 0.169292] e820: reserve RAM buffer [mem 0x41ee00000-0x41fffffff]
मेमोरी रेंज जो "BIOS-e820" से शुरू होती है, उस तालिका में वर्णित हैं। पहली पंक्ति स्पष्ट रूप से आपको इस जानकारी का स्रोत बताती है। इस जानकारी का सटीक प्रारूप लिनक्स कर्नेल संस्करण पर निर्भर करता है। किसी भी स्थिति में, आपको प्रत्येक प्रविष्टि में एक सीमा और एक प्रकार दिखाई देगा। "E820" ("BIOS-" भाग के बिना) के साथ शुरू होने वाली पंक्तियाँ वे परिवर्तन हैं जो कर्नेल ने स्वयं तालिका में किए हैं। E820h
अलग-अलग प्रविष्टियों में प्राप्त सीमाओं के बीच बगिया का कार्यान्वयन हो सकता है या ओवरलैप हो सकता है। कर्नेल आवश्यक जांच करता है और तदनुसार बदलता रहता है। उन श्रेणियों को "प्रयोग करने योग्य" के रूप में चिह्नित किया गया है, जो कर्नेल द्वारा उपयोग के लिए अधिकतर मुफ्त हैं, जिनकी चर्चा एसीपीआई विनिर्देश में की गई है और जिनमें से कर्नेल अवगत है। अधिकांश 128 मेमोरी रेंज डिस्क्रिप्टर पर पीसी BIOS कार्यान्वयन का अधिकांश हिस्सा वापस आ जाता है। लिनक्स कर्नेल के पुराने संस्करण केवल 128 मेमोरी रेंज तक ही संभाल सकते हैं, इसलिए E820h
128 वें से परे से लौटी किसी भी प्रविष्टि को अनदेखा कर दिया जाता है। संस्करण से शुरू ?, इस सीमा को आराम दिया गया था। अधिक जानकारी के लिए, कर्नेल पैच की श्रृंखला देखें जिसका शीर्षक है "x86 बूट: सेटअप डेटा की लिंक की गई सूची के माध्यम से E820 मेमोरी मैप प्रविष्टियों को 128 से अधिक पास करें।"
प्रकार के रंग usable
और ACPI data
। प्रकार की रेंज reserved
DRAM DIMM द्वारा समर्थित हैं या CPU या प्लेटफ़ॉर्म फ़र्मवेयर द्वारा MMIO के लिए कटा हुआ है। प्रकार के रंग ACPI NVS
फर्मवेयर मेमोरी द्वारा समर्थित हैं। अन्य सभी श्रेणियां वास्तविक मेमोरी द्वारा वापस नहीं आती हैं जहाँ तक फ़र्मवेयर बता सकता है। ध्यान दें कि फर्मवेयर सभी स्थापित DRAM DIMM या NVDIMM को मैप नहीं करने का विकल्प चुन सकता है। यह तब हो सकता है यदि भौतिक स्मृति कॉन्फ़िगरेशन समर्थित नहीं है या यदि फर्मवेयर DIMM में किसी समस्या के कारण स्थापित DIMM से जानकारी प्राप्त करने में असमर्थ है।
आप गणना कर सकते हैं कि स्थापित DRAM DIMM और NVDIMM की कितनी मेमोरी फर्मवेयर को कर्नेल के लिए उपलब्ध कराई गई है। अपने सिस्टम पर, मैंने 16 GB DRAM DIMMs स्थापित किया है। इसलिए जब तक डीआईएमएम में से कुछ ठीक से स्थापित नहीं होते हैं, सही ढंग से काम नहीं कर रहे हैं, फर्मवेयर में एक बग, या मंच या प्रोसेसर द्वारा समर्थित नहीं है, कर्नेल को उपलब्ध कराए गए 16 जीबी से थोड़ा कम होना चाहिए।
सभी usable
श्रेणियां 0x3FA42B800 बाइट तक जुड़ती हैं। ध्यान दें कि श्रेणी का अंतिम पता समावेशी है, जिसका अर्थ है कि यह एक बाइट स्थान की ओर इशारा करता है जो कि सीमा का हिस्सा है। शारीरिक रूप से स्थापित डीआईएमएम की कुल मात्रा 16 जीबी या 0x400000000 बाइट्स है। तो स्थापित मेमोरी की कुल मात्रा जो कर्नेल के लिए उपलब्ध नहीं की गई थी, वह है 0x400000000 - 0x3FA42B800 या कुल 16 जीबी के लगभग 92 एमबी। यह स्मृति कुछ reserved
श्रेणियों और सभी श्रेणियों द्वारा ली गई थी ACPI data
। यदि DRAM DIMM या NVDIMM में कुछ स्थानों को प्लेटफ़ॉर्म फ़र्मर द्वारा अविश्वसनीय के रूप में निर्धारित किया गया था, तो उन्हें भी काट दिया जाएगा reserved
।
ध्यान दें कि सीमा 0x000a0000-0x000fffff E820
स्मृति मानचित्र में ACPI विनिर्देश के अनुसार वर्णित नहीं है । यह 640KB-1MB ऊपरी मेमोरी क्षेत्र है। कर्नेल एक संदेश प्रिंट करता है जो कहता है कि इसने इस सीमा को प्रयोग करने योग्य स्मृति क्षेत्र से हटा दिया है ताकि प्राचीन प्रणालियों के साथ सहानुभूति बनाए रख सकें।
इस बिंदु पर, अधिकांश PCIe उपकरणों के लिए MMIO के रूप में उपयोग की जाने वाली मेमोरी अभी तक आवंटित नहीं की गई है। मेरा प्रोसेसर 39-बिट भौतिक पता स्थान का समर्थन करता है, जिसका अर्थ है कि मानचित्रण के लिए 0 से 2 ^ 39 के बीच पते उपलब्ध हैं। अब तक केवल सबसे निचले 16.5 GB स्थान को किसी चीज़ में मैप किया गया है। ध्यान दें कि इस रेंज में अभी भी अनमैप्ड गैप हैं। कर्नेल इन अंतरालों का उपयोग कर सकता है (कुछ 100 एमबी की) और बाकी भौतिक पता स्थान (लगभग 495.5 GB) IO उपकरणों के लिए अतिरिक्त रेंज आवंटित करने के लिए। कर्नेल अंततः PCIe उपकरणों की खोज करेगा और प्रत्येक डिवाइस के लिए, यदि उपलब्ध हो तो संगत ड्राइवर को लोड करने का प्रयास करेगा। ड्राइवर तब निर्धारित करता है कि डिवाइस को कितनी मेमोरी की जरूरत है और डिवाइस द्वारा लगाए गए मेमोरी एड्रेस पर कोई प्रतिबंध और कर्नेल से डिवाइस के लिए मेमोरी आवंटित करने और डिवाइस के स्वामित्व वाली MMIO मेमोरी के रूप में कॉन्फ़िगर करने का अनुरोध करता है। आप कमांड का उपयोग करके अंतिम मेमोरी मैप देख सकते हैं sudo cat /proc/iomem
।
ऐसी स्थितियाँ हैं जहाँ आप मैन्युअल रूप से मौजूदा मेमोरी रेंज के मेमोरी प्रकार को बदलना चाहते हैं (उदाहरण के लिए, परीक्षण के लिए), एक नई रेंज बनाएँ (जैसे, DRAM पर लगातार मेमोरी का अनुकरण करने के लिए या यदि फ़र्मवेयर सभी की खोज करने में असमर्थ है। जो भी कारण हो उसके लिए उपलब्ध मेमोरी), कर्नेल द्वारा प्रयोग करने योग्य मेमोरी की मात्रा को कम करें (जैसे, सीमा से परे मेमोरी का उपयोग करने के लिए एक नंगे-धातु हाइपरविजर को रोकने के लिए और बाकी मेहमानों के लिए उपलब्ध कराएं), या यहां तक कि पूरी तरह से ओवरराइड की गई तालिका से वापस लौटे E820h
। mem
और memmap
कर्नेल पैरामीटर ऐसे प्रयोजनों के लिए इस्तेमाल किया जा सकता। जब इनमें से एक या अधिक पैरामीटर वैध मानों के साथ निर्दिष्ट किए जाते हैं, तो कर्नेल पहले BIOS-प्रदान किए गए मेमोरी मैप को पढ़ेगा और तदनुसार बदलाव करेगा। कर्नेल अंतिम मेमोरी मैप को "उपयोगकर्ता द्वारा परिभाषित भौतिक रैम मैप" के रूप में प्रिंट करेगा। कर्नेल संदेश रिंग बफ़र में। आप इन संदेशों को देख सकते हैं dmesg | grep user:
(प्रत्येक मेमोरी रेंज पंक्ति "उपयोगकर्ता:" से शुरू होती है)। इन संदेशों को "BIOS-e820" संदेशों के बाद मुद्रित किया जाएगा।
UEFI फर्मवेयर के साथ बूट किए गए एक x86 प्लेटफ़ॉर्म पर जो संगतता समर्थन मॉड्यूल का समर्थन करता है (अधिक जानकारी के लिए CSM विनिर्देश को देखें, जो UEFI से अलग है), विरासत वास्तविक-मोड E820h
इंटरफ़ेस समर्थित है और डिफ़ॉल्ट रूप से लिनक्स कर्नेल इसका उपयोग करता है। यदि कर्नेल UEFI के साथ x86 प्लेटफ़ॉर्म पर चल रहा है जो CSM का समर्थन नहीं करता है, तो E820h
इंटरफ़ेस सभी या कुछ मेमोरी रेंज प्रदान नहीं कर सकता है। add_efi_memmap
ऐसे प्लेटफार्मों पर कर्नेल पैरामीटर का उपयोग करना आवश्यक हो सकता है । UEFI मेमोरी V E820 मेमोरी में एक उदाहरण पाया जा सकता है । जब एक या अधिक मेमोरी रेंज प्रदान की जाती हैं GetMemoryMap()
, तो कर्नेल इन रेंज को E820h
इंटरफ़ेस से उन लोगों के साथ मिला देता है। परिणामी मेमोरी मैप को किसी dmesg | grep 'efi:'
अन्य UEFI- संबंधित कर्नेल पैरामीटर का उपयोग करके देखा जा सकता है जो मेमोरी मैप को प्रभावित करता है efi_fake_mem
।
ACPI विनिर्देश (धारा 6.3) कर्नेल को सूचित करने के लिए नोटिफिकेशन मैकेनिज्म प्रदान करता है जब किसी IO या DIMM डिवाइस को किसी S- अवस्था में सिस्टम से डाला या हटाया जाता है। (मुझे नहीं पता कि क्या कोई मदरबोर्ड हैं जो किसी भी एस-राज्य में डीआईएमएम को हटाने का समर्थन करते हैं, हालांकि। यह आमतौर पर जी 3 राज्य और संभवत: एस 4 और / या एस 5 में संभव है) जब ऐसी कोई घटना होती है, तो कर्नेल या फर्मवेयर अपने अनुसार मेमोरी मैप में बदलाव करता है। ये परिवर्तन परिलक्षित होते हैं sudo cat /proc/iomem
।
पीसी-रिलेटिव एड्रेसिंग एक प्रोग्रामिंग तकनीक को संदर्भित करता है जहां आपका प्रोग्राम किसी भी पते पर काम कर सकता है। चूंकि स्थानांतरण रजिस्टर (जैसे। खंड) मवाद बन गए हैं, अधिकांश पीसी-सापेक्ष प्रोग्रामिंग स्पष्ट रूप से किया जाता है। यहाँ मशीन कोड के सामान्य प्रकार में एक उदाहरण दिया गया है:
.text
entry:
call reloc /* call is pc relative */
reloc:
pop %r0 /* r0 now contains physical address of reloc */
sub $reloc, %r0, %r14 /* r14 contains difference between link address of reloc */ /* At this point, r14 is a relocation register. A virtual address + r14 == the corresponding physical address. */ add $proot, %r14, %r0 /* physical address of page table root */
add $entry, %r14, %r1 /* entry is where we were loaded into ram */ test $0xfff, %r1 /* someone is being funny and not page aligning us */
jnz bad_alignment
or $0x7, %r1 /* put mythical page protection bits in r1 */ mov $1024, %r2 /* number of pages in r2 */
loop:
store %r1, (%r0) /* store a page table entry */
add $0x1000, %r1 /* setup next one 4096 bytes farther */ add $4, %r0 /* point to next page table entry */
sub $1, r2 /* are we done? */ cmp %0, r2 jne loop /* nope, setup next entry */ add $proot, %r14, %r0
loadsysreg %r0, page_table_base_register
mov $1, %r0 mov $v_entry, %r1
loadsysreg %r0, page_table_enabled
jmp %r1
v_entry:
/* now we are virtually addressed */
call main
1: jmp 1b /* main shouldn't return. */
.data
.align 12 /* 4096 byte pages */
proot:
.zero 4096
.text
यह पौराणिक मशीन एक फ्लैट पेज टेबल के साथ बहुत सरल है, और कर्नेल पते 0 पर जुड़ा हुआ है, लेकिन पहले 4M (1024 * 4096) में कहीं से भी चलाया जा सकता है। असली मशीनें इसके अधिक विस्तृत संस्करण हैं। सामान्य तौर पर, आप सिस्टम भाषाओं पर भी भरोसा नहीं कर सकते, C
जब तक कि आपके पास प्रारंभिक पता स्थान सेटअप नहीं है। एक बार यह हो जाने के बाद, इसमें कोड बहुत अधिक जटिल पेज टेबल, और क्वेरी डेटाबेस जैसे डिवाइस ट्री, या एपर्स्ट / यूफी जैसे राम लेआउट के बारे में अधिक जानकारी के लिए निर्माण कर सकते हैं।
फॉरवर्ड मैप्ड पेज टेबल आर्किटेक्चर में जहां आंतरिक नोड्स पत्ते के नोड्स (x86- क्लासिक, उदाहरण के लिए) के रूप में एक संगत प्रारूप में हैं, आप अधिक लचीली लिंक पते की अनुमति देने के लिए एक सिंगल पेज टेबल का पुन: उपयोग कर सकते हैं । उदाहरण के लिए, यदि आपने proot में अंतिम प्रविष्टि (जो कि proot [1023]) है, को वापस proot में इंगित किया, तो आप अपने OS को 0xffffc000 में लिंक कर सकते हैं, और यह कोड बस काम करेगा (एक बार x86 में अनुवादित)।