2014-01-10 08:10 AM
Hello. I am looking at
https://github.com/mabl/ChibiOS/blob/master/os/ports/GCC/ARMCMx/STM32F4xx/ld/STM32F405xG.ld
, one of the GNU linker scripts for the ChibiOS project. I understand this script for the most part but I am very confused by the alignment of the sections. Namely:Thanks for the help!
Sam #stm32f405-linker-scatter-gnu-ld2014-01-10 08:42 AM
The reason to align a section is to permit things within that section to be placed up to that granularity. Multiple objects may feed into a single section.
All data and variables should be placeable at 32-bit boundaries. Data paths and memories are optimized and decoded on that premise. For flash the key thing to understand is the line width of the memory. Flash is slow (figure 35ns whether you read 1 byte or a dozen), if you read a value that spans two lines it will be doubly slow. The flash line width in the F4 is 128-bits, the cache (ART) sitting in front of it is also 128-bit wide. Subroutines and branch targets tend to work better if aligned, the initial hit occurs if there is a cache miss, but the next 7 instructions fetch for free as part of the optimized prefetch path.2014-01-10 08:59 AM
Hi
Yes, very strange. Technically - the linker is part of the Compiler and Linker suite (ie gcc in this case). The OS (ChibiOS) is something that just runs like any other program as far as the compiler/linker is concerned. ''Any particular reason for the 4 byte alignment of input sections in the .data and .bss sections?'' ARM Cortex M series are 32bit - so all asm instructions should be min 4 byte aligned. ''The stack must be double-word aligned.'' which may explain why the stack is aligned as it is by the linker... but what happens if the code before a function call pushes a 32-bit value onto the stack? It seems as though it would no longer be 64-bit aligned.'' As far as Stack alignment goes - my understanding is hat it MUST be even. The stack is not only used for return addresses - it is also used for local variables and passing parameters into/out of functions. So what happens when you create a char as a local vairable?? - The compiler and the processor must make sure there is a dummy byte inserted into the stack. The stack can be any mix of 2byte/4byte/8byte words (as anybody who has had to hand unwind the tack knows). If you are foolish enough to pass bulk data as input parameter - this get pushed onto the stack. Exception here is strings - compiler knows to push a pointer onto stack. The .text output section normally are ALL the executable code. '' I asked in the ChibiOS forum but the response did not make a great deal of sense... I was told that a single read is 128 bits (16 bytes) so these sections are aligned to avoid reading across one of these boundaries.'' Well if that is what the ChibiOS does (reads 16bytes at a time) - then it makes sense to align to 16byte boundaries. ''why are the constructors and destructors aligned to 4 byte boundaries? It seems as though they are executable code, much like the .text section.'' Conceptually, objects are code and data bound together. However, the processor has no way to enforce this concept. It is upto the compiler to do this. Yes, Constructors and Destructors are just functions and hence they must be 4byte aligned. Constructors and Destructors are just functions hence they go in the .text section. .bss sections are one of the sections for variable data. There is one for intialised data (bsscontaining statically-allocated variables
) and one for un-initialised data (zerovars). OK, having just read Clive1's post - some of it make more sense to me now.2014-01-10 02:39 PM
''Any particular reason for the 4 byte alignment of input sections in the .data and .bss sections?''
The data bus is 32-bit wide and such alignment speeds up the access to multibyte variables (no crossing boundaries) ''I am assuming the compiler handles alignment in each input section.'' I do not think so. The compiler has no knowledge about how to place those unless you explicitly use some attribute (though that is passed to the linker anyway). ''but what happens if the code before a function call pushes a 32-bit value onto the stack?'' Architecture Reference Manual: ''When the processor pushes the PSR value to the stack it uses bit[9] of the stacked PSR value to indicate whether it realigned the stack.''2014-01-10 07:09 PM
clive1: Where did you get that fancy graphic? I am confused by the block of 128-bit values. Thumb and Thumb-2 instructions either 16 or 32 bits so do they represent between 4 and 8 instructions? From the Architecture Manual ''While instruction fetches are always halfword-aligned, some load and store instructions support unaligned addresses.'' (so aligning to 16 bytes shouldn't be needed?) If I knew what the 128-bits represented I think I have a much better understanding. It looks like I need to read more about the ART as well.
: What I meant when I said ''I am assuming the compiler handles alignment in each input section.'' is that compiler must pack the data in a way that an input section does not violate the alignment (perhaps this is something the linker does as well?). How is an 8-bit value stored in flash? My guess would be that it would be stored in a 32-bit slot.Also I found this linker script from TrueSTUDIO:https://github.com/jeremyherbert/stm32-templates/blob/master/stm32f4-discovery/stm32_flash.ld
It aligns the .text section to 4 bytes. Is any less valid than the way ChibiOS aligns the instructions?Thanks all for the responses.Edit: Between 4 and 8 instructions, not 2 and 4. Doh!2014-01-11 11:14 AM
''compiler must pack the data in a way''
Ok, lets suppose some object file (let it be main.o) contains one .data section (-f-no-data-sections) filled with various variables. Among them structs, unions, uin8_t, uin64_t etc. Now I understand the question is how the (gcc?) compiler manages that?2014-01-11 01:39 PM
@samuel - It's from one of the STM32F2/4 brochures. I'll dig one up shortly.
Remember this is external to the core, as the core designs don't provide any implementation for caching or TCM. The ART can provide prefetch data at basically zero-cycles, compared to say SRAM where it will still take a cycle to fetch. So from flash while you might have a 5 cycle hit for the first 16-bit word, the next 7 can be feed at 0 cost.2014-01-11 04:11 PM
I've seen coverage in a couple of places, this seems to be one of the better ones from the F4 Seminars. See pg 33
https://drive.google.com/file/d/0B7OY5pub_GfILVJERmZ6TktEQkE/edit?usp=sharing
2014-01-13 02:41 AM
Hi
''Also I found this linker script from TrueSTUDIO:https://github.com/jeremyherbert/stm32-templates/blob/master/stm32f4-discovery/stm32_flash.ld
It aligns the .text section to 4 bytes. Is any less valid than the way ChibiOS aligns the instructions?'' OK Atollic TrueStudio uses gcc as the compiler/linker. Yes, it aligns to 4 byte boundaries (due 32bit ARM architecture) ''Is any less valid than the way ChibiOS aligns the instructions?'' No, both ways are OK but in fact from what Clive1 said about the Flash and cache - it sounds like ChibiOS is trying to be clever and optimise Flash access for the STM architecture. What it is doing is forcing a 128 bit read (hence taking advantage of the Flash width and Cache) every time it reads an instruction, a number of instructions (4) are all read into the cache. Note : this does not guarantee ChibiOS runs faster then other Rtos' but is helps2014-01-13 05:26 PM
Thanks all, it is starting to come together. In the example below, which is an unoptimized function that adds two floats, I highlighted the first 128 bits of the function. Any idea how the ART handles only having half of the instruction stored in the cache? It is hard to tell from the presentation but perhaps it reads ahead and does not wait until a cache miss?
08000010 <add>: 8000010: b480 push {r7} 8000012: b083 sub sp, #12 8000014: af00 add r7, sp, #0 8000016: ed87 0a01 vstr s0, [r7, #4] 800001a: edc7 0a00 vstr s1, [r7] 800001e: ed97 7a01 vldr s14, [r7, #4] 8000022: edd7 7a00 vldr s15, [r7] 8000026: ee77 7a27 vadd.f32 s15, s14, s15 800002a: eeb0 0a67 vmov.f32 s0, s15 800002e: 370c adds r7, #12 8000030: 46bd mov sp, r7 8000032: f85d 7b04 ldr.w r7, [sp], #4 8000036: 4770 bx lrThis example brings up one more question (I can probably find it in the architecture reference manual): How does the core decode the combination of 16 and 32 bit instructions? The I-code bus is 32 bits so the core load 2 16-bit instructions at once? What happens if it tries to load a 16-bit and half of a 32-bit instruction?I will start looking looking through the reference manual.Thanks for the help, the ART makes a lot more sense to me now! This is much more complex than the AVRs and PICs I am used to!