2008-12-14 19 views
18

मेरे सी ++ प्रोग्राम (विंडोज़ पर) में, मैं स्मृति के ब्लॉक को आवंटित कर रहा हूं और यह सुनिश्चित कर सकता हूं कि यह भौतिक स्मृति में लॉक (असफल और संगत) रहता है (यानी वर्चुअलअलोकएक्स(), MapUserPhysicalPages() आदि का उपयोग कर)।वर्चुअल मेमोरी एड्रेस को भौतिक पते पर कैसे अनुवादित करें?

मेरी प्रक्रिया के संदर्भ में, मैं, कि ब्लॉक के आभासी स्मृति पता प्राप्त कर सकते हैं, लेकिन मैं इसे कुछ बाहरी उपकरण को पारित करने के लिए यह की भौतिक स्मृति पते के पता लगाने के लिए की जरूरत है।


1. वहाँ किसी भी तरह से मैं उपयोगकर्ता मोड में मेरी कार्यक्रम के भीतर शारीरिक एक के लिए आभासी पता, अनुवाद कर सकते हैं है?

2. यदि नहीं, तो मैं इस वर्चुअल को केवल केरल मोड में भौतिक मानचित्रण के बारे में पता लगा सकता हूं। मुझे लगता है कि इसका मतलब है कि मुझे ऐसा करने के लिए एक ड्राइवर लिखना है ...? क्या आप किसी भी आसानी से उपलब्ध ड्राइवर/डीएलएल/एपीआई के बारे में जानते हैं जिसका मैं उपयोग कर सकता हूं, कि मेरा एप्लिकेशन (प्रोग्राम) अनुवाद करने के लिए इंटरफ़ेस करेगा?

3. यदि मुझे ड्राइवर को खुद लिखना होगा, तो मैं यह अनुवाद कैसे करूं? मैं किस काम का उपयोग करता हूं? क्या यह mmGetPhysicalAddress() है? मैं इसे कैसे इस्तेमाल करूं?

4. इसके अलावा, अगर मैं सही ढंग से समझता हूं, तो mmGetPhysicalAddress() कॉलिंग प्रक्रिया के संदर्भ में वर्चुअल बेस पते का भौतिक पता देता है। लेकिन अगर बुला प्रक्रिया ड्राइवर है, और मुझे लगता है कि समारोह के लिए ड्राइवर को कॉल करने के अपने आवेदन का उपयोग कर रहा है, मैं संदर्भों को बदलने कर रहा हूँ और मैं एप्लिकेशन जब mmGetPhysicalAddress दिनचर्या कहा जाता है के संदर्भ में नहीं हूं ... इसलिए मैं एप्लिकेशन (उपयोगकर्ता-मोड) मेमोरी स्पेस में वर्चुअल एड्रेस का अनुवाद कैसे करूं, ड्राइवर नहीं?

कोई भी उत्तर, सुझाव और कोड अंश बहुत सराहना की जाएगी !!

धन्यवाद

+0

मैं उत्सुक हूँ, क्या एक बाह्य उपकरण एक भौतिक स्मृति पते के साथ कर सकता है? – jyoung

+0

विवरण में जाकर, यह एक ऑनबोर्ड डिवाइस है जिसकी मशीन की रैम तक सीधी पहुंच है, लेकिन ओएस मैपिंग से अनजान है (यही कारण है कि वर्चुअल एड्रेस या साझा मेमोरी ऑब्जेक्ट का उपयोग नहीं करेगा)। –

उत्तर

4

1) कोई

2) हाँ, आप एक चालक लिखने के लिए की है। सर्वश्रेष्ठ या तो वर्चुअल ड्राइवर होगा, या विशेष-बाहरी डिवाइस के लिए ड्राइवर को बदलें।

3) यह यहां बहुत भ्रमित हो जाता है। MmGetPhysicalAddress विधि आपके लिए लॉक कर होना चाहिए, लेकिन मैं वास्तव में नहीं जानता कि कैसे भौतिक पता बैंक/चिप/आदि के लिए मैप किया गया है। भौतिक स्मृति पर।

4) आप पेजेड मेमोरी का उपयोग नहीं कर सकते हैं, क्योंकि यह स्थानांतरित हो जाता है। आप एक एमडीएल पर MmProbeAndLockPages के साथ पेजेड मेमोरी को लॉक कर सकते हैं, आप उपयोगकर्ता मोड कॉलिंग संदर्भ से पारित मेमोरी पर बना सकते हैं। लेकिन गैर-पेजेड मेमोरी आवंटित करना और आपके उपयोगकर्ता मोड एप्लिकेशन को हाथ देना बेहतर है।

