2012-01-22 24 views
6

Ngắn câu chuyện dài. Tôi muốn tìm hiểu làm thế nào để tạo ra một kịch bản liên kết tốt để tôi nên thay đổi nền tảng/kiến ​​trúc/nhà cung cấp, tôi không bị mắc kẹt ở mặt đất bằng không một lần nữa mà không biết phải làm gì. Tôi không quan tâm đến những khó khăn của nhiệm vụ, nhiều như hiểu nó.Lời khuyên về việc tạo và xác minh kịch bản liên kết

Tôi đã bắt đầu một loại project, như vậy, để tạo cơ sở hoặc bộ xương để lập trình và phát triển trên các chip Cortex-M3 32 bit của STM. Với sự giúp đỡ của jsiei97 Bắt đầu với STM32F103RB (Tôi cũng có một TI Stellaris LM3S828, nhưng đó là một vấn đề khác), mà không cần một IDE được cấp phép. Vì tôi là một sinh viên, và hầu hết sinh viên không thể đủ khả năng như vậy.

Tôi hiểu rằng có ODev và Eclipse Plugins và không đọc nhiều blog, wiki, tài liệu/trang người đàn ông và hầu hết các dự án cung cấp cho bạn tập lệnh liên kết ít giải thích tại sao và ở đâu đã được xác định.

Tôi đã biên soạn một chuỗi công cụ arm-no-eabi cho STM32 nhưng tôi bị treo lên trong kịch bản trình liên kết. CodeSourcery cũng yêu cầu một cái. Tôi có một khái niệm cơ bản về cách tạo ra chúng và cú pháp của chúng sau khi đọc các trang của người đàn ông gnu, nhưng tôi chỉ đơn giản là không có đầu mối bắt đầu bằng việc đưa vào các phần bổ sung khác ngoài các phần .text, .bss và .data rõ ràng .

Tôi đã tạo một rudimentary version nhưng tôi nhận được các lỗi liên kết yêu cầu định nghĩa phần và đó là nơi tôi gặp khó khăn. Tôi biết làm thế nào để xác định chúng, nhưng biết nếu những gì tôi đang làm là ngay cả gần bên phải là vấn đề.

+0

tập lệnh liên kết gnu khá đau đớn ở mức tốt nhất. Và từ gcc 3.x đến 4.x những thứ được sử dụng để làm việc didnt làm việc nữa vì vậy, tôi giả sử nó sẽ tiếp tục mà không có vấn đề làm thế nào tốt bạn nhận được ở đó họ sẽ yank các tấm thảm ra từ dưới chân của bạn một ngày nào đó. –

+0

Điều này đúng. Tôi chỉ có thể mong đợi điều đó. Tuy nhiên, từ 4.x đến 5.x tôi có thể nhận được một số công việc vững chắc trong, và nó sẽ là một vấn đề sau khi đăng nhập thay đổi. nên bất cứ điều gì thay đổi lớn. – Crewe

Trả lời

2

Dưới đây là một kịch bản mối liên kết làm việc cho một STM32F105RB (cũng có phiên bản dành cho R8 và RC):

https://github.com/anrope/stm-arp/blob/github/arp.rb.ld (văn bản dưới đây)

My top-of-the-head đoán là bạn sẽ không phải thay đổi bất cứ điều gì. Có thể là nguồn gốc của các vùng được xác định trong câu lệnh MEMORY {}. Hy vọng rằng các ý kiến ​​sẽ hữu ích cho bạn.

Tôi đã sử dụng tính năng này với trình biên dịch chéo GNU/GCC mà tôi đã tự cuộn. Sau khi biên dịch, sẽ hữu ích khi chạy nm trên mã của bạn để đảm bảo rằng các phần được đặt ở đúng địa chỉ.

Edit: Tôi chắp kịch bản mối liên kết này với nhau bằng cách sử dụng các tài liệu ld GNU:

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

và bằng cách kiểm tra sản phẩm của một GCC cross-biên dịch với kịch bản mối liên kết tiêu chuẩn, sử dụng nm. Tôi về cơ bản xác định tất cả các phần đã được sản lượng và tìm ra những người đã thực sự hữu ích, và nơi trong bộ nhớ họ nên đi cho STM32F105.

Tôi đã ghi chú trong tập lệnh liên kết với mục đích của từng phần.

/* 
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

Tôi đã được thông báo rằng chúng tôi không thể cung cấp liên kết trong câu trả lời vì những câu trả lời đó có thể thay đổi nhưng mang lại thông tin cho câu trả lời mà chúng tôi đang nói đến. Tôi đã thêm tệp bạn đã chỉ định cho câu trả lời của mình. –

+1

Bạn lấy thông tin bạn cần để tạo tập lệnh này ở đâu? Làm thế nào bạn biết bạn cần ** _ sheap **, ** _ sidata ** và ** _ sstack ** và những gì để gán cho họ. Đó là loại thông tin tôi đang tìm kiếm. – Crewe

+1

Tôi đã chỉnh sửa câu trả lời của mình. Mỗi phần trong số đó (và nhiều phần khác) xuất hiện trong một bản dịch bằng cách sử dụng một kịch bản liên kết tiêu chuẩn. Kiểm tra các ý kiến ​​trong kịch bản. _sheap là khởi đầu của heap, _sstack là khởi đầu của ngăn xếp. – anrope

8

Tôi có một tập lệnh liên kết đơn giản mà tôi thường xuyên sử dụng lại trên các nền tảng, chỉ cần thay đổi một số địa chỉ nếu cần.

http://github.com/dwelch67/

Có một số lượng mẫu nhiều với mẫu gcc và hầu hết những người có kịch bản mối liên kết.

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

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

+1 để giữ cho nó đơn giản. Tuyệt đối bất cứ ai cũng có thể đọc điều này và hiểu nó. Vì vậy, nhiều người cố gắng trực tiếp đặt các thanh ghi ánh xạ bộ nhớ, v.v ... vào trong kịch bản trình liên kết, và khá sớm nó được đưa vào cuộc sống của riêng nó. Chưa kể đến việc không thể di chuyển được. – Dan

+1

Điều này có thiếu sót ít nhất là phần dữ liệu không? (Các globals được khởi tạo của bạn sẽ đi đâu?) – dbrank0

Các vấn đề liên quan