2013-03-20 8 views
5

में स्थान को अपनाने के लिए हम लिनक्स छवि को कैसे लोड कर सकते हैं हम एक विशिष्ट स्थान पर हमारे डीआरएएम में लिनक्स छवि लोड करने की कोशिश कर रहे हैं, डीआरएएम एंड एड्रेस 0x80000000 है जिसे हम बूट लॉग से जानते हैं जो कहता है "मेम डिवाइस एंडिंग पता 0x80000000 है eaxmple के लिए फिर से बूट लॉग से 0x5000000 "और छवि में है कि variuos अनुभाग कुछ पता है जो से अधिक है पर लोड हो रहा से पहले" 0x80000000 "" हम पते पर हमारी छवि लोड कर रहे हैं ",मेमोरी

loading section to address 0xc5000000 from file position 0x1000, size is 0x5ac13e 

क्या अर्थ उपरोक्त पंक्ति में "फ़ाइल स्थिति 0x1000 से"।

प्रथम खंड लोड .text अनुभाग, इसलिए पूर्ण .लेकिन एक बात हम यहाँ देख सकते पोस्ट नहीं है नीचे अनुभाग शीर्ष लेख

[Nr]  Name   Type   Addr  Off Size ES Flg Lk Inf Al 

[ 0]      NULL   00000000 000000 000000 00  0 0 0 

[ 1] .text   PROGBITS  c5000000 001000 5ac13e 00 AX 0 0 4096 

[ 2]  .notes   NOTE   c55ac140 5ad140 000168 00 AX 0 0 4 

[ 3] __ex_table  PROGBITS  c55ac2b0 5ad2b0 000fe0 00 A 0 0 4 

[ 4] .rodata   PROGBITS  c55ae000 5af000 20a930 00 A 0 0 64 

[ 5] __bug_table  PROGBITS  c57b8930 7b9930 0075fc 00 A 0 0 1 

[ 6] .pci_fixup  PROGBITS  c57bff2c 7c0f2c 001a90 00 A 0 0 4 

[ 7] .builtin_fw  PROGBITS  c57c19bc 7c29bc 0000cc 00 A 0 0 4 

इसकी काफी एक बड़ी सूची के बारे में हमारी vmlinux छवि डंप है। टेक्स्ट सेक्शन डीआरएएम एंड एड्रेस से बड़ा है, इसलिए छवि को सही ढंग से दर्ज नहीं किया जाना चाहिए, हालांकि हमें पहले सेक्शन को लोड करने के बाद कोई त्रुटि नहीं मिल रही है, यह अन्य वर्गों को लोड करने पर रखती है लेकिन इस संदेश के बाद यह लटकती है।

program load complete, entry point: 0x5000000, size: 0x92e7fc 

मेरा प्रश्न है कि कैसे मैं इन विभिन्न वर्गों हमारे DRAM पते पर संबोधित संरेखित कर सकते हैं, objcopy उपयोगिता यहां इस्तेमाल किया जा सकता इन विभिन्न वर्गों के पते को बदलने की है।

क्या संकलन से पहले इन अनुभागों को सेट करने का कोई तरीका है ?? दूसरी बात यह है कि इस हैंग प्रोग्राम प्रोग्राम लोड के लिए क्या कारण हो सकता है।

+0

एक इनाम अच्छा है, लेकिन क्योंकि सवाल काफी जानकारीपूर्ण नहीं है जरूरी नहीं कि आप एक समाधान प्राप्त करने के लिए जा रहा है और क्योंकि हम अपने कोड नहीं देख सकता। आप मूल रूप से लोगों को अंधेरे में शूट करने के लिए कह रहे हैं। –

+0

हां एलेक्सी आपने पहले से ही मेरे प्रश्न का उत्तर दिया है, मैंने सोचा कि इस सवाल पर और अधिक विचार करना अच्छा विचार है। मैं नहीं चाहता कि लोग मेरी समस्या का समाधान करें क्योंकि तब मैं अपने आप से नहीं सीखूंगा, सिर्फ दो जोड़े रखना चाहता था अच्छे विचारों के –

+0

वास्तव में अच्छा बिंदु। –

उत्तर

6

from file position 0x1000 का अर्थ यह है कि यह क्या कहता है। आप डंप में यह है:

[Nr]  Name   Type   Addr  Off Size ES Flg Lk Inf Al 
... 
[ 1] .text   PROGBITS  c5000000 001000 5ac13e 00 AX 0 0 4096 

यह जहां .text अनुभाग फ़ाइल में शुरू होता है है, पर 0x1000 ऑफसेट।

लेकिन एक बात हम यहाँ अनुभाग .text देख सकते हैं की तुलना में DRAM अंत पता

नहीं अधिक से अधिक है, यह अधिक से अधिक (के अर्थ में बड़ा, कम से कम नहीं), यह नहीं है उम्मीद में संकलित किया गया है कि यह स्मृति में 0xc5000000 पते पर लोड किया जाएगा।

तो छवि ठीक loded नहीं किया जाना चाहिए, हालांकि हम प्रथम खंड यह अन्य वर्गों

लोड हो रहा है छवि कहीं भी लोड किया जा सकता रहती है लोड करने के बाद किसी भी त्रुटि नहीं मिल रहा है, यह सिर्फ के प्रयोजन के लिए डेटा है लोड हो रहा है।

ओटीओएच, यदि loading section to address 0xc5000000 का अर्थ है कि यह क्या कहता है, तो फ़ाइल कहीं भी लोड नहीं हो जाती है क्योंकि आपकी रैम 0x7fffffff पर समाप्त होती है।

लेकिन इस संदेश के बाद यह लटकता है।

और इसकी उम्मीद है। मशीन कोड शायद ही कभी स्थिति-स्वतंत्र है और इसलिए यदि आप इसे किसी स्थान पर लोड करते हैं, जहां से इसे लोड किया जाना चाहिए, तो यह काम नहीं करेगा। या अगर यह भी लोड नहीं होता है, तो आप निष्पादित करने के लिए क्या जा रहे हैं? कचरा।

क्या संकलन से पहले इन अनुभागों को सेट करने का कोई तरीका है ??

प्रणाली के आधार पर आप विकल्प नीचे दो या दोनों में से एक हो सकता है:

  • इस तरह से पेज अनुवाद की स्थापना की है कि 0xc5000000 से और पते के लिए नक्शे अप 0x5000000 से आभासी पते और पूरे कार्यक्रम
  • लिंकर स्क्रिप्ट है जो आपके संकलक का उपयोग करने और 0x5000000 करने के लिए 0xc5000000 से प्रारंभिक खंड पता बदलने है खोजने के लिए, यह ऊपर गूगल, देख संकलक/लिंकर प्रलेखन

इसके अलावा, यह थोड़ा विचित्र है कि प्रविष्टि बिंदु 0x5000000 पर है। यह नहीं कि यह जरूरी है कि यह गलत है, यह सिर्फ इतना ही मामला है। मैं सुनिश्चित करता हूं कि start लेबल (या _start या जो भी हो) वास्तव में .text अनुभाग की शुरुआत के समान ही पता प्राप्त करता है। यदि, किसी कारण से, यह मामला नहीं है, तो लिंकर स्क्रिप्ट या कंपाइलर/लिंकर कमांड लाइन विकल्पों या लोडर के साथ कुछ गड़बड़ है।

+0

आपकी तरह की प्रतिक्रिया के लिए धन्यवाद @Alexey। चीजों की संख्या आपके साथ साझा करना चाहती है जो मुझे अपने प्रश्न में याद आई, प्रविष्टि बिंदु 0x5000000 कर्नेल की .config फ़ाइल को बदलकर हमारे द्वारा बदल दिया गया है क्योंकि डिफ़ॉल्ट पते पर छवि लोड नहीं कर सका 0x1000000। दूसरी बात यह है कि हमने पहले एक ही डीआरएएम में एक क्यूएनएक्स आधारित कर्नेल छवि को लोड और निष्पादित किया है, अब हम लिनक्स कर्नेल छवि और एक और बिंदु के लिए क्यूएनएक्स छवि के लिए इस्तेमाल किए गए अनुभागों और एंट्री पॉइंट पते के लिए समान पते का उपयोग कर सकते हैं आपने उठाया है कि प्रविष्टि बिंदु .text खंड का हिस्सा है। –

+0

क्या यह अब हम अनुभागों और प्रविष्टि बिंदु पते के लिए समान पते का उपयोग कर सकते हैं जिनका उपयोग क्यूएनएक्स छवि के लिए यहां लिनक्स कर्नेल छवि के लिए किया गया है? मैं तुम्हारा मुद्दा बिल्कुल नहीं देखता हूं। –

+0

हाय एलेसेक्सी जैसा कि आपने पृष्ठ ऑफसेट मान को बदलने के बाद सुझाव दिया था, 2 जीबी रेंज के भीतर सेक्शन पता मिला और प्रोग्राम लोड पूरा होने के बाद, हमारी छवि संदेश नहीं लगी है, लेकिन हम दूसरी समस्या में भाग गए, जल्द ही इसका कहना है कि प्रोग्राम लोड पूर्ण हो गया है, लिनक्स कर्नेल छवि पर नियंत्रण देने के बजाय सीपीयू रीसेट हो रहा है, इस मामले पर आपके अंत से एक शब्द या दो सुनना चाहूंगा। –

3

आप किस लोडर का उपयोग करते हैं? "छवि" का रूप क्या है? यू-बूट छवि, कच्ची एक, vmlinux ईएलएफ फ़ाइल? मुझे लगता है कि अनुभागों के अस्तित्व के आधार पर आखिरी फैसला, इत्यादि। ईएलएफ फ़ाइल से आपको अनुभागों को लोड नहीं करना चाहिए बल्कि प्रोग्राम हेडर भी कहा जाना चाहिए। उदाहरण के लिए इस OpenRISC लिनक्स कर्नेल कार्यक्रम हेडर लिस्टिंग (प्राप्त readelf -l का उपयोग) है:

Elf file type is EXEC (Executable file) 
Entry point 0xc0000000 
There are 2 program headers, starting at offset 52 

Program Headers: 
    Type   Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align 
    LOAD   0x002000 0xc0000000 0x00000000 0x231728 0x232000 RWE 0x2000 
    LOAD   0x234000 0xc0232000 0x00232000 0x17c78c 0x18bfcc RWE 0x2000 

Section to Segment mapping: 
    Segment Sections... 
    00  .text .rodata __ksymtab __ksymtab_gpl __ksymtab_strings __param __modver 
    01  .data __ex_table .head.text .init.text .init.data .bss 

VirtAddr और PhysAddr के बीच का अंतर देखें (सामान्य लिनक्स कर्नेल मानचित्रण के कारण c गिरा दिया)। स्वाभाविक रूप से, लोड करने के लिए भौतिक पता का उपयोग किया जाना चाहिए।

कारण कर्नेल प्रतीकों के लिए वर्चुअल पतों का उपयोग कर रहा है, खंड आदि यह है कि बूट के दौरान आप एमएमयू प्रारंभ होने पर उस पल में जल्दी से प्रवेश करते हैं, वर्चुअल पते तब केवल वैध होते हैं।

और आखिरकार, उन पते को बदलने के बारे में। दरअसल, जैसा कि एलेक्सी द्वारा इंगित किया गया है, लिंकर स्क्रिप्ट कुंजी है। आप इन्हें arch/(your arch)/kernel/vmlinux.lds.S में पा सकते हैं। लेकिन मुद्दा यह है कि यह आईएमओ आपकी समस्या नहीं है, समस्या शायद लोडर या उसके विकल्पों में निहित है।

1

की जाँच करें अपने कट्टर/हाथ/मच-xxx/Makefile.boot (आप हाथ बोर्ड का उपयोग ना?)

zreladdr-y  += 0x80008000 
params_phys-y  := 0x80000100 
initrd_phys-y  := 0x80800000 

यह ती OMAP3 चिप से है।

के रूप में मुझे लगता है कि आप की आवश्यकता होगी एक ही

+0

प्रतिक्रिया @liyaoshi के लिए धन्यवाद लेकिन हम x86 बोर्ड –

+0

पर हैं इस उत्तर के लिए खेद है, मैं एक गलती करता हूं। मैंने सोचा 0x80000000 यह आपके बोर्ड का प्रारंभ पता था। – liyaoshi

संबंधित मुद्दे