PVOID p = ExAllocatePoolWithTag(NonPagedPool, POOL_TAG); 
PHYSICAL_ADDRESS realAddr = MmGetPhysicalAddress(p); 

// use realAddr 
12

मेरी सी ++ प्रोग्राम (Windows पर) में, मैं स्मृति का एक ब्लॉक का आवंटन कर रहा हूँ और यकीन है कि यह भौतिक स्मृति में लॉक रहता है (unswapped और सन्निहित) (यानी VirtualAllocEx(), MapUserPhysicalPages() का उपयोग कर सकते हैं आदि)।

नहीं है, तुम सच में सुनिश्चित नहीं कर सकते कि यह लॉक रहे। क्या होगा यदि आपकी प्रक्रिया दुर्घटनाग्रस्त हो जाती है, या जल्दी निकलती है? क्या होगा यदि उपयोगकर्ता इसे मारता है? यही कारण है कि स्मृति के लिए कुछ और दोबारा इस्तेमाल किया जाएगा, और यदि आपका डिवाइस अभी भी डीएमए कर रहा है, है कि अंततः डेटा हानि/भ्रष्टाचार या किसी बग जाँच (बीएसओडी) का परिणाम देगा।

इसके अलावा, MapUserPhysicalPages विंडोज एडब्ल्यूई (पता विंडिंग एक्सटेंशन) का हिस्सा है, जो विंडोज सर्वर के 32-बिट संस्करणों पर 4 जीबी से अधिक रैम को संभालने के लिए है। मुझे नहीं लगता कि इसका उद्देश्य उपयोगकर्ता-मोड डीएमए को हैक करने के लिए किया जाना था।

1. क्या कोई तरीका है कि मैं वर्चुअल एड्रेस को अपने प्रोग्राम में भौतिक एक में उपयोगकर्ता मोड में अनुवाद कर सकता हूं?

ऐसे ड्राइवर हैं जो आपको ऐसा करने देते हैं, लेकिन आप विंडोज़ पर उपयोगकर्ता मोड से डीएमए प्रोग्राम नहीं कर सकते हैं और अभी भी एक स्थिर और सुरक्षित प्रणाली है। एक सीमित उपयोगकर्ता खाते के रूप में चलने वाली प्रक्रिया को पढ़ने/लिखने के लिए भौतिक स्मृति को उस प्रक्रिया को सिस्टम के स्वामित्व की अनुमति मिलती है। यदि यह एक-ऑफ सिस्टम या प्रोटोटाइप के लिए है, तो यह संभवतः स्वीकार्य है, लेकिन यदि आप अपने सॉफ़्टवेयर और आपके डिवाइस का उपयोग करने के लिए अन्य लोगों (विशेष रूप से भुगतान करने वाले ग्राहकों) की अपेक्षा करते हैं, तो आपको ड्राइवर लिखना चाहिए।

2. यदि नहीं, तो मैं इस वर्चुअल को केवल केरल मोड में भौतिक मानचित्रण के बारे में पता लगा सकता हूं। मुझे लगता है कि इसका मतलब है कि मुझे ऐसा करने के लिए एक ड्राइवर लिखना है ...?

इस समस्या से संपर्क करने का यह अनुशंसित तरीका है।

क्या आप किसी भी आसानी से उपलब्ध ड्राइवर/डीएलएल/एपीआई के बारे में जानते हैं जिसका मैं उपयोग कर सकता हूं, कि मेरा एप्लिकेशन (प्रोग्राम) अनुवाद करने के लिए इंटरफ़ेस करेगा?

आप उपयोगकर्ता-मोड प्रक्रिया के स्वामित्व वाले मेमोरी बफर समेत मनमाने ढंग से स्मृति को लॉक करने के लिए MDL (Memory Descriptor List) का उपयोग कर सकते हैं और इसके आभासी पते को भौतिक पते में अनुवाद कर सकते हैं। METHOD_IN_DIRECT या METHOD_OUT_DIRECT का उपयोग कर आप DeviceIoControl पर कॉल में पारित बफर के लिए अस्थायी रूप से एक एमडीएल बना सकते हैं।

ध्यान दें कि आभासी पता स्थान में संगत पृष्ठ भौतिक पता स्थान में लगभग कभी भी संगत नहीं होते हैं। उम्मीद है कि आपका डिवाइस इसे संभालने के लिए डिज़ाइन किया गया है।

