element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Avnet Boards Forums
  • Products
  • Dev Tools
  • Avnet & Tria Boards Community
  • Avnet Boards Forums
  • More
  • Cancel
Avnet Boards Forums
ZedBoard Hardware Design program code in external memory
  • Forum
  • Documents
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Avnet Boards Forums to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Not Answered
  • Replies 2 replies
  • Subscribers 341 subscribers
  • Views 314 views
  • Users 0 members are here
Related

program code in external memory

Former Member
Former Member over 13 years ago

Hi All

Has anyone tried to load the elf file in a location other than BRAM. If yes , can u please share how did you go about it? From what I could gather, the base address needs to be replaced with the external memory's base address, post which the same changes need to be made in the linker script file.However, it would help me if someone could elaborate on these steps.An example design would really help me.

akanksha

  • Sign in to reply
  • Cancel
  • Former Member
    0 Former Member over 13 years ago

    You can't really do that directly. In order to do use the DDR3 memory, the memory controller needs to be initialized. You need to have some code to do that. Where that code lives depends on how you set the boot pins.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • zedhed
    0 zedhed over 13 years ago

    Hi akanksha112,

    Are you referring to where the First Stage Boot Loader gets loaded upon power up?  If so, I believe that Galfonz is correct.

    At power up, the BootROM is just intelligent enough to search out for a boot image header on the supported boot memory devices (NAND Flash, NOR Flash, QSPI Flash, SD card...) according to the boot mode pins.

    The BootROM has no way of knowing what type of external RAM memory is connected to the system so it cannot accurately configure the DDR controller to bring a stable memory interface up in order to load applications into.  The On Chip Memory (OCM) space is available to the BootROM so that is why you see the linker script for the FSBL application loading code sections to this space.

    MEMORY
    {
       SEGMENT_ONE : ORIGIN = 0x00000000, LENGTH = 0x00030000
    /*  SEGMENT_TWO : ORIGIN = 0x00020000, LENGTH = 0x00010000 */
       SEGMENT_TWO : ORIGIN = 0xFFFF0000, LENGTH = 0x000FE00
    }

    SECTIONS
    {
    .boot 0x00000000: {
       *(.vectors)
       *(.boot)
    } > SEGMENT_ONE

    .text : {
       *(.text)
       *(.gnu.linkonce.t.*)
    } > SEGMENT_ONE

    .jtag 0x00007E40 : {
            *(.jtag)
    } > SEGMENT_ONE

    .handoff 0x0000FF40 : {
            *(.handoff)
    } > SEGMENT_ONE


    .mmu_tbl 0x0010000: {
            *(.mmu_tbl)
    }> SEGMENT_ONE

    .init : {
       KEEP (*(.init))
    } > SEGMENT_ONE

    .fini : {
       KEEP (*(.fini))
    } > SEGMENT_ONE

    .glue_7 : {
       KEEP (*(.glue_7))
    } > SEGMENT_ONE

    .glue_7t : {
       KEEP (*(.glue_7t))
    } > SEGMENT_ONE

    .rodata : {
       __rodata_start = .;
       *(.rodata)
       *(.rodata.*)
       *(.gnu.linkonce.r.*)
       __rodata_end = .;
    } > SEGMENT_ONE

    .rodata1 : {
       __rodata1_start = .;
       *(.rodata1)
       *(.rodata1.*)
       __rodata1_end = .;
    } > SEGMENT_ONE

    .eh_frame : {
       *(.eh_frame)
    } > SEGMENT_ONE

    .ARM.extab : {
       KEEP (*(.ARM.extab))
    } > SEGMENT_ONE

    .ARM.exidx : {
       __exidx_start = .;
       *(.ARM.exidx* .gnu.linkonce.armexidx.*)
       __exidx_end = .;
    } > SEGMENT_ONE

    .got : {
       *(.got)
    } > SEGMENT_ONE

    .got1 : {
       *(.got1)
    } > SEGMENT_ONE

    .got2 : {
       *(.got2)
    } > SEGMENT_ONE

    .ctors : {
       __CTOR_LIST__ = .;
       ___CTORS_LIST___ = .;
       KEEP (*crtbegin.o(.ctors))
       KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
       KEEP (*(SORT(.ctors.*)))
       KEEP (*(.ctors))
       __CTOR_END__ = .;
       ___CTORS_END___ = .;
    } > SEGMENT_ONE


    .dtors : {
       __DTOR_LIST__ = .;
       ___DTORS_LIST___ = .;
       KEEP (*crtbegin.o(.dtors))
       KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
       KEEP (*(SORT(.dtors.*)))
       KEEP (*(.dtors))
       __DTOR_END__ = .;
       ___DTORS_END___ = .;
    } > SEGMENT_ONE

    .fixup : {
       __fixup_start = .;
       *(.fixup)
       __fixup_end = .;
    } > SEGMENT_ONE

    .jcr : {
       *(.jcr)
    } > SEGMENT_ONE

    .gcc_except_table : {
       *(.gcc_except_table)
    } > SEGMENT_ONE


    .init_array : {
    __init_array_start = . ;
       KEEP (*(.init_array))
    __init_array_end = . ;
    } > SEGMENT_ONE

    .comment : {
       KEEP (*(.comment))
    } > SEGMENT_ONE

    .plt : {
       KEEP (*(.plt))
    } > SEGMENT_ONE

    .interp : {
       KEEP (*(.interp))
    } > SEGMENT_ONE

    .note.ABI-tag : {
       KEEP (*(.note.ABI-tag))
    } > SEGMENT_ONE

    .interp : {
       KEEP (*(.interp))
    } > SEGMENT_ONE

    .note.ABI-tag : {
       KEEP (*(.note.ABI-tag))
    } > SEGMENT_ONE

    .hash : {
       KEEP (*(.hash))
    } > SEGMENT_ONE

    .dynsym : {
       KEEP (*(.dynsym))
    } > SEGMENT_ONE

    .dynstr : {
       KEEP (*(.dynstr))
    } > SEGMENT_ONE

    .gnu.version : {
       KEEP (*(.version))
    } > SEGMENT_ONE

    .gnu.version_r : {
       KEEP (*(.gnu.version_r))
    } > SEGMENT_ONE

    .gnu.version_d : {
       KEEP (*(.gnu.version_d))
    } > SEGMENT_ONE

    .rel.dyn : {
       KEEP (*(.rel.dyn))
    } > SEGMENT_ONE

    .rel.plt : {
       KEEP (*(.rel.plt))
    } > SEGMENT_ONE

    .got.plt : {
       KEEP (*(.got.plt))
    } > SEGMENT_ONE

    .init : {
       KEEP (*(.note.ABI-tag))
    } > SEGMENT_ONE

    .fini_array : {
       KEEP (*(.fini_array))
    } > SEGMENT_ONE

    .ARM.attributes :{
       KEEP (*(.ARM.attributes))
    } > SEGMENT_ONE

    .dynbss : {
       KEEP (*(.dynbss))
    } > SEGMENT_ONE

    .dynamic : {
       KEEP (*(.dynamic))
    } > SEGMENT_ONE

    .sdata2 : {
       __sdata2_start = .;
       *(.sdata2)
       *(.sdata2.*)
       *(.gnu.linkonce.s2.*)
       __sdata2_end = .;
    } > SEGMENT_ONE

    .data : {
       __data_start = .;
       *(.data)
       *(.data.*)
       *(.gnu.linkonce.d.*)
       __data_end = .;
    } > SEGMENT_ONE

    .data1 : {
       __data1_start = .;
       *(.data1)
       *(.data1.*)
       __data1_end = .;
    } > SEGMENT_ONE


    .sdata : {
       __sdata_start = .;
       *(.sdata)
       *(.sdata.*)
       *(.gnu.linkonce.s.*)
       __sdata_end = .;
    } > SEGMENT_ONE

    .tdata : {
       __tdata_start = .;
       *(.tdata)
       *(.tdata.*)
       *(.gnu.linkonce.td.*)
       __tdata_end = .;
    } > SEGMENT_ONE


    .sbss2 : {
       __sbss2_start = .;
       *(.sbss2)
       *(.sbss2.*)
       *(.gnu.linkonce.sb2.*)
       __sbss2_end = .;
    } > SEGMENT_ONE

    .sbss : {
       __sbss_start = .;
       *(.sbss)
       *(.sbss.*)
       *(.gnu.linkonce.sb.*)
       *(.scommon)
       __sbss_end = .;
    } > SEGMENT_ONE

    .tbss : {
       __tbss_start = .;
       *(.tbss)
       *(.tbss.*)
       *(.gnu.linkonce.tb.*)
       __tbss_end = .;
    } > SEGMENT_ONE

    .bss : {
    __bss_start__ = .;
    __bss_start = .;
       *(.bss)
       *(.bss.*)
       *(.gnu.linkonce.b.*)
       *(COMMON)
       . = ALIGN(4);
    __bss_end = .;
    __bss_end__ = .;
    } > SEGMENT_ONE

    /* Generate Stack and Heap Sections */
    .heap : {
       . = ALIGN(16);
       _heap_start = .;
      HeapBase = .;
       . += _HEAP_SIZE;
       . = ALIGN(16);
      HeapLimit = .;
       _heap_end = .;
       _end = .;
       _end = .;
    __end__ = . ;
    _end = .;
    PROVIDE (end = .);
    } > SEGMENT_ONE


    .stack : {
       _stack_end = .;
       . += _STACK_SIZE;
       . = ALIGN(16);
       __stack = .;
    } > SEGMENT_TWO

    Once the First Stage Boot Loader begins executing out of OCM, it can begin configuring the platform specdific hardware settings (including DDR controller) so that applications can be loaded and executed from external memory.

    You could, in theory, change the memory mappings for FSBL within the linker script to point into the DDR space and rebuild.  However, since the DDR controller is not up and running at the time BootROM loads FSBL, BootROM may either lock up or execution transferred to a memory space that is not yet active.  In either case, the results would not be desirable.

    If you are not talking about the FSBL and you are simply looking at changing the execution location of your application executable, this can be done within the application linker script before building the application.

    Here is an example linker script from my Hello World application and you can see that the code sections are assigned to DDR memory space:

    SECTIONS
    {
    .text : {
       *(.vectors)
       *(.boot)
       *(.text)
       *(.text.*)
       *(.gnu.linkonce.t.*)
       *(.plt)
       *(.gnu_warning)
       *(.gcc_execpt_table)
       *(.glue_7)
       *(.glue_7t)
       *(.vfp11_veneer)
       *(.ARM.extab)
       *(.gnu.linkonce.armextab.*)
    } > ps7_ddr_0_S_AXI_BASEADDR

    .init : {
       KEEP (*(.init))
    } > ps7_ddr_0_S_AXI_BASEADDR

    .fini : {
       KEEP (*(.fini))
    } > ps7_ddr_0_S_AXI_BASEADDR

    .rodata : {
       __rodata_start = .;
       *(.rodata)
       *(.rodata.*)
       *(.gnu.linkonce.r.*)
       __rodata_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .rodata1 : {
       __rodata1_start = .;
       *(.rodata1)
       *(.rodata1.*)
       __rodata1_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .sdata2 : {
       __sdata2_start = .;
       *(.sdata2)
       *(.sdata2.*)
       *(.gnu.linkonce.s2.*)
       __sdata2_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .sbss2 : {
       __sbss2_start = .;
       *(.sbss2)
       *(.sbss2.*)
       *(.gnu.linkonce.sb2.*)
       __sbss2_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .data : {
       __data_start = .;
       *(.data)
       *(.data.*)
       *(.gnu.linkonce.d.*)
       *(.jcr)
       *(.got)
       *(.got.plt)
       __data_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .data1 : {
       __data1_start = .;
       *(.data1)
       *(.data1.*)
       __data1_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .got : {
       *(.got)
    } > ps7_ddr_0_S_AXI_BASEADDR

    .ctors : {
       __CTOR_LIST__ = .;
       ___CTORS_LIST___ = .;
       KEEP (*crtbegin.o(.ctors))
       KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
       KEEP (*(SORT(.ctors.*)))
       KEEP (*(.ctors))
       __CTOR_END__ = .;
       ___CTORS_END___ = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .dtors : {
       __DTOR_LIST__ = .;
       ___DTORS_LIST___ = .;
       KEEP (*crtbegin.o(.dtors))
       KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
       KEEP (*(SORT(.dtors.*)))
       KEEP (*(.dtors))
       __DTOR_END__ = .;
       ___DTORS_END___ = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .fixup : {
       __fixup_start = .;
       *(.fixup)
       __fixup_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .eh_frame : {
       *(.eh_frame)
    } > ps7_ddr_0_S_AXI_BASEADDR

    .eh_framehdr : {
       __eh_framehdr_start = .;
       *(.eh_framehdr)
       __eh_framehdr_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .gcc_except_table : {
       *(.gcc_except_table)
    } > ps7_ddr_0_S_AXI_BASEADDR

    .sdata : {
       __sdata_start = .;
       *(.sdata)
       *(.sdata.*)
       *(.gnu.linkonce.s.*)
       __sdata_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .sbss (NOLOAD) : {
       __sbss_start = .;
       *(.sbss)
       *(.sbss.*)
       *(.gnu.linkonce.sb.*)
       __sbss_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .tdata : {
       __tdata_start = .;
       *(.tdata)
       *(.tdata.*)
       *(.gnu.linkonce.td.*)
       __tdata_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .tbss : {
       __tbss_start = .;
       *(.tbss)
       *(.tbss.*)
       *(.gnu.linkonce.tb.*)
       __tbss_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .bss (NOLOAD) : {
       __bss_start = .;
       *(.bss)
       *(.bss.*)
       *(.gnu.linkonce.b.*)
       *(COMMON)
       __bss_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .mmu_tbl : {
       . = ALIGN(32768);
       __mmu_tbl_start = .;
       *(.mmu_tbl)
       __mmu_tbl_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .ARM.exidx : {
       __exidx_start = .;
       *(.ARM.exidx*)
       *(.gnu.linkonce.armexidix.*.*)
       __exidx_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .preinit_array : {
       __preinit_array_start = .;
       KEEP (*(SORT(.preinit_array.*)))
       KEEP (*(.preinit_array))
       __preinit_array_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .init_array : {
       __init_array_start = .;
       KEEP (*(SORT(.init_array.*)))
       KEEP (*(.init_array))
       __init_array_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .fini_array : {
       __fini_array_start = .;
       KEEP (*(SORT(.fini_array.*)))
       KEEP (*(.fini_array))
       __fini_array_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .ARM.attributes : {
       __ARM.attributes_start = .;
       *(.ARM.attributes)
       __ARM.attributes_end = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    _SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );

    _SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );

    /* Generate Stack and Heap definitions */

    .heap (NOLOAD) : {
       . = ALIGN(16);
       _heap = .;
       HeapBase = .;
       _heap_start = .;
       . += _HEAP_SIZE;
       _heap_end = .;
       HeapLimit = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    .stack (NOLOAD) : {
       . = ALIGN(16);
       _stack_end = .;
       . += _STACK_SIZE;
       _stack = .;
       __stack = _stack;
       . = ALIGN(16);
       _irq_stack_end = .;
       . += _STACK_SIZE;
       __irq_stack = .;
       _supervisor_stack_end = .;
       . += _SUPERVISOR_STACK_SIZE;
       . = ALIGN(16);
       __supervisor_stack = .;
       _abort_stack_end = .;
       . += _ABORT_STACK_SIZE;
       . = ALIGN(16);
       __abort_stack = .;
    } > ps7_ddr_0_S_AXI_BASEADDR

    Regards,

    -Kevin

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2026 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube