How to force my section in the very end of flash? - linker-scripts

I have my linker script with such memory layout
MEMORY{
ram : ORIGIN = 0x0, LENGTH = 0x1000 /* 4KB of RAM starting at address 0x0 */
flash : ORIGIN = 0x20000000, LENGTH = 0xC000 /* 48KB of flash starting at address 0x20000000 */
}
and I want to add two section in the very end of my flash(let's say .section1 and .section2)
but I don't know the length of my section unless I compile it
In my expectation, my flash layout will look like this:
start address
section
0x20000000
.text
0x20000000+.text size
.data
0x20000000+.text size + .data size
.mdata
0x20000000+.text size + .data size + .mdata
(empty flash)
0x2000C000-.section2 size - section1 size
.section1
0x2000C000-.section2 size
.section2
How should I do in my linker script?
I don't know how to wrote it for now I just force my address like this. but its not what I want.
.section1 :{
*(.section1)
} >flash :AT (0x2000A000)
.section2 :{
*(.section2)
} >flash :AT (0x2000B000)

Related

linker script, what do region attributes do exactly?

In linker scripts I typically see that flash is marked with rx
MEMORY
{
/* Define each memory region */
PROGRAM_FLASH (rx) : ORIGIN = 0x60000000, LENGTH = 0x400000 /* 4M bytes (alias Flash) */
SRAM_DTC (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000 /* 64K bytes (alias RAM) */
SRAM_ITC (rwx) : ORIGIN = 0x0, LENGTH = 0x10000 /* 64K bytes (alias RAM2) */
SRAM_OC (rwx) : ORIGIN = 0x20200000, LENGTH = 0x20000 /* 128K bytes (alias RAM3) */
BOARD_SDRAM (rwx) : ORIGIN = 0x80000000, LENGTH = 0x1e00000 /* 30M bytes (alias RAM4) */
NCACHE_REGION (rwx) : ORIGIN = 0x81e00000, LENGTH = 0x200000 /* 2M bytes (alias RAM5) */
}
But I can still erase and write sections in flash when my app is running. What does this r attribute imply/limit/mean then?

GNU ASM .section directive not working/linker issue

I'm trying to move my _start function to 0x0, as it is the bootloader.
Flash ROM exists from 0x0 to the first 128MB (=1Gb), other memory is DDR3 RAM but we will map RAM to 0x80000000 to 0xFFFFFFFF.
The issue is with the directive .section ".vect", the _start address is not going into the .vect section, it is going into the .text section.
_start:
.section ".vect" /* I've tried .section .vect and I've tried moving above _start */
b ResetHandler
b UndefHandler
b SVC_Handler
b PrefetchAbortHandler
b DataAbortHandler
b NotUsedHandler
b IRQ_Handler
b FIQ_Handler
1:
b 1b /* Hang and don't return */
In my linker script, the MEMORY command and then the start of SECTIONS is:
MEMORY
{
vect (rx) : o = 0x0, l = 1M
rom (rx) : o = 1M, l = 127M
ram (wx) : o = 0x80000000, l = 0x80000000
}
SECTIONS
{
.vect : ALIGN(64)
{
. = 0x0;
*(.vect*)
VectTableEnd = .;
VectTableSize = SIZEOF(.vect);
} > vect
.... (.text, .bss, .data, .stack, etc are other SECTIONS entries)
}
But no matter what, the _start assembly function code gets shoved into the standard .text section, not at address 0x0. Does anyone know what I'm going wrong?
The code is targetted at bare-metal ARMv7A machines, compiled/linked with arm-none-eabi-as/ld
Cheers.
No surprises here if your _start label ends up in .text:
/* implicitly default section .text */
_start:
/* still the same section .text */
.section .vect
/* explicitly the section .vect */
b ResetHandler
You probably want to switch the section before defining the _start label to make that label end up in the intended section.
/* implicitly default section .text */
.section .vect
/* explicitly the section .vect */
_start:
b ResetHandler
Using the name _start as the symbol for a vector table is a bit weird (I would have expected a symbol like __vectors or vector_table), but that is beyond the scope of this question.

1024 X 768 X 32 VGA ,how to fill the whole screen?

I'm developing a hobby OS ,I want to draw something in vga mode when OS is in protected mode. I'm using the multiboot2 to guide my OS to step in and I setup the VGA as 1024 X 768 X 32 ,then I paint the whole screen like this :
memset ((void *) 0xA0000,0x0F,1024 * 768 * 4);
but encounted an exception,I found that VGA buffer address starts at 0xA00000 but ends at 0xB0000 ,totally 64K, the whole 1024 * 768 * 32 screen need rather than the 64K buffer.
So,How to fill the whole screent ? Any help would be appreciated ...

conditional statements for linker command language LD

Are there conditional statements for the GNU LD linker command language?
Context: I am developing firmware for an arm cortex m0+, which consists of a bootloader and an application. Both are compiled and flashed to target in separate projects, but I use a framework with symbolic links to the drivers, makefile and loader scripts so that I can reuse those for every app I make without copying these files for each app.
Currently I have two loader files, for bootloader and application (makefile automatically specifies the appropriate one), with memory assigment as follows:
bootloader
MEMORY {
flash (rx) : ORIGIN = 0x00000000, LENGTH = 16K
ram (rwx) : ORIGIN = 0x1FFFF000, LENGTH = 16K
}
app
MEMORY {
flash (rx) : ORIGIN = 0x00004000, LENGTH = 112K
ram (rwx) : ORIGIN = 0x1FFFF000, LENGTH = 16K
}
Like the makefile, I want to merge these to something like this (using C expressions to clarify)
MEMORY {
#ifdef(bootloaderSymbol)
flash (rx) : ORIGIN = 0x00000000, LENGTH = 16K
#else
flash (rx) : ORIGIN = 0x00004000, LENGTH = 112K
#endif
ram (rwx) : ORIGIN = 0x1FFFF000, LENGTH = 16K
}
Although its not its primary purpose, you can always run the C preprocessor
(cpp) on your linker scripts:
#if defined(MACHINE1)
# define TARGET_ADDRESS 0x80000000
# define SDRAM_START xxx
# define SDRAM_SIZE yyy
# define ROMFLAGS rx
#elif defined(MACHINE2)
# define TARGET_ADDRESS 0x40000000
# define SDRAM_START zzz
# define SDRAM_SIZE aaa
# define ROMFLAGS rwx
#else
# error unknown machine
#endif
MEMORY
{
rom (ROMFLAGS) : ORIGIN = TARGET_ADDRESS, LENGTH = 0x00100000
ram (WX) : ORIGIN = SDRAM_START + SDRAM_SIZE - 0x00200000, LENGTH = 0x00100000
driver_ram (WX) : ORIGIN = SDRAM_START + SDRAM_SIZE - 0x00100000, LENGTH = 0x00100000
}
...
You just need to make sure your macros don't collide with linker script syntax. Then save your linker script as xxx.lk.in (instead of xxx.lk) and add a recipe to your Makefile:
xxx.lk: xxx.lk.in
$(CPP) -P $(INCLUDE) -D$(MACHINE) $< $#
All that's left to do is to add xxx.lk as dependency to your final executables build recipe. I'm using similar processes on many of my projects successfully.
I think you can try "DEFINED(symbol)" according to https://sourceware.org/binutils/docs/ld/Builtin-Functions.html
Also, please don't forget to pass "--defsym=bootloaderSymbol=1" to ld.
MEMORY {
flash (rx) : ORIGIN = DEFINED(bootloaderSymbol) ? 0x00000000 : 0x00004000, LENGTH = DEFINED(bootloaderSymbol) ? 112K : 16K
ram (rwx) : ORIGIN = 0x1FFFF000, LENGTH = 16K
}
I've gone down this same path before, and later found out there's an ld command line argument to specify segment origin, which alleviates the need to figure it out in the linker script. From man page:
-Tbss=org
-Tdata=org
-Ttext=org
Same as --section-start, with ".bss", ".data" or ".text" as the section name.
So in your case, you would have -Ttext=0 (bootloader) or -Ttext=0x00004000 (app)

Cortex-M3 heap-stack organization using keil

Trying to run blinky sample for Atmel sam3s and inspecting the stack pointer...
SP has the value 0x20000238 at the start of main function which is equal too Ram base + RW + ZI for this sample.
The base RAM address for this chip is : 0x20000000
Total ram size is: 0x10000
I expected the sp to be initialized on 0x20010000 and coming down.
Can anyone explain if I am wrong or not?
As Pait said (he/she should have answered the question so I could accept it, I think),
I was wrong to think the stack will be placed at the end of RAM by default. But I think it is wise to make it be placed there.
This is how I do it for my SAM3S micro, by changing the scatter file
LR_IROM1 0x00400000 0x00080000 { ; load region size_region
ER_IROM1 0x00400000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00010000 { ; RW data
.ANY (+RW +ZI)
}
RW_STACK 0x2000C000 UNINIT 0x4000 { ; STACK data
*.o (STACK)
}
}
RAM base = 0x20000000
Total RAM = 64 kb
Intended stack size = 16 kb