एक अच्छा टीओसी और अधिक सामग्री के साथ इस उत्तर का संस्करण ।
मैं रिपोर्ट की गई किसी भी त्रुटि को ठीक करूंगा। यदि आप बड़े संशोधन करना चाहते हैं या एक लापता पहलू जोड़ना चाहते हैं, तो उन्हें अपने जवाबों पर अच्छी तरह से योग्य प्रतिनिधि प्राप्त करें। माइनर एडिट को सीधे मर्ज किया जा सकता है।
नमूना कोड
न्यूनतम उदाहरण: https://github.com/cirosantilli/x86-bare-metal-examples/blob/5c672f73884a487414b3e21bd9e579cbcd77721/paging.S
प्रोग्रामिंग में सब कुछ की तरह, वास्तव में यह समझने का एकमात्र तरीका न्यूनतम उदाहरणों के साथ खेलना है।
यह एक "कठिन" विषय बनाता है कि न्यूनतम उदाहरण बड़ा है क्योंकि आपको अपना खुद का छोटा ओएस बनाने की आवश्यकता है।
इंटेल मैनुअल
हालांकि मन में उदाहरणों के बिना समझना असंभव है, जितनी जल्दी हो सके मैनुअल से परिचित होने का प्रयास करें।
इंटेल इंटेल मैनुअल वॉल्यूम 3 सिस्टम प्रोग्रामिंग गाइड में पेजिंग का वर्णन करता है - 325384-056US सितंबर 2015 अध्याय 4 "पेजिंग"।
विशेष रूप से दिलचस्प है चित्रा 4-4 "सीआर 3 के प्रारूप और 32-बिट पेजिंग के साथ पेजिंग-स्ट्रक्चर एंट्रीज", जो प्रमुख डेटा संरचनाएं देता है।
MMU
पेजिंग CPU के मेमोरी मैनेजमेंट यूनिट (MMU) भाग द्वारा किया जाता है । कई अन्य (जैसे x87 सह-प्रोसेसर , APIC ) की तरह, यह शुरुआती दिनों में अलग चिप के द्वारा हुआ करता था, जिसे बाद में सीपीयू में एकीकृत किया गया था। लेकिन यह शब्द अभी भी प्रयोग किया जाता है।
सामान्य तथ्य
तार्किक पते "नियमित" उपयोगकर्ता-भूमि कोड (जैसे सामग्री rsi
में mov eax, [rsi]
) में उपयोग किए जाने वाले मेमोरी पते हैं ।
पहले विभाजन उन्हें रैखिक पतों में अनुवादित करता है, और फिर पेजिंग फिर रैखिक पतों का भौतिक पतों में अनुवाद करता है।
(logical) ------------------> (linear) ------------> (physical)
segmentation paging
अधिकांश समय, हम वास्तविक पतों को वास्तविक रैम हार्डवेयर मेमोरी कोशिकाओं को अनुक्रमित करने के रूप में सोच सकते हैं, लेकिन यह 100% सच नहीं है क्योंकि:
पेजिंग केवल संरक्षित मोड में उपलब्ध है। संरक्षित मोड में पेजिंग का उपयोग वैकल्पिक है। यदि रजिस्टर PG
थोड़ा सा cr0
सेट है तो पेजिंग चालू है।
पेजिंग बनाम विभाजन
पेजिंग और विभाजन के बीच एक बड़ा अंतर यह है कि:
- पेजिंग रैम पेज के बराबर आकार के विखंडू में विभाजित हो जाता है
- विभाजन, स्मृति को मनमाने आकार के टुकड़ों में विभाजित करता है
यह पेजिंग का मुख्य लाभ है, क्योंकि समान आकार के चोक चीजों को अधिक प्रबंधनीय बनाते हैं।
पेजिंग इतना अधिक लोकप्रिय हो गया है कि 64-बिट मोड में विभाजन के लिए समर्थन x86-64 में गिरा दिया गया था, नए सॉफ्टवेयर के लिए ऑपरेशन का मुख्य मोड, जहां यह केवल संगतता मोड में मौजूद है, जो IA32 का अनुकरण करता है।
आवेदन
पेजिंग का उपयोग आधुनिक ओएस पर प्रक्रियाओं को संबोधित करने के लिए किया जाता है। आभासी पतों के साथ ओएस एक ही रैम पर दो या अधिक समवर्ती प्रक्रियाओं को इस तरह से फिट कर सकता है:
- दोनों कार्यक्रमों को दूसरे के बारे में कुछ भी जानने की जरूरत नहीं है
- दोनों कार्यक्रमों की स्मृति आवश्यकतानुसार बढ़ सकती है और सिकुड़ सकती है
- कार्यक्रमों के बीच स्विच बहुत तेज है
- एक कार्यक्रम कभी भी किसी अन्य प्रक्रिया की मेमोरी तक नहीं पहुँच सकता है
ऐतिहासिक रूप से पेजिंग विभाजन के बाद आया, और बड़े पैमाने पर इसे आधुनिक ओएस जैसे लिनक्स में वर्चुअल मेमोरी के कार्यान्वयन के लिए बदल दिया गया क्योंकि चर लंबाई के खंडों के बजाय पृष्ठों की स्मृति के निश्चित आकार के टुकड़ों का प्रबंधन करना आसान है।
हार्डवेयर कार्यान्वयन
संरक्षित मोड में विभाजन की तरह (जहां एक सेगमेंट रजिस्टर को संशोधित करना GDT या LDT से लोड को ट्रिगर करता है), पेजिंग हार्डवेयर अपना काम करने के लिए मेमोरी में डेटा संरचनाओं का उपयोग करता है (पेज टेबल, पेज डायरेक्टरी, आदि)।
उन डेटा संरचनाओं का प्रारूप हार्डवेयर द्वारा तय किया गया है , लेकिन यह रैम पर उन डेटा संरचनाओं को सही ढंग से स्थापित करने और प्रबंधित करने के लिए ओएस पर निर्भर है, और हार्डवेयर को यह बताने के लिए कि उन्हें (कहां cr3
) ढूंढना है ।
कुछ अन्य आर्किटेक्चर सॉफ्टवेयर के हाथों में लगभग पूरी तरह से पेजिंग छोड़ देते हैं, इसलिए पेज टेबल पर चलने और टीएलबी में नई मैपिंग डालने के लिए एक टीएलबी मिस एक ओएस-आपूर्ति फ़ंक्शन चलाता है। यह ओएस द्वारा चुने जाने वाले पेज टेबल फॉर्मेट्स को छोड़ देता है, लेकिन यह हार्डवेयर के लिए पेज-वॉक को अन्य निर्देशों के आउट-ऑफ-ऑर्डर निष्पादन के साथ ओवरलैप करने में सक्षम होने की संभावना नहीं बनाता है , जिस तरह से x86 कर सकता है ।
उदाहरण: सरलीकृत एकल-स्तरीय पेजिंग योजना
यह एक उदाहरण है कि वर्चुअल मेमोरी स्पेस को लागू करने के लिए x86 आर्किटेक्चर के सरलीकृत संस्करण पर पेजिंग कैसे संचालित होती है।
पेज टेबल
ओएस उन्हें निम्नलिखित पेज टेबल दे सकता है:
ओएस द्वारा प्रक्रिया 1 को दी गई पृष्ठ तालिका:
RAM location physical address present
----------------- ----------------- --------
PT1 + 0 * L 0x00001 1
PT1 + 1 * L 0x00000 1
PT1 + 2 * L 0x00003 1
PT1 + 3 * L 0
... ...
PT1 + 0xFFFFF * L 0x00005 1
ओएस द्वारा 2 प्रक्रिया करने के लिए दी गई पृष्ठ तालिका:
RAM location physical address present
----------------- ----------------- --------
PT2 + 0 * L 0x0000A 1
PT2 + 1 * L 0x0000B 1
PT2 + 2 * L 0
PT2 + 3 * L 0x00003 1
... ... ...
PT2 + 0xFFFFF * L 0x00004 1
कहाँ पे:
PT1
और PT2
: रैम पर तालिका 1 और 2 की प्रारंभिक स्थिति।
मानों का नमूना: 0x00000000
, 0x12345678
, आदि
यह ओएस है जो उन मूल्यों को तय करता है।
L
: पृष्ठ तालिका प्रविष्टि की लंबाई।
present
: इंगित करता है कि पृष्ठ स्मृति में मौजूद है।
पेज टेबल रैम पर स्थित हैं। वे उदाहरण के लिए स्थित हो सकते हैं:
--------------> 0xFFFFFFFF
--------------> PT1 + 0xFFFFF * L
Page Table 1
--------------> PT1
--------------> PT2 + 0xFFFFF * L
Page Table 2
--------------> PT2
--------------> 0x0
दोनों पृष्ठ तालिकाओं के लिए RAM पर प्रारंभिक स्थान OS द्वारा मनमानी और नियंत्रित किए जाते हैं। यह सुनिश्चित करने के लिए ओएस पर निर्भर है कि वे ओवरलैप नहीं करते हैं!
प्रत्येक प्रक्रिया किसी भी पेज टेबल को सीधे नहीं छू सकती है, हालांकि यह ओएस के लिए अनुरोध कर सकती है जिससे पेज टेबल संशोधित हो सकती है, उदाहरण के लिए बड़े स्टैक या हीप सेगमेंट के लिए पूछना।
एक पृष्ठ 4KB (12 बिट्स) का एक हिस्सा है, और चूंकि पते में 32 बिट्स हैं, केवल 20 बिट्स (20 + 12 = 32, इस प्रकार हेक्साडेसिमल नोटेशन में 5 वर्ण) को प्रत्येक पृष्ठ की पहचान करना आवश्यक है। यह मान हार्डवेयर द्वारा तय किया जाता है।
पृष्ठ तालिका प्रविष्टियाँ
एक पृष्ठ तालिका है ... पृष्ठों की तालिका प्रविष्टियों की एक तालिका!
तालिका प्रविष्टियों का सटीक प्रारूप हार्डवेयर द्वारा तय किया गया है ।
इस सरलीकृत उदाहरण में, पृष्ठ तालिका प्रविष्टियों में केवल दो फ़ील्ड हैं:
bits function
----- -----------------------------------------
20 physical address of the start of the page
1 present flag
इसलिए इस उदाहरण में हार्डवेयर डिजाइनरों को चुना जा सकता था L = 21
।
अधिकांश वास्तविक पृष्ठ तालिका प्रविष्टियों में अन्य फ़ील्ड हैं।
यह 21 बिट्स पर चीजों को संरेखित करने के लिए अव्यवहारिक होगा क्योंकि मेमोरी बाइट्स द्वारा संबोधित की जाती है और बिट्स नहीं। इसलिए, इस मामले में भी केवल 21 बिट्स की आवश्यकता होती है, हार्डवेयर डिजाइनर शायद L = 32
तेजी से पहुंच बनाने के लिए चुनते हैं , और बाद में उपयोग के लिए शेष बिट्स को आरक्षित करते हैं। L
X86 पर वास्तविक मान 32 बिट्स है।
एकल-स्तरीय योजना में पता अनुवाद
एक बार ओएस द्वारा पृष्ठ तालिकाओं की स्थापना की गई है, रैखिक और भौतिक पते के बीच का अनुवाद हार्डवेयर द्वारा किया जाता है ।
जब OS प्रक्रिया 1 को सक्रिय करना चाहता है, तो यह प्रक्रिया एक के लिए, तालिका की शुरुआत cr3
को सेट करता है PT1
।
यदि प्रक्रिया 1 रैखिक पते का उपयोग करना चाहती है 0x00000001
, तो पेजिंग हार्डवेयर सर्किट ओएस के लिए स्वचालित रूप से निम्न कार्य करता है:
रैखिक पता को दो भागों में विभाजित करें:
| page (20 bits) | offset (12 bits) |
तो इस मामले में हमारे पास होगा:
- पेज = 0x00000
- ऑफसेट = 0x001
पृष्ठ 1 में देखें क्योंकि cr3
यह इंगित करता है।
प्रविष्टि देखें 0x00000
क्योंकि वह पृष्ठ भाग है।
हार्डवेयर जानता है कि यह प्रविष्टि रैम पते पर स्थित है PT1 + 0 * L = PT1
।
चूंकि यह मौजूद है, पहुंच वैध है
पृष्ठ तालिका द्वारा, पृष्ठ संख्या 0x00000
का स्थान पर है 0x00001 * 4K = 0x00001000
।
अंतिम भौतिक पता खोजने के लिए हमें केवल ऑफ़सेट जोड़ने की आवश्यकता है:
00001 000
+ 00000 001
-----------
00001 001
क्योंकि 00001
पृष्ठ का भौतिक पता तालिका पर देखा गया 001
है और ऑफसेट है।
जैसा कि नाम से संकेत मिलता है, ऑफसेट को हमेशा पृष्ठ का भौतिक पता जोड़ा जाता है।
हार्डवेयर तब उस भौतिक स्थान पर मेमोरी प्राप्त करता है।
उसी तरह, निम्नलिखित अनुवाद प्रक्रिया 1 के लिए होगा:
linear physical
--------- ---------
00000 002 00001 002
00000 003 00001 003
00000 FFF 00001 FFF
00001 000 00000 000
00001 001 00000 001
00001 FFF 00000 FFF
00002 000 00002 000
FFFFF 000 00005 000
उदाहरण के लिए, पता एक्सेस करते समय 00001000
, पृष्ठ भाग 00001
हार्डवेयर होता है, यह जानता है कि इसकी पृष्ठ तालिका प्रविष्टि RAM पते पर स्थित है: PT1 + 1 * L
( 1
पृष्ठ भाग के कारण), और वह वह जगह है जहाँ यह इसके लिए दिखेगा।
जब OS 2 को संसाधित करने के लिए स्विच करना चाहता है, तो उसे केवल cr3
पृष्ठ 2 पर बिंदु बनाना होगा। यह इतना आसान है!
अब निम्नलिखित अनुवाद प्रक्रिया 2 के लिए होंगे:
linear physical
--------- ---------
00000 002 00001 002
00000 003 00001 003
00000 FFF 00001 FFF
00001 000 00000 000
00001 001 00000 001
00001 FFF 00000 FFF
00003 000 00003 000
FFFFF 000 00004 000
एक ही रैखिक पता अलग-अलग प्रक्रियाओं के लिए अलग-अलग भौतिक पते में अनुवाद करता है , केवल अंदर के मूल्य पर निर्भर करता है cr3
।
इस तरह हर कार्यक्रम सटीक भौतिक पतों की चिंता किए बिना अपने डेटा को शुरू 0
और खत्म होने की उम्मीद कर सकता है FFFFFFFF
।
पृष्ठ दोष
क्या होगा यदि प्रक्रिया 1 एक पृष्ठ के अंदर एक पते तक पहुंचने की कोशिश करती है जो मौजूद नहीं है?
हार्डवेयर एक पृष्ठ दोष अपवाद के माध्यम से सॉफ्टवेयर को सूचित करता है।
यह आमतौर पर ओएस पर निर्भर होता है कि एक अपवाद हैंडलर को यह दर्ज करने के लिए कि क्या किया जाना है।
यह संभव है कि पृष्ठ पर नहीं है एक पृष्ठ तक पहुँचने के लिए एक प्रोग्रामिंग त्रुटि है:
int is[1];
is[2] = 1;
लेकिन ऐसे मामले हो सकते हैं जिनमें यह स्वीकार्य है, उदाहरण के लिए जब लिनक्स में:
कार्यक्रम अपने स्टैक को बढ़ाना चाहता है।
यह बस एक निश्चित सीमा में एक निश्चित बाइट तक पहुंचने की कोशिश करता है, और अगर ओएस खुश है तो यह उस पेज को प्रोसेस एड्रेस स्पेस में जोड़ता है।
पृष्ठ को डिस्क पर स्वैप किया गया था।
पेज को रैम में वापस लाने के लिए ओएस को प्रक्रियाओं के पीछे कुछ काम करना होगा।
OS यह पता लगा सकता है कि यह पृष्ठ तालिका प्रविष्टि के बाकी हिस्सों की सामग्री पर आधारित है, क्योंकि यदि वर्तमान ध्वज स्पष्ट है, तो पृष्ठ तालिका प्रविष्टि की अन्य प्रविष्टियाँ पूरी तरह से OS के लिए छोड़ दी जाती हैं कि वह क्या चाहती है।
लिनक्स पर उदाहरण के लिए, जब वर्तमान = 0:
यदि पृष्ठ तालिका प्रविष्टि के सभी क्षेत्र 0, अमान्य पते हैं।
और, पृष्ठ को डिस्क पर स्वैप किया गया है, और उन फ़ील्ड के वास्तविक मान डिस्क पर पृष्ठ की स्थिति को कूटबद्ध करते हैं।
किसी भी मामले में, ओएस को यह जानने की जरूरत है कि समस्या से निपटने में सक्षम होने के लिए कौन सा पता पेज फॉल्ट उत्पन्न करता है। यही कारण है कि अच्छा IA32 डेवलपर्स cr2
जब भी पृष्ठ दोष होता है, तो उस पते का मूल्य निर्धारित करता है। अपवाद हैंडलर तब केवल cr2
पता प्राप्त करने के लिए देख सकता है।
सरलीकरण
वास्तविकता का सरलीकरण जो इस उदाहरण को समझने में आसान बनाता है:
सभी वास्तविक पेजिंग सर्किट अंतरिक्ष को बचाने के लिए बहु-स्तरीय पेजिंग का उपयोग करते हैं, लेकिन यह एक साधारण एकल-स्तरीय योजना दिखाती है।
पृष्ठ तालिकाओं में केवल दो फ़ील्ड शामिल थे: एक 20 बिट पता और 1 बिट वर्तमान ध्वज।
वास्तविक पृष्ठ तालिकाओं में कुल 12 फ़ील्ड होते हैं, और इसलिए अन्य सुविधाएँ जिन्हें छोड़ दिया गया है।
उदाहरण: बहु-स्तरीय पेजिंग योजना
एकल-स्तरीय पेजिंग योजना के साथ समस्या यह है कि इसमें बहुत अधिक रैम होगी: प्रति प्रक्रिया 4 जी / 4K = 1M प्रविष्टियां । यदि प्रत्येक प्रविष्टि 4 बाइट्स लंबी है, तो यह 4M प्रति प्रक्रिया बना देगा , जो कि डेस्कटॉप कंप्यूटर के लिए भी बहुत अधिक है: ps -A | wc -l
कहते हैं कि मैं अभी 244 प्रक्रियाएँ चला रहा हूँ, ताकि मेरी RAM लगभग 1GB हो जाए!
इस कारण से, x86 डेवलपर्स ने बहु-स्तरीय योजना का उपयोग करने का निर्णय लिया जो रैम उपयोग को कम करता है।
इस प्रणाली का नकारात्मक पक्ष यह है कि इसका उपयोग थोड़ा अधिक है।
पीएई के बिना 32 बिट प्रोसेसर के लिए उपयोग की जाने वाली सरल 3 स्तरीय पेजिंग योजना में, 32 पते बिट्स को निम्नानुसार विभाजित किया गया है:
| directory (10 bits) | table (10 bits) | offset (12 bits) |
प्रत्येक प्रक्रिया में एक और केवल एक पेज डायरेक्टरी जुड़ी होनी चाहिए, इसलिए इसमें कम से कम 2^10 = 1K
पेज डायरेक्टरी एंट्रीज होंगी , जो कि सिंगल-लेवल स्कीम पर आवश्यक न्यूनतम 1M से बहुत बेहतर है।
पेज टेबल केवल ओएस द्वारा आवश्यकतानुसार आवंटित किए जाते हैं। प्रत्येक पृष्ठ तालिका में 2^10 = 1K
पृष्ठ निर्देशिका प्रविष्टियाँ हैं
पृष्ठ निर्देशिकाओं में शामिल हैं ... पृष्ठ निर्देशिका प्रविष्टियाँ! पृष्ठ निर्देशिका प्रविष्टियाँ पृष्ठ तालिका प्रविष्टियों के समान होती हैं सिवाय इसके कि वे सारणी के भौतिक पतों के बजाय पृष्ठ तालिकाओं के RAM पतों की ओर इंगित करती हैं । चूंकि वे पते केवल 20 बिट्स चौड़े हैं, इसलिए पेज टेबल 4KB पेजों की शुरुआत में होनी चाहिए।
cr3
अब पृष्ठ तालिकाओं के बजाय वर्तमान प्रक्रिया के पृष्ठ निर्देशिका की रैम पर स्थान को इंगित करता है।
एकल-स्तरीय योजना से पृष्ठ तालिका प्रविष्टियाँ बिल्कुल नहीं बदलती हैं।
एकल-स्तरीय योजना से पृष्ठ तालिकाएँ बदल जाती हैं क्योंकि:
- प्रत्येक प्रक्रिया में 1K पेज टेबल, एक पेज डायरेक्टरी प्रविष्टि हो सकती है।
- प्रत्येक पृष्ठ तालिका में 1M प्रविष्टियों के बजाय 1K प्रविष्टियाँ होती हैं।
पहले दो स्तरों (और नहीं, कहते हैं 12 | 8 | 12
) पर 10 बिट्स का उपयोग करने का कारण यह है कि प्रत्येक पृष्ठ तालिका प्रविष्टि 4 बाइट्स लंबी है। तब पृष्ठ निर्देशिकाओं और पेज टेबल्स की 2 ^ 10 प्रविष्टियां 4K पेज में अच्छी तरह से फिट होंगी। इसका मतलब यह है कि यह उस उद्देश्य के लिए पृष्ठों को आवंटित करने और उनसे निपटने के लिए तेज़ और सरल है।
बहु-स्तरीय योजना में पता अनुवाद
OS द्वारा पेज 1 को संसाधित करने के लिए दी गई पृष्ठ निर्देशिका:
RAM location physical address present
--------------- ----------------- --------
PD1 + 0 * L 0x10000 1
PD1 + 1 * L 0
PD1 + 2 * L 0x80000 1
PD1 + 3 * L 0
... ...
PD1 + 0x3FF * L 0
OS PT1 = 0x10000000
( 0x10000
* 4K) पर 1 द्वारा प्रोसेस करने के लिए दी गई पेज टेबल :
RAM location physical address present
--------------- ----------------- --------
PT1 + 0 * L 0x00001 1
PT1 + 1 * L 0
PT1 + 2 * L 0x0000D 1
... ...
PT1 + 0x3FF * L 0x00005 1
OS PT2 = 0x80000000
( 0x80000
* 4K) पर 1 द्वारा प्रोसेस करने के लिए दी गई पेज टेबल :
RAM location physical address present
--------------- ----------------- --------
PT2 + 0 * L 0x0000A 1
PT2 + 1 * L 0x0000C 1
PT2 + 2 * L 0
... ...
PT2 + 0x3FF * L 0x00003 1
कहाँ पे:
PD1
: RAM पर प्रक्रिया 1 की पृष्ठ निर्देशिका की प्रारंभिक स्थिति।
PT1
और PT2
: रैम पर प्रक्रिया 1 के लिए पेज टेबल 1 और पेज टेबल 2 की प्रारंभिक स्थिति।
तो इस उदाहरण में पेज डायरेक्टरी और पेज टेबल को कुछ इस तरह रैम में स्टोर किया जा सकता है:
----------------> 0xFFFFFFFF
----------------> PT2 + 0x3FF * L
Page Table 1
----------------> PT2
----------------> PD1 + 0x3FF * L
Page Directory 1
----------------> PD1
----------------> PT1 + 0x3FF * L
Page Table 2
----------------> PT1
----------------> 0x0
आइए, रैखिक पता 0x00801004
चरण का अनुवाद करें ।
हमें लगता है कि cr3 = PD1
, यह सिर्फ वर्णित पृष्ठ निर्देशिका को इंगित करता है।
बाइनरी में रैखिक पता है:
0 0 8 0 1 0 0 4
0000 0000 1000 0000 0001 0000 0000 0100
समूह के रूप में 10 | 10 | 12
देता है:
0000000010 0000000001 000000000100
0x2 0x1 0x4
जो देता है:
- पृष्ठ निर्देशिका प्रविष्टि = 0x2
- पृष्ठ तालिका प्रविष्टि = 0x1
- ऑफसेट = 0x4
इसलिए हार्डवेयर पेज डायरेक्टरी के एंट्री 2 के लिए दिखता है।
पेज डायरेक्टरी टेबल कहती है कि पेज टेबल पर स्थित है 0x80000 * 4K = 0x80000000
। यह प्रक्रिया का पहला रैम एक्सेस है।
चूँकि पेज टेबल एंट्री है 0x1
, हार्डवेयर पेज टेबल के एंट्री 1 पर दिखता है 0x80000000
, जो बताता है कि भौतिक पेज एड्रेस पर स्थित है 0x0000C * 4K = 0x0000C000
। यह प्रक्रिया का दूसरा रैम एक्सेस है।
अंत में, पेजिंग हार्डवेयर ऑफसेट जोड़ता है, और अंतिम पता है 0x0000C004
।
अनुवादित पतों के अन्य उदाहरण हैं:
linear 10 10 12 split physical
-------- --------------- ----------
00000001 000 000 001 00001001
00001001 000 001 001 page fault
003FF001 000 3FF 001 00005001
00400000 001 000 000 page fault
00800001 002 000 001 0000A001
00801008 002 001 008 0000C008
00802008 002 002 008 page fault
00B00001 003 000 000 page fault
पृष्ठ दोष तब होते हैं यदि पृष्ठ निर्देशिका प्रविष्टि या पृष्ठ तालिका प्रविष्टि मौजूद नहीं है।
यदि OS दूसरी प्रक्रिया को समवर्ती रूप से चलाना चाहता है, तो यह दूसरी प्रक्रिया को एक अलग पृष्ठ निर्देशिका प्रदान करेगा, और उस निर्देशिका को अलग-अलग पृष्ठ तालिकाओं से लिंक करेगा।
64-बिट आर्किटेक्चर
वर्तमान बिट आकार के लिए 64 बिट अभी भी बहुत अधिक पता है, इसलिए अधिकांश आर्किटेक्चर कम बिट का उपयोग करेंगे।
x86_64 48 बिट्स (256 TiB) का उपयोग करता है, और विरासत मोड का PAE पहले से ही 52-बिट पते (4 PiB) की अनुमति देता है।
उन 48 बिट्स में से 12 पहले से ही ऑफसेट के लिए आरक्षित हैं, जो 36 बिट्स को छोड़ देता है।
यदि 2 स्तर का दृष्टिकोण लिया जाता है, तो सबसे अच्छा विभाजन दो 18 बिट स्तर होगा।
लेकिन इसका मतलब यह होगा कि पेज डायरेक्टरी में 2^18 = 256K
प्रविष्टियां होंगी , जिसमें बहुत अधिक रैम होगी: 32 बिट आर्किटेक्चर के लिए एकल-स्तरीय पेजिंग के करीब!
इसलिए, 64 बिट आर्किटेक्चर और भी पेज स्तर बनाते हैं, आमतौर पर 3 या 4।
x86_64 किसी 9 | 9 | 9 | 12
योजना में 4 स्तरों का उपयोग करता है , ताकि ऊपरी स्तर केवल 2^9
उच्च स्तर की प्रविष्टियाँ लेता है ।
पीएई
भौतिक पता विस्तार।
32 बिट्स के साथ, केवल 4GB रैम को संबोधित किया जा सकता है।
यह बड़े सर्वरों के लिए एक सीमा बनना शुरू हो गया, इसलिए इंटेल ने पीएई तंत्र को पेंटियम प्रो में पेश किया।
समस्या से छुटकारा पाने के लिए, इंटेल ने 4 नई एड्रेस लाइन्स जोड़ीं, ताकि 64GB को संबोधित किया जा सके।
पृष्ठ तालिका संरचना भी बदल दी जाती है यदि PAE चालू है। जिस तरीके से इसे बदला गया है, वह इस बात पर निर्भर करता है कि PSE चालू या बंद है।
पीएई को PAE
बिट के माध्यम से चालू और बंद किया जाता है cr4
।
भले ही कुल पता करने योग्य मेमोरी 64GB हो, लेकिन व्यक्तिगत प्रक्रिया अभी भी केवल 4GB तक उपयोग करने में सक्षम है। हालाँकि OS विभिन्न प्रक्रियाओं को अलग-अलग 4GB विखंडू पर रख सकता है।
सार्वजनिक उपक्रम
पृष्ठ आकार विस्तार।
4K के बजाय पृष्ठों की लंबाई 4M (या PAM पर है तो 2M) है।
PSE को PAE
बिट के माध्यम से चालू और बंद किया जाता है cr4
।
पीएई और पीएसई पेज टेबल योजनाएं
यदि पीएई और पीएसई सक्रिय हैं, तो विभिन्न पेजिंग स्तर की योजनाओं का उपयोग किया जाता है:
कोई PAE और कोई PSE: 10 | 10 | 12
कोई पीएई और पीएसई: नहीं 10 | 22
।
22 बिट्स 4Mb पृष्ठ के भीतर ऑफसेट है, क्योंकि 22 बिट्स 4Mb को संबोधित करते हैं।
पीएई और कोई पीएसई: 2 | 9 | 9 | 12
डिज़ाइन का कारण 10 के बजाय 9 का उपयोग किया जाता है, क्योंकि अब प्रविष्टियाँ 32 बिट्स में फिट नहीं हो सकती हैं, जो सभी 20 पते बिट्स और 12 सार्थक या आरक्षित फ़्लैग बिट्स द्वारा भरे गए थे।
कारण यह है कि पृष्ठ तालिकाओं के पते का प्रतिनिधित्व करने के लिए 20 बिट्स पर्याप्त नहीं हैं: प्रोसेसर में 4 अतिरिक्त तारों को जोड़ने के कारण अब 24 बिट्स की आवश्यकता होती है।
इसलिए, डिजाइनरों ने प्रवेश का आकार 64 बिट तक बढ़ाने का फैसला किया, और उन्हें एक ही पृष्ठ तालिका में फिट करने के लिए प्रविष्टियों की संख्या 2 ^ 10 के बजाय 2 ^ 9 तक कम करना आवश्यक है।
के बाद से यह शुरू करने से 2, एक नया पृष्ठ के स्तर का कहा जाता है पृष्ठ निर्देशिका सूचक तालिका (PDPT) है बताते पेज निर्देशिका और पता रैखिक 32 बिट में भरने के लिए। PDPT भी 64 बिट्स चौड़े हैं।
cr3
अब पीडीपीटी की ओर इशारा करता है जो मुट्ठी की 4 4GB मेमोरी पर होना चाहिए और दक्षता को संबोधित करने के लिए 32 बिट गुणकों पर संरेखित किया जाना चाहिए। इसका मतलब यह है कि अब cr3
पहले के 4GB के 2 ^ 32 को पूरा करने के लिए 32 गुणकों के लिए 20: 2 ^ 5 के बजाय 27 महत्वपूर्ण बिट्स हैं।
PAE और PSE: 2 | 9 | 21
डिजाइनरों ने एक एकल पृष्ठ में फिट होने के लिए एक 9 बिट चौड़े मैदान को रखने का फैसला किया।
इससे 23 बिट्स निकलते हैं। पीएसई के लिए पीएई मामले के साथ समान रखने के लिए पीएसपी के लिए 2 छोड़कर, ऑफसेट के लिए 21 छोड़ देता है, जिसका अर्थ है कि पृष्ठ 4 एम के बजाय 2 एम व्यापक हैं।
TLB
अनुवाद लुकाहेड बफर (TLB) पेजिंग पतों के लिए एक कैश है।
चूंकि यह एक कैश है, इसलिए यह सीपीयू कैश के कई डिजाइन मुद्दों को साझा करता है, जैसे कि एसोसिएटिविटी स्तर।
यह खंड 4 एकल पते प्रविष्टियों के साथ एक सरलीकृत पूरी तरह से साहचर्य TLB का वर्णन करेगा। ध्यान दें कि अन्य कैश की तरह, असली टीएलबी आमतौर पर पूरी तरह से सहयोगी नहीं होते हैं।
मूल परिचालन
रैखिक और भौतिक पते के बीच अनुवाद होने के बाद, इसे टीएलबी पर संग्रहीत किया जाता है। उदाहरण के लिए, 4 प्रविष्टि टीएलबी निम्नलिखित अवस्था में शुरू होती है:
valid linear physical
------ ------- ---------
> 0 00000 00000
0 00000 00000
0 00000 00000
0 00000 00000
>
वर्तमान प्रविष्टि को बदला जाएगा इंगित करता है।
और एक पृष्ठ के बाद रैखिक पता 00003
एक भौतिक पते पर अनुवादित किया 00005
जाता है, टीएलबी बन जाता है:
valid linear physical
------ ------- ---------
1 00003 00005
> 0 00000 00000
0 00000 00000
0 00000 00000
और का एक दूसरा अनुवाद के बाद 00007
के लिए 00009
यह हो जाता है:
valid linear physical
------ ------- ---------
1 00003 00005
1 00007 00009
> 0 00000 00000
0 00000 00000
अब अगर 00003
फिर से अनुवाद करने की आवश्यकता है, तो हार्डवेयर पहले टीएलबी को देखता है और एक सिंगल रैम एक्सेस के साथ अपना पता ढूंढता है 00003 --> 00005
।
बेशक, 00000
टीएलबी पर नहीं है 00000
क्योंकि एक कुंजी के रूप में कोई वैध प्रविष्टि शामिल नहीं है ।
प्रतिस्थापन नीति
जब टीएलबी भरा जाता है, तो पुराने पते लिखे जाते हैं। सीपीयू कैश के लिए की तरह, प्रतिस्थापन नीति एक संभावित जटिल ऑपरेशन है, लेकिन एक सरल और उचित अनुमानी हाल ही में उपयोग की गई प्रविष्टि (LRU) को हटा देना है।
LRU के साथ, राज्य से शुरू:
valid linear physical
------ ------- ---------
> 1 00003 00005
1 00007 00009
1 00009 00001
1 0000B 00003
जोड़ना 0000D -> 0000A
होगा:
valid linear physical
------ ------- ---------
1 0000D 0000A
> 1 00007 00009
1 00009 00001
1 0000B 00003
सीएएम
टीएलबी का उपयोग करने से अनुवाद में तेजी आती है, क्योंकि प्रारंभिक अनुवाद प्रति टीएलबी स्तर तक एक पहुंच लेता है , जिसका अर्थ है कि एक साधारण 32 बिट योजना पर 2, लेकिन 64 बिट आर्किटेक्चर पर 3 या 4।
टीएलबी को आम तौर पर एक महंगी प्रकार की रैम के रूप में लागू किया जाता है जिसे सामग्री-पता योग्य मेमोरी (सीएएम) कहा जाता है। सीएएम हार्डवेयर पर एक साहचर्य मानचित्र को लागू करता है, अर्थात, एक संरचना जो एक कुंजी (रैखिक पता) दी गई है, एक मान प्राप्त करता है।
मैपिंग को रैम पतों पर भी लागू किया जा सकता है, लेकिन सीएएम मैपिंग में रैम मैपिंग की तुलना में बहुत कम प्रविष्टियों की आवश्यकता हो सकती है।
उदाहरण के लिए, एक नक्शा जिसमें:
- दोनों कुंजियों और मूल्यों में 20 बिट्स हैं (एक साधारण पेजिंग योजनाओं का मामला)
- प्रत्येक समय पर अधिकतम 4 मूल्यों को संग्रहीत करने की आवश्यकता होती है
4 प्रविष्टियों के साथ एक TLB में संग्रहीत किया जा सकता है:
linear physical
------- ---------
00000 00001
00001 00010
00010 00011
FFFFF 00000
हालाँकि, RAM के साथ इसे लागू करने के लिए, 2 ^ 20 पते होना आवश्यक होगा :
linear physical
------- ---------
00000 00001
00001 00010
00010 00011
... (from 00011 to FFFFE)
FFFFF 00000
जो कि TLB का उपयोग करने से भी अधिक महंगा होगा।
प्रविष्टियों को अमान्य कर रहा है
जब cr3
परिवर्तन होते हैं, तो सभी टीएलबी प्रविष्टियां अमान्य हो जाती हैं, क्योंकि एक नई प्रक्रिया के लिए एक नई पृष्ठ तालिका का उपयोग किया जाने वाला है, इसलिए यह संभव नहीं है कि पुरानी प्रविष्टियों में से किसी का कोई अर्थ हो।
X86 invlpg
निर्देश भी प्रदान करता है जो स्पष्ट रूप से एकल TLB प्रविष्टि को अमान्य करता है। अन्य आर्किटेक्चर टीएलबी प्रविष्टियों को अमान्य करने के लिए और भी अधिक निर्देश प्रदान करते हैं, जैसे किसी दिए गए सीमा पर सभी प्रविष्टियों को अमान्य करना।
कुछ x86 सीपीयू x86 विनिर्देश की आवश्यकताओं से परे जाते हैं और एक पृष्ठ तालिका प्रविष्टि को संशोधित करने और इसका उपयोग करने के बीच , इसकी गारंटी से अधिक सामंजस्य प्रदान करते हैं , जब यह टीएलबी में पहले से ही कैश नहीं था । जाहिरा तौर पर विंडोज 9x ने शुद्धता के लिए उस पर भरोसा किया, लेकिन आधुनिक एएमडी सीपीयू सुसंगत पेज-वॉक प्रदान नहीं करते हैं। इंटेल सीपीयू करते हैं, भले ही उन्हें ऐसा करने के लिए गलत-अटकलों का पता लगाना हो। इसका फायदा उठाना शायद एक बुरा विचार है, क्योंकि संभवतः बहुत कुछ हासिल करने के लिए नहीं है, और सूक्ष्म समय-संवेदनशील समस्याओं को पैदा करने का एक बड़ा जोखिम है जो डिबग करना कठिन होगा।
लिनक्स कर्नेल उपयोग
लिनक्स कर्नेल छोटे डेटा विखंडन के साथ तेज़ प्रक्रिया स्विच की अनुमति देने के लिए x86 की पेजिंग सुविधाओं का व्यापक उपयोग करता है।
के v4.2
तहत, देखो arch/x86/
:
include/asm/pgtable*
include/asm/page*
mm/pgtable*
mm/page*
ऐसा लगता है कि पृष्ठों को दर्शाने के लिए परिभाषित कोई संरचना नहीं है, केवल मैक्रोज़: include/asm/page_types.h
विशेष रूप से दिलचस्प है। अंश:
#define _PAGE_BIT_PRESENT 0 /* is present */
#define _PAGE_BIT_RW 1 /* writeable */
#define _PAGE_BIT_USER 2 /* userspace addressable */
#define _PAGE_BIT_PWT 3 /* page write through */
arch/x86/include/uapi/asm/processor-flags.h
परिभाषित करता है CR0
, और विशेष रूप से PG
बिट स्थिति:
#define X86_CR0_PG_BIT 31 /* Paging */
ग्रन्थसूची
नि: शुल्क:
गैर-मुक्त: