IAR linker copy code from FLASH to RAM during initialization - c

I want to run code in RAM and use initialize copy by directives.
My .icf file is as follows:
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x080007ff;
define symbol __ICFEDIT_region_ROM1_start__ = 0x08070000;
define symbol __ICFEDIT_region_ROM1_end__ = 0x0807FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
define symbol __ICFEDIT_size_cstack__ = 0x600;
define symbol __ICFEDIT_size_heap__ = 0x00;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x600;
define symbol __ICFEDIT_size_heap__ = 0x00;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region ROM1_region = mem:[from __ICFEDIT_region_ROM1_start__ to __ICFEDIT_region_ROM1_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
do not initialize { section .noinit };
initialize by copy {readwrite};
initialize by copy {
object gd32f403_it.o,
object gd32f403_exti.o,
object gd32f403_fmc.o,
object gd32f403_gpio.o,
object gd32f403_misc.o,
object gd32f403_pmu.o,
object gd32f403_rcu.o,
object gd32f403_timer.o,
object gd32f403_usart.o,
object usb_delay.o,
object iap_core.o,
object usb_core.o,
object usbd_core.o,
object usbd_int.o,
object usbd_std.o,
object app.o ,
};
place in ROM_region {
readonly object system_gd32f403.o,
};
place in ROM1_region {
readonly object app.o ,
readonly object usb_delay.o,
readonly object iap_core.o,
readonly object gd32f403_it.o,
readonly object gd32f403_exti.o,
readonly object gd32f403_fmc.o,
readonly object gd32f403_gpio.o,
readonly object gd32f403_misc.o,
readonly object gd32f403_pmu.o,
readonly object gd32f403_rcu.o,
readonly object gd32f403_timer.o,
readonly object gd32f403_usart.o,
readonly object usb_core.o,
readonly object usbd_core.o,
readonly object usbd_int.o,
readonly object usbd_std.o,
readonly,
};
place in RAM_region {
readwrite,
block CSTACK, block HEAP,
};
export symbol __ICFEDIT_region_RAM_start__;
export symbol __ICFEDIT_region_RAM_end__;
But only gd32f403_gpio.o and gd32f403_misc.o execute in RAM and other objects still run in FLASH as shown in output .map files:
"P3", part 1 of 3: 0x54c
P3-1 0x20000000 0x54c <Init block>
...
.rodata inited 0x20000000 0x40 app.o [1]
.rodata inited 0x20000040 0x44 app.o [1]
.rodata inited 0x20000130 0x8 gd32f403_rcu.o [1]
.rodata inited 0x20000138 0x14 iap_core.o [1]
.rodata inited 0x2000014c 0x4 iap_core.o [1]
.text inited 0x20000150 0xc6 gd32f403_gpio.o [1]
.text inited 0x20000218 0xd0 gd32f403_misc.o [1]
.data inited 0x200002e8 0x120 app.o [1]
.data inited 0x20000408 0x30 iap_core.o [1]
.data inited 0x20000504 0x48 xfiles.o [3]
...
- 0x2000054c 0x54c
Why other objects such as app.o, gd32f403_usart.o have not been copied into RAM to execute?
Please!
What should I do if I want achieve the goal that copy code to RAM described in .icf file?

Sections that are needed for initialization are not affected by the initialize by copy
directive. This includes the __low_level_initfunction and anything it references.
Anything reachable from the programentry label is considered needed for initialization
unless reached via a section fragment with a label starting with __iar_init$$done.

Related

Godot/GdScript How to instantiate a class from a static function?

I have 2 scripts:
A.gd
class_name A
var v = 0
func _init(v_):
v = v_
B.gd
class_name B
var A = preload("res://A.gd")
static func Add(a1:A, a2:A):
return A.new(a1.v + a2.v)
I don't understand why I have this error while I'm typing:
res://B.gd:6 - Parse Error: Can't access member variable ("A") from a static function.
Apparently, I can't instantiate A from a static function. If I remove static, there are no more errors. What am I doing wrong? How can I instantiate A from a static function?
There are no static variables in Godot. Thus that var A is not a static variable. And thus it is not available from a static function.
On the other hand, if you gave a name to your class with class_name - which you did - then that class name exist everywhere. Remove var A.

Why does a const disappear during linking when static doesn't?

I have a function like this in my static library crate:
use super::*;
static BLANK_VEC: [u8; 16] = [0_u8; 16];
pub fn pad(name: &'static str) -> String {
let mut res = String::from(name);
res.push_str(&String::from_utf8_lossy(&BLANK_VEC[name.len()..]));
res
}
When I link this to C code it works as expected, but if I link with the below code (the only difference being const instead of static) the label BLANK_VEC doesn't appear in the ELF file. It could compile and run until it gets a HardFault.
use super::*;
const BLANK_VEC: [u8; 16] = [0_u8; 16];
pub fn pad(name: &'static str) -> String {
let mut res = String::from(name);
res.push_str(&String::from_utf8_lossy(&BLANK_VEC[name.len()..]));
res
}
Is this a bug on the Rust side? I think so because the const variable goes out of scope somehow. I can reference it and it compiles. Where is the ensured memory safety? Why didn't I have to use unsafe block to do that?
If this is something that depends on my linker: I use arm-gcc-none-eabi.
Edit: I understand why this happens but shouldn't Rust ensure that the user uses a variable that won't disappear?
It's not a bug in rust: const defines a constant value copied at every use-site (therefore not existing at runtime).
static defines a global variable (which may or may not be constant), and is thus present in the final program, it's an actual single location in memory.

Linker script confusion - why multiple labels are needed?

Hello I have a "linker script" for GNU linker ld and I have two questions related to it:
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(__start)
SECTIONS
{
. = 0x11029000;
.text :
{
__exidx_start = .;
PROVIDE (__gnu_textstart = .);
startup.o(.text .text.*)
*(.text .text.*)
}
.rodata :
{
*(.rodata .rodata.*);
}
__exidx_end = .;
PROVIDE (__gnu_textend = .);
.data :
{
PROVIDE (__gnu_datastart = .);
*(.data .data.*);
PROVIDE (__gnu_dataend = .);
}
.bss :
{
PROVIDE (__gnu_bssstart = .);
*(.bss .bss.*) *(COMMON);
PROVIDE (__gnu_bssend = .);
}
PROVIDE (end = .);
PROVIDE (__end = .);
__image_size = ((__gnu_bssstart - __gnu_textstart) + 511) & ~ 511;
__EH_FRAME_BEGIN__ = 0;
}
Q1: Why do we define multiple labels like __exidx_start and __gnu_textstart for the same adress? The later is defined using PROVIDE.
Q2: At the end the linker script calculates the image size like this:
__image_size = ((__gnu_bssstart - __gnu_textstart) + 511) & ~ 511;
Would we get the same result if we calculated it like this:
__image_size = ((__exdix_start - __exidx_end) + 511) & ~ 511;
From http://www.sourceware.org/binutils/docs-2.10/ld_3.html#SEC17 it looks like using the PROVIDE command is meant as a declaration ONLY IF used without another declaration. The benefit being that the symbol could be defined by a user should they choose (or if they are just not aware of the symbol). In a sense, the definition in the PROVIDE will act as a default of sorts if it is never defined elsewhere but still referenced.
Given that, I would assume that __gnu_textstart is meant to be an alias of sorts to __exidx_start and therefore that the answer to Q2 is yes, as the symbols reference the same locations.

what initializations i need to do in .lcf(linker file) and other files before generation RAM.bin image file for MPC5604E controller

I am trying to load the RAM.bin image on SRAM of MPC5604E controller through serial boot (using autobaud mode for LINFLEX0). I am using an sample LED toggle program to generate RAM.bin image file and tried to load through serial boot, it is loaded successfully and LED toggle working fine(when watchdog is enabled),but if we disable the watchdog and then load and execute it,LED toggle is not working. So I assume there may be some issue related to initialization in .lcf(linker file) and some other files before generating the RAM.bin file through code warrior for serial booting.
Can anybody help me with these initializations because i don't know what to do ? So that my RAM.bin image file can execute successfully.
MPC5604E.lcf :::
/* lcf file for MPC5604E processors */
/* */
/* 512KB Flash, 96KB SRAM */
MEMORY
{
resetvector: org = 0x00000000, len = 0x00000008
init: org = 0x00000020, len = 0x00000FE0
exception_handlers: org = 0x00001000, len = 0x00001000
internal_flash: org = 0x00002000, len = 0x000FE000
internal_ram: org = 0x40000000, len = 0x00016000
heap : org = 0x40016000, len = 0x00001000
stack : org = 0x40017000, len = 0x00001000
}
/* This will ensure the rchw and reset vector are not stripped by the linker*/
FORCEACTIVE { "bam_rchw" "bam_resetvector" }
SECTIONS
{
.__bam_bootarea LOAD (0x00000000): {} > resetvector
GROUP : {
.init LOAD (0x00000020) : {}
.init_vle (VLECODE) LOAD (_e_init) : {
*(.init)
*(.init_vle)
}
} > init
GROUP : {
.ivor_branch_table (VLECODE) LOAD (0x00001000) : {}
.__exception_handlers (VLECODE) LOAD (_e_ivor_branch_table) : {}
} > exception_handlers
GROUP : {
.text : {}
.text_vle (VLECODE) ALIGN(0x08): {
*(.text)
*(.text_vle)
}
.rodata (CONST) : {
*(.rdata)
*(.rodata)
}
.ctors : {}
.dtors : {}
extab : {}
extabindex : {}
} > internal_flash
GROUP : {
.__uninitialized_intc_handlertable ALIGN(2048) : {}
.data : {}
.sdata : {}
.sbss : {}
.sdata2 : {}
.sbss2 : {}
.bss : {}
} > internal_ram
}
/* Freescale CodeWarrior compiler address designations */
_stack_addr = ADDR(stack)+SIZEOF(stack);
_stack_end = ADDR(stack);
_heap_addr = ADDR(heap);
_heap_end = ADDR(heap)+SIZEOF(heap);
/* Exceptions Handlers Location (used in Exceptions.c IVPR initialization)*/
EXCEPTION_HANDLERS = ADDR(exception_handlers);
/* L2 SRAM Location (used for L2 SRAM initialization) */
L2SRAM_LOCATION = 0x40000000;

Understanding of uboot.lds

I am trying to understand how the porting of uboot is done on powerpc mpc8313 processor based board. During this procedure I came across the file called uboot.lds, linker script file.
I need to understand this file. I mean the significance of the contents mentioned and where the actual addresses are defined in uboot package.
for example; in SECTIONS, where I can find the significance of the following information:
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
.text :
{
cpu/mpc83xx/start.o (.text)
*(.text)
*(.fixup)
*(.got1)
. = ALIGN(16);
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
*(.eh_frame)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
__fixup_entries = (. - _FIXUP_TABLE_) >> 2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = .;
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}
where to look for this information and how to identify the changes to be done in lds file?
Please acknowledge or atleast give some pointers to read the information, thank you
Regads,
Vijay
To port u-boot, the u-boot.lds can probably be used from the cpu directory and not the board directory. In other words, there is probably no need to port this file. However, if there is then here is an overview.
You can find lots of information in the LD documentation.
In general, what LD scripts allow you to do is to override the default places that the GCC tool chain places things in memory when run. When you compile an application, the source code is processed and object code files containing machine code are created. During linking the various object files are combined into one file, ELF executable for example, and a header is placed on the file to tell the OS where each object file should be placed in memory so that it can be found when needed (globals, function calls, etc.)
A custom script is needed if you want to place the code in a specific place that you cannot expect the complier/linker to guess. There are many reasons to do this, as I will try to list.
Constants may be placed in Read-Only memory if RAM is sparse
Memory that is accessed a lot may need to be placed in faster RAM if available
Some data may need to be aligned on a certain boundary, such as 64K
Some code (.TEXT) should be placed at the reset vector so that it is executed at reset
Same for ISR code vectors
Besides this, it can be a way to get convenient access to memory pointers at linkage time. For example, __init_begin is defined as a symbol that has the memory address of any code compiled as *.text.init. You can now call that memory by setting the program counter to the value of __init_begin without having a full C environment configured.
The compiler documentation + u-boot Makefiles should explain how and when the compiler generates object files of each type (ex. .txt, .data, .bss, .fini, .ctors, etc.)

Resources