3. अगर मुझे ड्राइवर को खुद लिखना पड़ेगा, तो मैं यह अनुवाद कैसे करूं? मैं किस काम का उपयोग करता हूं? क्या यह mmGetPhysicalAddress() है? मैं इसे कैसे इस्तेमाल करूं?

कुछ एपीआई को कॉल करने से ड्राइवर को लिखने के लिए बहुत कुछ है। यदि आप एक ड्राइवर लिखने जा रहे हैं, तो मैं MSDN और OSR से जितनी प्रासंगिक सामग्री पढ़ सकता हूं उसे पढ़ने की सलाह दूंगा। इसके अलावा, Windows Driver Kit में उदाहरण देखें।

4. इसके अलावा, अगर मैं सही ढंग से समझता हूं, तो mmGetPhysicalAddress() कॉलिंग प्रक्रिया के संदर्भ में वर्चुअल बेस पते का भौतिक पता देता है। लेकिन अगर कॉलिंग प्रक्रिया ड्राइवर है, और मैं उस फ़ंक्शन के लिए ड्राइवर को कॉल करने के लिए अपने एप्लिकेशन का उपयोग कर रहा हूं, तो मैं संदर्भ बदल रहा हूं और जब मैं mmGetPhysicalAddress routine कहलाता हूं तो मैं ऐप के संदर्भ में नहीं हूं ... इसलिए मैं एप्लिकेशन (उपयोगकर्ता-मोड) मेमोरी स्पेस में वर्चुअल एड्रेस का अनुवाद कैसे करूं, ड्राइवर नहीं?

ड्राइवर्स प्रक्रिया नहीं हैं। एक ड्राइवर किसी भी प्रक्रिया के संदर्भ में, साथ ही विभिन्न उन्नत संदर्भ (हस्तक्षेप हैंडलर और डीपीसी) के संदर्भ में चला सकता है।

4

आप वास्तव में इस तरह की चीजें usermode में नहीं करनी चाहिए; जैसा कि क्रिस्टोफर कहता है, आपको पृष्ठों को लॉक करने की आवश्यकता है ताकि जब कोई डिवाइस इसका उपयोग कर रहा हो, तो एमएम आपकी बैकिंग मेमोरी को पेज करने का निर्णय नहीं लेता है, जो यादृच्छिक स्मृति पृष्ठों को दूषित कर देगा।

लेकिन अगर बुला प्रक्रिया ड्राइवर है, और मुझे लगता है कि समारोह के लिए ड्राइवर को कॉल करने के अपने आवेदन का उपयोग कर रहा है, मैं संदर्भों को बदलने कर रहा हूँ और मैं अनुप्रयोग के संदर्भ में नहीं हूं जब mmGetPhysicalAddress दिनचर्या

