c++ - आम कार्यक्रम आम तौर पर 0x8000 से क्यों शुरू होता है?




linker bootloader (4)

मैं बूटलोडर और सिस्टम SW के लिए नया नहीं हूँ, लेकिन मैं सामान्य कारण 0x8000 से शुरू होने वाले कारण के मूल को नहीं जानता। मुझे पहले से ही पता है कि पता 0x8000 सामान्य सी / सी ++ प्रोग्राम में आरंभिक पते के रूप में इस्तेमाल किया गया है।

क्या एक सामान्य कार्यक्रम के लिए बूटलोडर का न्यूनतम आकार 0x8000 तक ले जाता है? या ROM का न्यूनतम ब्लॉक आकार है जिसे बूटलोडर 32KB के लिए आवंटित किया जाना चाहिए? या फिर एक और कारण है?

मैं इस बारे में, ऐतिहासिक या तार्किक रूप से और आभासी पते के दृश्य के बारे में जानना चाहता हूं।

मैं सभी की सराहना करता हूँ, अपना समय और इस के साथ मदद प्रश्न को और अधिक स्पष्ट करने के लिए, प्रश्न भौतिक से संबंधित आभासी पते से संबंधित नहीं है

मैं मूल रूप से भौतिक स्मृति पते के दृष्टिकोण से आर की राय से सहमत हूं।

उदाहरण के लिए लिनक्स (यहां तक ​​कि एंड्रॉइड में), सामान्य आरटीओएस (न्यूक्लियस, और अन्य, विशेष रूप से एआरएम लिंकर अनुभाग) के लिए विशिष्ट सिस्टम नहीं कहने के बिना, वे सभी 0x8000 पते का पता प्रारंभ सामान्य कार्यक्रम के रूप में करते हैं। इस क्षेत्र में लोडर के साथ 0x0 पर स्थित crt_begin.o, crt.o, आदि नामित है।

इसलिए मुझे लगता है कि सामान्य कार्यक्रम के लिए बूटलोडर का न्यूनतम आकार 32KB ब्लॉक आकार पर विचार करता है अगर यह बूट समय में बूट्रम (ठंडे बूट) में स्थित होगा।

उम्म, लेकिन मुझे यकीन नहीं है ...


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

मुझे उम्मीद थी कि आज भी, कुछ एम्बेडेड सिस्टम पता 0 पर शुरू होने वाले कार्यक्रम को लोड करते हैं।


सामान्य तौर पर, सबसे छोटे एम्बेडेड सिस्टम पर, प्लेटफॉर्म एबीआई डिज़ाइनर का उपयोग करने में सबसे कम पतों को छोड़ने से बचना है ताकि शून्य पॉइंटर डिरेरेन्स फंस सकें। कभी-वैध पतों के कई KB होने से आपको कुछ अतिरिक्त सुरक्षा मिलती है यदि शून्य सूचक एक सरणी या संरचना के ऑफसेट ऑफसेट के साथ dereferenced होता है, जैसे null_ptr->some_member


मेरा मानना ​​है कि इसका जवाब इंटरप्ट हैंडलिंग से संबंधित है। इंटरप्ट हैंडलर पते हार्डवेयर में सेट किए गए हैं इंटेल 8086 में, इंटरप्ट हैंडलर कोड पर एक सीधी अनुवाद तालिका थी और इसके साथ-साथ इंटरप्ट हैंडलिंग रूटीन था। शायद, यह कुछ संयोजी सर्किट द्वारा किया गया था और इसलिए, आगे संगतता को संरक्षित करने के लिए, हर बार परिवर्तनों को रोकने के लिए अंत में बजाए स्मृति को शुरू करने पर उन्हें जगह देने के लिए अधिक समझदार होता। इसलिए, निष्पादन प्रारंभ पता स्मृति के दूसरे छोर पर होगा साथ ही, यह आवश्यक था कि उस ब्लॉक में पर्याप्त कोड मेमोरी सेगमेंट प्रोग्राम लोड करने के लिए और उस कोड पते से कोड निष्पादित करने के लिए स्विच करने के लिए एक छलांग अनुक्रम होना चाहिए।


यह कुछ हद तक मनमाना है, और लिनक्स पर, लिंकर द्वारा कम से कम तय किया गया है। सामान्य विचार को नल सूचक अपवाद को पकड़ने के लिए कुछ जगह आरक्षित करना है। कर्नेल अवस्था में कर्नेल मोड में अनियंत्रित यूज़र कोड निष्पादित करने से कर्नेल स्पेस नल पॉइंटर डिरेरेन्मेंट को रोकने में मदद करने के लिए, लिनक्स आपको मेमोरी के बहुत नीचे मैप करने से रोकता है। /proc/sys/vm/mmap_min_addr आप जिस न्यूनतम पते को मैप कर सकते हैं उसे नियंत्रित करता है (आप इसे 0 पर बदल सकते हैं और यदि आप चाहें तो 0 पर एक पेज मैप कर सकते हैं)।

लिनक्स पर आप /proc देखकर मेमोरी मैपिंग देख सकते हैं उदाहरण के लिए,

genwitt ~> cat /proc/self/maps 
00400000-0040c000 r-xp 00000000 08:01 354804                             /bin/cat
0060b000-0060c000 r--p 0000b000 08:01 354804                             /bin/cat
0060c000-0060d000 rw-p 0000c000 08:01 354804                             /bin/cat
01dda000-01dfb000 rw-p 00000000 00:00 0                                  [heap]
7f5b25913000-7f5b25a97000 r-xp 00000000 08:01 435953                     /lib64/libc-2.14.1.so
7f5b25a97000-7f5b25c97000 ---p 00184000 08:01 435953                     /lib64/libc-2.14.1.so
7f5b25c97000-7f5b25c9b000 r--p 00184000 08:01 435953                     /lib64/libc-2.14.1.so
7f5b25c9b000-7f5b25c9c000 rw-p 00188000 08:01 435953                     /lib64/libc-2.14.1.so
7f5b25c9c000-7f5b25ca1000 rw-p 00000000 00:00 0 
7f5b25ca1000-7f5b25cc2000 r-xp 00000000 08:01 436061                     /lib64/ld-2.14.1.so
7f5b25cd2000-7f5b25e97000 r--p 00000000 08:01 126248                     /usr/lib64/locale/locale-archive
7f5b25e97000-7f5b25e9a000 rw-p 00000000 00:00 0 
7f5b25ec0000-7f5b25ec1000 rw-p 00000000 00:00 0 
7f5b25ec1000-7f5b25ec2000 r--p 00020000 08:01 436061                     /lib64/ld-2.14.1.so
7f5b25ec2000-7f5b25ec3000 rw-p 00021000 08:01 436061                     /lib64/ld-2.14.1.so
7f5b25ec3000-7f5b25ec4000 rw-p 00000000 00:00 0 
7fff18c37000-7fff18c58000 rw-p 00000000 00:00 0                          [stack]
7fff18d0c000-7fff18d0d000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]






bootloader