This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Guidance on ROMRAM ldi


On Tue, 23 Nov 2010, Michael Bergandi wrote:

Sergei,

I am trying to learn more about the linker file used in a ROMRAM
configuration. I have looked at several other ROMRAM ldi files for the
ARM, but I can't seem to find much agreement as to the proper way to
set up the SECTIONS section.

Our board has 2MB ROM and 32MB RAM and uses an iMX27 (ARM9) processor.
The current ldi file is adapted from a Freescale Redboot port to the
iMX27 LiteKit and looks like this:

MEMORY
{
 ram : ORIGIN = 0, LENGTH = 0x02000000
 rom : ORIGIN = 0xA1E00000, LENGTH = 0x00200000
}

SECTIONS
{
 SECTIONS_BEGIN
 SECTION_rom_vectors (rom, 0xA1E00000, LMA_EQ_VMA)
 SECTION_text (rom, ALIGN (0x4), LMA_EQ_VMA)
 SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
 SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
 SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
 SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
 SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
 SECTION_fixed_vectors (ram, 0x20, LMA_EQ_VMA)
 SECTION_sram (ram, 0x8000, FOLLOWING (.gcc_except_table))
 SECTION_data (ram, ALIGN (0x4), LMA_EQ_VMA)
 SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
 CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
 SECTIONS_END
}

It looks like ROM LDI.


If I understand correctly, the lengths provided from rom and ram in
the MEMORY section should be the actual size without concession for a
copy of ROM that would consume a portion of the RAM.

The rom ORIGIN is an offset into the RAM (which is mapped to both
0x00000000 and 0xA0000000). We want our app to be loaded to the end of
the RAM.

The MEMORY block contains lines describing the address (ORIGIN) and the size (LENGTH) of each memory region.[1]

----
[1]
http://ecos.sourceware.org/docs-latest/user-guide/modifying-the-memory-layout.html

Yes, I got that part and I read the documentation above before posting. What is not discussed is how to properly setup your ldi for running your app from the 'top' of the ram rather than at the start/bottom.


In some of the other ROMRAM ldi files I looked at, the SECTION
declarations use only 'ram' and not 'rom'. I'm thinking this may not
matter depending on the order and SECTION declaration options
(assuming you are only working with a single chunk off RAM). Is this
thinking correct?

In contrast, the most the linker script includes uses only ram! For the linker's view a ROMRAM startup should be like RAM startup.

Âgrep -I -r -l --include *romram.ldi rom, $ECOS_REPOSITORY | wc -l
Â5

Âgrep -v -I -r -l --include *romram.ldi rom, $ECOS_REPOSITORY | wc -l
Â33

It was a discovery for me what there are 5 such files in the trunk. But,
those are auto-generated .ldi files with Memory Layout Tool in old good
years. Use patterns from those 33 romram.ldi. Necessarily look on the
target's startup code to get it. There is a piece of code in asm which
does relocation.

Those 5 files you discovered are attempting to do exactly what we are trying to do, which is to load the app to the top of ram instead of the bottom. The following ldi is one of those 5.

$ cat packages/hal/frv/mb93093/current/include/pkgconf/mlt_frv_mb93093_romram.ldi
// eCos memory layout - Fri Oct 20 05:56:24 2000

// This is a generated file - do not edit

#include <cyg/infra/cyg_type.inc>

// Leave room for PCI window at 0x03F00000

MEMORY
{
   ram : ORIGIN = 0x0000, LENGTH = 0x03E00000
   rom : ORIGIN = 0x03E00000, LENGTH = 0x00100000
}

SECTIONS
{
   SECTIONS_BEGIN
   SECTION_rom_vectors (rom, 0x03E00000, LMA_EQ_VMA)
   SECTION_text (rom, ALIGN (0x4), LMA_EQ_VMA)
   SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
   SECTION_rodata (rom, ALIGN (0x4), LMA_EQ_VMA)
   SECTION_rodata1 (rom, ALIGN (0x4), LMA_EQ_VMA)
   SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
   SECTION_gcc_except_table (rom, ALIGN (0x4), LMA_EQ_VMA)
   SECTION_fixed_vectors (ram, 0x1000, LMA_EQ_VMA)
   SECTION_data (ram, 0x2000, FOLLOWING (.gcc_except_table))
   SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
   CYG_LABEL_DEFN(__heap1) = ALIGN (0x1000);
   SECTIONS_END
}

The rom memory region's origin is in the ram address space, as I would
expect for a romram link. However, note that the length of the ram
region was decreased by the length of the rom region. Here is another
of those 5 that does not compensate the ram length for the rom region:

$ cat packages/hal/powerpc/vads/current/include/pkgconf/mlt_powerpc_vads_romram.ldi
// eCos memory layout - Fri Oct 20 10:36:41 2000

// This is a generated file - do not edit

#include <cyg/infra/cyg_type.inc>

MEMORY
{
   ram : ORIGIN = 0x00000000, LENGTH = 0x01000000
   rom : ORIGIN = 0x00f00000, LENGTH = 0x00100000
}

SECTIONS
{
   SECTIONS_BEGIN
   SECTION_vectors (rom, 0x00f00000, LMA_EQ_VMA)
   SECTION_text (rom, ALIGN (0x4), LMA_EQ_VMA)
   SECTION_RELOCS (rom, ALIGN (0x4), LMA_EQ_VMA)
   SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA)
   SECTION_rodata1 (rom, ALIGN (0x8), LMA_EQ_VMA)
   SECTION_rodata (rom, ALIGN (0x8), LMA_EQ_VMA)
   SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA)
   SECTION_gcc_except_table (rom, ALIGN (0x1), LMA_EQ_VMA)
   SECTION_eh_frame (rom, ALIGN (0x4), LMA_EQ_VMA)
   CYG_LABEL_DEFN(__reserved_vectors)       = 0;           . =
CYG_LABEL_DEFN(__reserved_vectors)       + 0x3000;
   CYG_LABEL_DEFN(__reserved_vsr_table)     = ALIGN (0x1); . =
CYG_LABEL_DEFN(__reserved_vsr_table)     + 0x200;
   CYG_LABEL_DEFN(__reserved_virtual_table) = ALIGN (0x1); . =
CYG_LABEL_DEFN(__reserved_virtual_table) + 0x100;
   CYG_LABEL_DEFN(__reserved_for_flash)     = ALIGN (0x1); . =
CYG_LABEL_DEFN(__reserved_for_flash)     + 0xcd00;
   SECTION_data (ram, ALIGN (0x10), FOLLOWING (.eh_frame))
   SECTION_sbss (ram, ALIGN (0x4), LMA_EQ_VMA)
   SECTION_bss (ram, ALIGN (0x10), LMA_EQ_VMA)
   CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
   SECTIONS_END
}

I am sorry, to get an expert conclusion about the above snippets it's needed: 1) good knowledges of specific architecture; 2) look on a few things together: arch. ld script; arch. startup; HAL CDL; HAL startup; HAL MLT (.ldi + .h); sometimes you must take a look on RedBoot's ECM, i.e. "grep" around 'ROMRAM'.

Assuming that both of the above ldi's actually work,  which is the
proper thing to do? To be clear, if you have 32MB of ram and 2MB of
rom, should your ram length be specified as 30MB, instead of 32MB?

So, your PROGBITS can occupy maximum 2M of the ROM. Then, if you do plan to use RedBoot[ROMRAM] bootstrap environment (no matter on top or bottom of RAM) such ldi scripts have to be like those 33 to provide an ability for ROMRAM RedBoot to upgrade (rewrite) itself: to be by Baron MÃnchhausen (escaping from a swamp by pulling himself up by his own hair). If such a behavior is extra thing for you and you want to use fast RAM instead slow FLASH you would leave some PROGBITS in a place and some put (move to) into RAM (for me that is too smart thing).

I also looked at all of the ARM based ROMRAM ldi's and found that the
excalibur appears to be the only one loading the app to the top of
ram, but is doing it in quite a different manner:

Now, 'top' (subtraction of 2M) vs 'bottom' (no subtraction). In case of 'top' builds, that is additional protection for relocated PROGBITS. Your heap grows and sbrk() even won't be know that you have 32M of RAM. In "bottom-centric" builds sbrk() sees whole RAM. I see no implication here, may be I miss something.

$ cat packages/hal/arm/arm9/excalibur/current/include/pkgconf/mlt_arm_arm9_excalibur_romram.ldi
// eCos memory layout - Tue Aug 14 12:49:58 2001

// This is a generated file - do not edit

#include <cyg/infra/cyg_type.inc>

MEMORY
{
   ram : ORIGIN = 0, LENGTH = 0x8000000
   rom : ORIGIN = 0x40000000, LENGTH = 0x100000
}

SECTIONS
{
   SECTIONS_BEGIN
   SECTION_fixed_vectors (ram, 0x20, LMA_EQ_VMA)
   SECTION_rom_vectors (ram, 0x8000, AT (0x40000000))
   SECTION_text (ram, ALIGN (0x4), FOLLOWING (.rom_vectors))
   SECTION_fini (ram, ALIGN (0x4), FOLLOWING (.text))
   SECTION_rodata (ram, ALIGN (0x4), FOLLOWING (.fini))
   SECTION_rodata1 (ram, ALIGN (0x4), FOLLOWING (.rodata))
   SECTION_fixup (ram, ALIGN (0x4), FOLLOWING (.rodata1))
   SECTION_gcc_except_table (ram, ALIGN (0x4), FOLLOWING (.fixup))
   SECTION_data (ram, ALIGN (0x1), FOLLOWING (.gcc_except_table))
   SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
   CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
   SECTIONS_END
}

Note here, the use of AT in the rom_vectors section and everything is
FOLLOWING. Is this the new/preferred way?

Let's look on FOLLOWING macro in arm.ld. The above ldi script *force* two things: and section alingment and section order "manually", i.e. be alignment, follow that. I never see the famous MLT tool from RedHat, but my guess is: a user could just define sections in that user-friendly GUI (one by one) and could check: be aligned and could specify: follow this section. And voila, he/she got .mlt, .ldi, .h files! I never see the MLT screenshots (that is from my mind). My guess that "lazy" users got LMA_EQ_VMA-centric ldi scrits and experienced users made smart scripts. But that my guess only :-) Let's eCos veterans say what MLT was.

I think you've got not very much information from me, but still...

Sergei

For references how it works look on hal_platform_setup.h or for non-ARM
targets on its target.S sources.

Yep, I am familiar with hal_platform_setup.h. I have done some stepping through that with gdb to get a better understanding.

I have also seen some discussion in the archives suggesting that using
LMA_EQ_VMA is not the right thing to use. Is there Âa final word on
this? Should I use only FOLLOWING, as I have seen elsewhere?

In 99% cases for embedded world it is used LMA_EQ_VMA. ÂIf you know LMA_EQ_VMA, SECTION_xxx are macros are defined in platform .ld file, for example, for ARM:

Â$ECOS_REPOSITORY/hal/arm/arch/*/src/arm.ld


Good to know, thanks.



-- Michael Bergandi

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]