ड्राइवर्स के पास उपयोगकर्ता-मोड ऐप्स जैसे संदर्भ नहीं हैं; यदि आप किसी आईओसीटीएल या किसी चीज़ के माध्यम से ड्राइवर में कॉल कर रहे हैं, तो आप आमतौर पर कॉलिंग उपयोगकर्ता थ्रेड के संदर्भ में होने के लिए (लेकिन गारंटी नहीं है!) हैं। लेकिन वास्तव में, इससे कोई फर्क नहीं पड़ता कि आप क्या पूछ रहे हैं, क्योंकि कर्नेल-मोड मेमोरी (0x80000000 से ऊपर कुछ भी) वही मैपिंग है चाहे आप कहीं भी हों, और आप कर्नेल पक्ष में स्मृति आवंटित करना समाप्त कर देंगे। लेकिन फिर, एक उचित ड्राइवर लिखें। WDF (http://www.microsoft.com/whdc/driver/wdf/default.mspx) का उपयोग करें, और यह एक सही ड्राइवर को बहुत आसान बना देगा (हालांकि अभी भी बहुत मुश्किल है, विंडोज चालक लेखन आसान नहीं है)

संपादित करें: बस सोचा कि मैं आपकी मदद करने के लिए कुछ पुस्तक संदर्भ फेंक दूंगा , आपको निश्चित रूप से (यदि आप ड्राइवर लिखने का पीछा नहीं करते हैं) भी देखें) Russinovich और Solomon द्वारा Windows Internals पढ़ें (http://www.amazon.com/Microsoft-Windows-Internals-4th-Server/dp/0735619174/ref=pd_bbs_sr_2?ie=UTF8&s=books&qid=1229284688&sr=8-2); माइक्रोसॉफ्ट विंडोज चालक मॉडल प्रोग्रामिंग भी अच्छा है (http://www.amazon.com/Programming-Microsoft-Windows-Driver-Second/dp/0735618038/ref=sr_1_1?ie=UTF8&s=books&qid=1229284726&sr=1-1)

-2

रुको, और भी कुछ है। अपने ग्राहक के Vista 64 बिट पर चलने के विशेषाधिकार के लिए, आप अपने कर्नल मोड ड्राइवर को माइक्रोसॉफ्ट,

4

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

METHOD_IN_DIRECT या METHOD_OUT_DIRECT का उपयोग करके आप अपने ड्राइवर को आईओसीटीएल (डिवाइसकंट्रोल फ़ंक्शन के माध्यम से) भेजकर, एक एमडीएल, या मेमोरी डिस्क्रिप्टर सूची नामक बफर का विवरण प्राप्त कर सकते हैं। IOCTL को परिभाषित करने की चर्चा के लिए निम्न पृष्ठ देखें।

http://msdn.microsoft.com/en-us/library/ms795909.aspx

अब आप अपने डिवाइस के लिए एक ड्राइवर में बफर का एक विवरण है, तो आप इसे लॉक कर सकते हैं ताकि बफर पूरी अवधि है कि आपके डिवाइस उस पर कार्य कर सकते हैं के लिए स्मृति में बनी हुई है। एमएसडीएन पर एमएमप्रोब एंड लॉकपेज देखें।

आपका डिवाइस बफर में सभी मेमोरी को पढ़ने या लिखने में सक्षम नहीं हो सकता है या नहीं। डिवाइस केवल 32-बिट डीएमए का समर्थन कर सकता है और मशीन में 4 जीबी से अधिक रैम हो सकते हैं। या आप ऐसी मशीन से निपट रहे हैं जिसमें आईओएमएमयू, एक जीएआरटी या कुछ अन्य पता अनुवाद तकनीक है। इसे समायोजित करने के लिए, अपने डिवाइस द्वारा उपयोग के लिए अच्छे लॉजिकल पतों का एक सेट प्राप्त करने के लिए विभिन्न डीएमए एपीआई का उपयोग करें। कई मामलों में, ये तार्किक पते उन भौतिक पते के बराबर होंगे जो आपके प्रश्न के बारे में पूछे जाने पर पूछे जाते हैं, लेकिन हमेशा नहीं।

आपके द्वारा उपयोग किए जाने वाले डीएमए एपीआई इस बात पर निर्भर करता है कि आपका डिवाइस स्कैटर/इकट्ठा सूचियों और ऐसे संभाल सकता है या नहीं। आपका ड्राइवर, अपने सेटअप कोड में, IoGetDmaAdapter को कॉल करेगा और इसके द्वारा लौटाए गए कुछ कार्यों का उपयोग करेगा।

आमतौर पर, आपको GetScatterGatherList और PutScatterGatherList में रुचि होगी। आप एक फ़ंक्शन (निष्पादन routine) प्रदान करते हैं जो वास्तव में आपके हार्डवेयर को स्थानांतरण करने के लिए प्रोग्राम करता है।

इसमें बहुत सारे विवरण शामिल हैं। शुभ लाभ।

4

आप उपयोगकर्ता स्थान से पृष्ठ सारणी तक नहीं पहुंच सकते हैं, वे कर्नेल में मैप किए गए हैं।

यदि आप कर्नेल में हैं, तो आप मूल पृष्ठ तालिका पता का पता लगाने के लिए सीआर 3 के मूल्य का निरीक्षण कर सकते हैं और फिर अपना संकल्प शुरू कर सकते हैं।

This blog series में यह कैसे करना है इसका एक अद्भुत स्पष्टीकरण है। वर्चुअल < -> भौतिक पते को हल करने के लिए आपको किसी भी ओएस सुविधा/API की आवश्यकता नहीं है।

वर्चुअल पता: f9a10054

1: kd> .formats 0xf9a10054 
Binary: 11111001 10100001 00000000 01010100 

Page Directory Pointer Index(PDPI)  11      Index into 

1 तालिका (पृष्ठ निर्देशिका सूचक तालिका) पृष्ठ निर्देशिका सूचकांक (PDI) 2 तालिका में
111,001 101 सूचकांक (पृष्ठ निर्देशिका तालिका) पृष्ठ तालिका सूचकांक (पीटीआई)
00001 0000 इंडेक्सतालिका (पृष्ठ तालिका) बाइट इंडेक्स
0000 01010100 0x054, ऑफ़सेट भौतिक मेमोरी पेज

उनके उदाहरण में, वे विंडबग का उपयोग करते हैं,! डीक एक भौतिक स्मृति पढ़ा जाता है।

enter image description here