2012-01-22 36 views
6

लंबी कहानी संक्षिप्त पर सलाह। मैं सीखना चाहता हूं कि एक अच्छी लिंकर स्क्रिप्ट कैसे बनाएं ताकि मुझे प्लेटफॉर्म/आर्किटेक्चर/विक्रेताओं को बदलना चाहिए, मैं यह जानने के लिए जमीन शून्य पर फंस नहीं रहा हूं कि क्या करना है। मैं कार्य की कठिनाई से चिंतित नहीं हूं, इसे समझने के लिए बहुत कुछ।लिंकर स्क्रिप्ट निर्माण और सत्यापन

मैं क्योंकि यह थे, कार्यक्रमों की के लिए एक आधार या कंकाल बना सकते हैं और एसटीएम के 32-बिट कॉर्टेक्स- एम 3 चिप्स पर विकसित करने के लिए project का एक तरह शुरू कर दिया है,। jsiei97 की मदद से एसटीएम 32 एफ 103 आरबी (मेरे पास एक टीआई स्टालेरिस एलएम 3 एस 828 भी है, लेकिन यह एक और मुद्दा है), लाइसेंस प्राप्त आईडीई की आवश्यकता के बिना। चूंकि मैं एक छात्र हूं, और अधिकांश छात्र ऐसी चीजें बर्दाश्त नहीं कर सकते हैं।

मैं समझता हूं कि ओडेव, और ग्रहण प्लगइन्स और क्या नहीं है, और विभिन्न ब्लॉग, विकी, दस्तावेज़/मैन पेज पढ़ चुके हैं और अधिकांश प्रोजेक्ट आपको एक लिंकर स्क्रिप्ट प्रदान करते हैं, जिसके बारे में स्पष्टीकरण के बारे में पता नहीं है कि क्यों और कहाँ चीजें परिभाषित किया गया है।

मैंने एसटीएम 32 के लिए एक हाथ-नो-एबी टूलचैन संकलित किया है, लेकिन जहां मैं लटका हुआ हूं लिंकर स्क्रिप्ट में है। CodeSourcery भी एक की आवश्यकता है। मेरे पास gnu मैन पेज पढ़ने के बाद उन्हें और उनके वाक्यविन्यास को बनाने का मूल अवधारणा है, लेकिन मुझे बस एक सुराग नहीं है जहां स्पष्ट .text, .bss और .data के अलावा विभिन्न अतिरिक्त खंडों को डालने के साथ शुरू करना है। ।

मैंने rudimentary version बनाया है, लेकिन मुझे अनुभाग परिभाषाओं के लिए पूछताछ त्रुटियों को जोड़ना है और यही वह जगह है जहां मैं अटक गया हूं। मुझे पता है कि उन्हें कैसे परिभाषित किया जाए, लेकिन यह जानकर कि मैं क्या कर रहा हूं, वह भी सही है।

+0

gnu लिंकर स्क्रिप्ट सबसे अच्छा दर्दनाक हैं। और जीसीसी 3.x से 4.x चीजें जो काम करने के लिए प्रयुक्त होती थीं अब काम नहीं करतीं, मुझे लगता है कि यह जारी रहेगा कि इससे कोई फर्क नहीं पड़ता कि आप इसे कितना अच्छा पाते हैं, वे कुछ दिनों में आपके पैरों के नीचे से गले लगाएंगे। –

+0

यह सच है। मैं केवल यही उम्मीद कर सकता हूं। हालांकि 4.x से 5.x तक मुझे कुछ ठोस काम मिल सकता है, और यह परिवर्तन लॉग का पालन करने का विषय होगा। कुछ भी बड़ा बदलाव होना चाहिए। – Crewe

उत्तर

2

यहाँ एक STM32F105RB के लिए एक काम कर लिंकर स्क्रिप्ट है (वहाँ भी कर रहे हैं R8 और आर सी के लिए संस्करण):

https://github.com/anrope/stm-arp/blob/github/arp.rb.ld (नीचे पाठ)

मेरे शीर्ष के- the- सिर अनुमान है कि आप अभ्यस्त है कुछ भी बदलना है। शायद मेमरी {} कथन में परिभाषित क्षेत्रों की उत्पत्ति। उम्मीद है कि टिप्पणियां आपके लिए सहायक होंगी।

मैंने इसे एक जीएनयू/जीसीसी क्रॉस-कंपाइलर के साथ इस्तेमाल किया जो मैंने खुद को लुढ़काया। संकलन के बाद, यह सुनिश्चित करने के लिए कि सही पते पर अनुभागों को रखा जा रहा है, अपने कोड पर nm चलाने में मददगार है।

संपादित करें: मैं जीएनयू ld प्रलेखन का उपयोग करके एक साथ इस लिंकर स्क्रिप्ट pieced:

http://sourceware.org/binutils/docs/ld/

और, मानक लिंकर स्क्रिप्ट के साथ पार संकलन एक जीसीसी के उत्पादन की जांच nm का उपयोग करके। मैंने मूल रूप से उन सभी वर्गों की पहचान की जो आउटपुट थे और यह पता लगाया गया कि कौन से वास्तव में उपयोगी थे, और जहां स्मृति में उन्हें एसटीएम 32 एफ 105 के लिए जाना चाहिए।

मैंने प्रत्येक अनुभाग के उद्देश्य के लिंकर स्क्रिप्ट में नोट्स बनाए हैं।

/* 
arp.{r8,rb,rc}.ld : 
These linker scripts (one for each memory density of the stm32f105) are used by 
the linker to arrange program symbols and sections in memory. This is especially 
important for sections like the interrupt vector, which must be placed where the 
processor is hard-coded to look for it. 
*/ 

/*stm32f105 dev board linker script*/ 

/* 
OUTPUT_FORMAT() defines the BFD (binary file descriptor) format 
OUTPUT_FORMAT(default, big, little) 
*/ 
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") 
/* ENTRY() defines the symbol at which to begin executing code */ 
ENTRY(_start) 
/* tell ld where to look for archive libraries */ 
/*SEARCH_DIR("/home/arp/stm/ctc/arm-eabi/lib")*/ 
/*SEARCH_DIR("/home/arp/stm/ccbuild/method2/install/arm-eabi/lib")*/ 
SEARCH_DIR("/home/arp/stm32dev-root/usrlol/arm-eabi/lib") 

/* 
MEMORY{} defines the memory regions of the target device, 
and gives them an alias for use later in the linker script. 
*/ 

/* stm32f105rb */ 
MEMORY 
{ 
    ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32k 
    flash (rx) : ORIGIN = 0x08000000, LENGTH = 128k 
    option_bytes_rom (rx) : ORIGIN = 0x1FFFF800, LENGTH = 16 
} 

_sheap = _ebss + 4; 
_sstack = _ebss + 4; 
/*placed __stack_base__ trying to figure out 
global variable overwrite issue 
__stack_base__ = _ebss + 4;*/ 

_eheap = ORIGIN(ram) + LENGTH(ram) - 1; 
_estack = ORIGIN(ram) + LENGTH(ram) - 1; 

/* SECTIONS{} defines all the ELF sections we want to create */ 
SECTIONS 
{ 
    /* 
    set . to an initial value (0 here). 
    . (dot) is the location counter. New sections are placed at the 
    location pointed to by the location counter, and the location counter 
    is automatically moved ahead the length of the new section. It is important 
    to maintain alignment (not handled automatically by the location counter). 
    */ 
    . = SEGMENT_START("text-segment", 0); 



    /*isr_vector contains the interrupt vector. 

    isr_vector is read only (could be write too?). 

    isr_vector must appear at start of flash (USR), 
    address 0x0800 0000*/ 
    .isr_vector : 
    { 
     . = ALIGN(4); 
     _sisr_vector = .; 

     *(.isr_vector) 

     _eisr_vector = .; 
    } >flash 

    /*text contains executable code. 

    text is read and execute.*/ 
    .text : 
    { 
     . = ALIGN(4); 
     *(.text) 
     . = ALIGN(4); 
     *(.text.*) 
    } >flash 

    /*init contains constructor functions 
    called before entering main. used by crt (?).*/ 
    .init : 
    { 
     . = ALIGN(4); 
     KEEP(*(.init)) 
    } >flash 

    /*fini contains destructor functions 
    called after leaving main. used by crt (?).*/ 
    .fini : 
    { 
     . = ALIGN(4); 
     KEEP(*(.fini)) 
    } >flash 

    /* rodata contains read only data.*/ 
    .rodata : 
    { 
     . = ALIGN(4); 
     *(.rodata) 

     /* sidata contains the initial values 
     for variables in the data section. 

     sidata is read only.*/ 
     . = ALIGN(4); 
     _sidata = .; 
    } >flash 

    /*data contains all initalized variables. 

    data is read and write. 
    .data (NOLOAD) : AT(_sidata)*/ 
    .data : AT(_sidata) 
    { 
     . = ALIGN(4); 
     _sdata = .; 

     *(.data) 

     _edata = .; 
    } >ram 

    /*bss contains unintialized variables. 

    bss is read and write. 
    .bss (NOLOAD) :*/ 
    .bss : 
    { 
     . = ALIGN(4); 
     _sbss = .; 
     __bss_start__ = .; 

     *(.bss) 
     . = ALIGN(4); 

     /*COMMON is a special section containing 
     uninitialized data. 

     Example: (declared globally) 
     int temp; //this will appear in COMMON */ 
     *(COMMON) 

     _ebss = .; 
     __bss_end__ = .; 
    } >ram AT>flash 

    . = ALIGN(4); 
    end = .; 

     /* remove the debugging information from the standard libraries */ 
    DISCARD : 
    { 
    libc.a (*) 
    libm.a (*) 
    libgcc.a (*) 
    } 

    /* Stabs debugging sections. */ 
    .stab   0 : { *(.stab) } 
    .stabstr  0 : { *(.stabstr) } 
    .stab.excl  0 : { *(.stab.excl) } 
    .stab.exclstr 0 : { *(.stab.exclstr) } 
    .stab.index 0 : { *(.stab.index) } 
    .stab.indexstr 0 : { *(.stab.indexstr) } 
    .comment  0 : { *(.comment) } 
    /* DWARF debug sections. 
     Symbols in the DWARF debugging sections are relative to the beginning 
     of the section so we begin them at 0. */ 
    /* DWARF 1 */ 
    .debug   0 : { *(.debug) } 
    .line   0 : { *(.line) } 
    /* GNU DWARF 1 extensions */ 
    .debug_srcinfo 0 : { *(.debug_srcinfo) } 
    .debug_sfnames 0 : { *(.debug_sfnames) } 
    /* DWARF 1.1 and DWARF 2 */ 
    .debug_aranges 0 : { *(.debug_aranges) } 
    .debug_pubnames 0 : { *(.debug_pubnames) } 
    /* DWARF 2 */ 
    .debug_info  0 : { *(.debug_info .gnu.linkonce.wi.*) } 
    .debug_abbrev 0 : { *(.debug_abbrev) } 
    .debug_line  0 : { *(.debug_line) } 
    .debug_frame 0 : { *(.debug_frame) } 
    .debug_str  0 : { *(.debug_str) } 
    .debug_loc  0 : { *(.debug_loc) } 
    .debug_macinfo 0 : { *(.debug_macinfo) } 
    /* SGI/MIPS DWARF 2 extensions */ 
    .debug_weaknames 0 : { *(.debug_weaknames) } 
    .debug_funcnames 0 : { *(.debug_funcnames) } 
    .debug_typenames 0 : { *(.debug_typenames) } 
    .debug_varnames 0 : { *(.debug_varnames) } 
} 
+0

