के लिए मैं एक लिनक्स कर्नेल ड्राइवर लिख रहा हूं और प्रत्येक कार्य के लिए जो उपयोगकर्ताओं को डेटा भेजता है या उपयोगकर्ता स्पेस से डेटा भेजता है, मैं copy_to_user() और copy_from_user() का उपयोग कर रहा हूं। मेरा सवाल है: क्या मुझे इन कॉलों का उपयोग करने की ज़रूरत है यदि मैं सिर्फ एक मूल डेटा प्रकार की प्रतिलिपि बना रहा हूं जैसे कि u32 या int?copy_to_user() और copy_from_user() मूल डेटा प्रकार
उत्तर
समारोह उपयोगकर्ता के अंतरिक्ष डेटा के लिए एक सूचक प्राप्त करता है, तो आप copy_from_user()
उपयोग करने के लिए कर्नेल अंतरिक्ष (और इसके विपरीत) में उपयोगकर्ता अंतरिक्ष से उठाई-डेटा कॉपी करने के लिए है।
ध्यान दें कि पॉइंटर मान स्वयं मूल्य (सभी सी पैरामीटर की तरह) द्वारा पारित किया जाता है, इसलिए आपको copy_from_user()
को पॉइंटर मान प्राप्त करने के लिए copy_from_user()
डेटा को इंगित करने से पहले copy_from_user()
करने की आवश्यकता नहीं है।
संख्यात्मक तर्क पॉइंटर तर्क के समान काम करते हैं; सी शर्तों में, वे दोनों scalars हैं। पैरामीटर के मान की प्रतिलिपि बनाने के लिए आपको copy_from_user()
का उपयोग करने की आवश्यकता नहीं है; यह पहले से ही कॉपी किया गया है। आपको केवल उस डेटा की प्रतिलिपि बनाने के लिए इसका उपयोग करना होगा जो पास किए गए पॉइंटर द्वारा इंगित किया गया है।
तो यदि आपके पास int
प्रकार का पैरामीटर है, तो आप इसका सीधे उपयोग कर सकते हैं। यदि आपका पैरामीटर int
पर इंगित करता है, तो int
ऑब्जेक्ट उपयोगकर्ता स्थान पर होगा, और आपको उस ऑब्जेक्ट के मान को कर्नेल स्पेस में कॉपी करने के लिए copy_to_user
का उपयोग करने की आवश्यकता है।
मैं आपसे असहमत हूं। मान लीजिए कि उपयोगकर्ता स्थान में एक पॉइंटर पेज गठबंधन नहीं है और आपको इसे पूरा करने के लिए पॉइंटर के दोनों हिस्सों को इकट्ठा करना होगा? कॉल करने के लिए पैरामीटर के रूप में उपयोगकर्ता से प्राप्त एकमात्र चीज उपयोगकर्ता सूचक है, लेकिन यदि यह किसी अन्य उपयोगकर्ता सूचक को इंगित करती है, तो वह पॉइंटर उपयोगकर्ता_copy के साथ अधिग्रहित किया जाना चाहिए। 64 बिट वातावरण में, उपयोगकर्ता सूचक 8 बाइट चौड़ा होता है, और इसे पृष्ठ सीमा में विभाजित किया जा सकता है, इसलिए आपको वर्चुअल पेज टेबल को उपयोगकर्ता स्थान से कर्नेल में अनुवाद करने के लिए acces करना होगा। इसके अलावा, उपयोगकर्ता स्पेस पेजों को बदल दिया जा सकता है, इसलिए इसके साथ सावधान रहें। –
जब आप कहते हैं कि पॉइंटर पेज गठबंधन नहीं है, तो क्या आपका मतलब है कि पॉइंटर ऑब्जेक्ट को गलत तरीके से गलत किया गया है, या डेटा जो इंगित करता है? पॉइंटर्स स्केलर होते हैं और हमेशा मूल्य से गुजरते हैं। यदि सिस्टम कॉल में कहा गया है, तो 'शून्य * 'पैरामीटर, कर्नेल फ़ंक्शन जो सिस्टम कॉल को संभालता है उसे सूचक की * प्रति * प्राप्त होता है; कॉलर पक्ष पर पॉइंटर ऑब्जेक्ट का संरेखण अप्रासंगिक है। –
सरल डेटा प्रकारों (जैसे 'int *') के पॉइंटर्स के लिए, 'put_user' और' get_user' का भी उपयोग किया जा सकता है। – holgac
जब कोई उपयोगकर्ता कर्नेल स्पेस को डेटा पास करता है, तो यह डेटा कई पृष्ठों पर विभाजित किया जा सकता है, और ये पृष्ठ मेमोरी में भी बदल सकते हैं। इन मामलों में, आपको कर्नेल को पृष्ठ में स्वैप करने और उस पृष्ठ तक पहुंच प्राप्त करने की प्रतीक्षा करनी होगी जहां डेटा है। प्राथमिक डेटा प्रकारों (जैसे int या पॉइंटर्स) के मामले में यह भी सच है कि कुछ आर्किटेक्चर (विशेष रूप से x86 इंटेल) उपयोगकर्ता को डेटा संरेखित करने के लिए मजबूर नहीं करता है, इसलिए एक पूर्णांक को पृष्ठ सीमा के चारों ओर विभाजित किया जा सकता है। आपके पास पूर्णांक के पहले भाग तक पहुंच हो सकती है, लेकिन पूरी चीज तक पहुंचने से पहले मेमोरी मैनेजर द्वारा दूसरे को बदलने के लिए प्रतीक्षा करें।
आप सभी उपयोगकर्ता डेटा को उस संरचना में डालकर कुछ राउंडट्रिप्स सहेज सकते हैं जिनके पॉइंटर को कर्नेल में पास किया जाता है। आप एक ब्लॉक के रूप में यह copy_from_user कर सकते हैं और पहुंच को बचाने (और होने का खतरा में चल रहे कई बार अवरुद्ध)
तो, और एक निष्कर्ष के रूप में, , यहां तक कि बुनियादी प्रकार के लिए कार्यों का उपयोग के रूप में उनमें से बहुत सारे हैं। कर्नेल मोड में चलते समय उपयोगकर्ता डेटा कहां हो सकता है इसके बारे में कुछ भी न मानें। आपके पास इसका उपयोग है, लेकिन उपयोगकर्ता डेटा के कर्नेल वर्चुअल पतों में उपयोगकर्ता मोड में देखे गए वर्चुअल पतों से कोई लेना देना नहीं है।
लुइस: मुझे लगता है कि आपने ओपी का गलत व्याख्या किया है। सभी ओपी करने का प्रयास कर रहा है मूल डेटा प्रकार का एक मूल्य पास है। ओपी वास्तव में पूछ रहा है कि संदर्भ के बजाय मूल्य के आधार पर मूल डेटा पास करना संभव है या नहीं। जैसा कि @ किथ इंगित कर रहा था, आम तौर पर एक सूचक पास हो जाता है, और यह सूचक मूल्य से गुजरता है ताकि इसे सीधे एक्सेस किया जा सके। हालांकि यदि आप उपयोगकर्ता पॉइंटर को हटाना चाहते हैं, तो आपको कर्नेल में copy_from_user() या get_user() फ़ंक्शन का उपयोग करना होगा। –
क्षमा करें, लेकिन जैसा कि वह कहता है: * यदि मैं सिर्फ एक मूल डेटा प्रकार की प्रतिलिपि बना रहा हूं जैसे कि u32 या int * अर्थ कॉपी करना, तो मुझे लगता है कि int संदर्भ द्वारा पारित किया गया है (उदाहरण के लिए कुछ मान वापस करने के लिए) बेशक अगर वह केवल कर्नेल के लिए मूल्य गुजर रहा है (लेकिन उपयोगकर्ता स्थान पर वापस नहीं) तो वह ऐसा कर सकता है। मैं ioctl पर सोच नहीं रहा हूं, जहां यह समझ में आता है। मान लीजिए कि वह 'int' करने की कोशिश कर रहा है; लिखो (एफसी, और ए, आकार का ए); '... –
बेशक आप ** ** ** लिखने (2) ** में डेटा के रूप में कर्नेल स्पेस को पास पॉइंटर का उपयोग कर सकते हैं, लेकिन एक बनाने पर ज्यादा समझ नहीं है इस तरह चालक। वह कहता है * ... और हर समारोह के लिए ... * –
- 1. copy_from_user()
- 2. लिनक्स कर्नेल: copy_from_user - पॉइंटर्स
- 3. copy_to_user बनाम memcpy
- 4. मूल डेटा में अभिभावक इकाई और रिश्ते
- 5. ऑब्जेक्ट का मूल प्रकार
- 6. मूल निवासी प्रकार
- 7. मूल डेटा वितरण
- 8. मूल (0,0) से डेटा
- 9. सी #/आयरनपीथन इंटरऑप और "फ्लोट" डेटा प्रकार
- 10. डेटा प्रकार
- 11. डेटा प्रकार
- 12. डेटा प्रकार
- 13. बूस्ट। किसी भी मूल प्रकार
- 14. प्रतिक्रिया मूल कैमरा बारकोड प्रकार
- 15. KnockoutJS में परिवर्तनीय $ डेटा का मूल और उद्देश्य क्या है?
- 16. UIImagePickerControllerOriginalImage बनाम मूल संपत्ति डेटा
- 17. मूल डेटा को छवि सहेजना
- 18. एसक्यूएल सर्वर एक्सएमएल डेटा प्रकार और QUOTED_IDENTIFIER
- 19. सी #, वीबी 6 और दशमलव डेटा प्रकार
- 20. उद्देश्य सी रिलीज, ऑटोरेलीज, और डेटा प्रकार
- 21. डेटा प्रकार बाइट, चार और कम आवश्यक
- 22. डेटा संयोजन। गतिशील और प्रकार वर्ग
- 23. जेडीबीसी टेम्पलेट और इनसेट डेटा प्रकार
- 24. mysql BLOB और टेक्स्ट डेटा प्रकार अंतर
- 25. जेनेरिक प्रकार, स्वामित्व, और लगातार डेटा संरचनाएं
- 26. डेटा प्रकार पाठ और nvarchar ऑपरेटर
- 27. नाममात्र प्रकार की भूमिकाएं और डेटा परिवार
- 28. एसक्यूएल दिनांक डेटा प्रकार और ईएफ 4
- 29. वीबी 6 ऑब्जेक्ट और डेटा प्रकार
- 30. Kotlin डेटा वर्गों और नल प्रकार
आप जो पूछ रहे हैं उसके बारे में कुछ भ्रम है। एक सैंपल फ़ंक्शन घोषणा, यह दर्शाती है कि क्या आप 'int' या 'int' पर पॉइंटर पास कर रहे हैं, यह सहायक होगा। अब तक पोस्ट किए गए दो उत्तरों आपके प्रश्न की दो अलग-अलग व्याख्याओं पर आधारित हैं। –