मुझे बताया गया है कि हम सिर्फ उत्तर में लिंक प्रदान नहीं कर सकते हैं क्योंकि वे बदल सकते हैं लेकिन उस जानकारी को उस उत्तर में लाएं जिसके बारे में हम बात कर रहे हैं। मैंने आपके द्वारा निर्दिष्ट फ़ाइल को आपके उत्तर में जोड़ा है। –

+1

इस स्क्रिप्ट को बनाने के लिए आपको आवश्यक जानकारी कहां प्राप्त हुई? आपको कैसे पता था कि आपको ** _ शेप **, ** _ सिडाटा ** और ** _ sstack ** की आवश्यकता है और उन्हें क्या असाइन करना है। यही वह जानकारी है जिसे मैं ढूंढ रहा हूं। – Crewe

+1

मैंने अपना जवाब संपादित किया। उन अनुभागों में से प्रत्येक (और अधिक) एक मानक लिंकर स्क्रिप्ट का उपयोग करके एक संकलन में दिखाई दिया। स्क्रिप्ट में टिप्पणियों की जांच करें। _sheap ढेर की शुरुआत है, _ स्टैक स्टैक की शुरुआत है। इसे आसान रखने के लिए – anrope

8

मेरे पास एक साधारण लिंकर स्क्रिप्ट है जो मैं प्लेटफॉर्म पर नियमित रूप से पुन: उपयोग करता हूं, बस कुछ पतों को आवश्यकतानुसार बदलता हूं।

http://github.com/dwelch67/

जीसीसी नमूने के साथ कई नमूनों की एक संख्या हैं और उन में से ज्यादातर के संयोजक स्क्रिप्ट हैं।

MEMORY 
{ 
    rom : ORIGIN = 0x00000000, LENGTH = 0x40000 
    ram : ORIGIN = 0x10000000, LENGTH = 30K 
} 

SECTIONS 
{ 
    .text : { *(.text*) } > rom 
    .bss : { *(.bss*) } > ram 
} 
+3

+1। बिल्कुल कोई इसे पढ़ सकता है और समझ सकता है। बहुत से लोग सीधे मेमरी मैप किए गए रजिस्टरों आदि को लिंकर स्क्रिप्ट में रखने की कोशिश करते हैं, और जल्द ही इसे अपने जीवन पर लिया जाता है। अयोग्य होने का जिक्र नहीं है। – Dan

+1

क्या यह कम से कम डेटा अनुभाग गुम नहीं है? (आपके आरंभिक ग्लोबल्स कहां जाएंगे?) – dbrank0

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

  • कोई संबंधित समस्या नहीं^_^