Support for adding section
tiberiusferreira opened this issue · 16 comments
Hello,
I'm using the FRDM-KL25Z and it needs a "flash protection" section. I tried modifying the memory.x script as follows:
MEMORY
{
VECTORS (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400
FLASH_PROTECTION (rx) : ORIGIN = 0x00000400, LENGTH = 0x00000010
FLASH (rx) : ORIGIN = 0x00000410, LENGTH = 128K - 0x00000410
RAM (rwx) : ORIGIN = 0x1FFFF0C0, LENGTH = 16K - 0xC0
}
SECTIONS
{
.flash_protect :
{
KEEP(*(.flash_configuration))
. = ALIGN(4);
} > FLASH_PROTECTION
}
With the following data:
#[link_section=".flash_configuration"]
#[used]
static FLASH_CONFIG_FIELD: [u32; 4] = [
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFE,
];
But after compiling and generating the .bin file, the address is not set.
I'm using the following commands to compile and generate the bin
xargo build --target thumbv6m-none-eabi --release -v
arm-none-eabi-objcopy -S -O binary ./target/thumbv6m-none-eabi/release/lab01 lab01.bin
Am I doing something wrong or is setting custom sections not supported?
The elf file works with GDB as expected, but to flash the code I need to use the bin file with the correct flash_config_field bits at 0x400.
Attached are the elf and bin files.
Thanks for the help in advance :)
I just tried to reproduce your example, and I see the region and section correctly added to the binary. But your lab01.elf doesn't have it for some reason.
Hello pftbest, thanks for the help, but I think it's the other way around, right? The ELF (which comes straight out of the compiler) has the section:
tiberiodarferreira$ arm-none-eabi-readelf -h target/thumbv6m-none-eabi/release/lab01
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x810
Start of program headers: 52 (bytes into file)
Start of section headers: 41592 (bytes into file)
Flags: 0x5000200, Version5 EABI, soft-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 2
Size of section headers: 40 (bytes)
Number of section headers: 12
Section header string table index: 11
note47:lab01 tiberiodarferreira$ arm-none-eabi-readelf -S target/thumbv6m-none-eabi/release/lab01
There are 12 section headers, starting at offset 0xa278:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .flash_protect PROGBITS 00000400 003e9c 000000 00 W 0 0 1
[ 2] .vector_table PROGBITS 00000410 000410 000090 00 A 0 0 4
[ 3] .text PROGBITS 00000810 000810 0026f4 00 AX 0 0 4
[ 4] .rodata PROGBITS 00002f10 002f10 000f8c 00 A 0 0 16
[ 5] .stack PROGBITS 1ffff0c0 003e9c 003f40 00 W 0 0 4
[ 6] .bss NOBITS 1ffff0c0 000000 000000 00 WA 0 0 4
[ 7] .data PROGBITS 1ffff0c0 007ddc 000000 00 WA 0 0 4
[ 8] .ARM.attributes ARM_ATTRIBUTES 00000000 007ddc 00002c 00 0 0 1
[ 9] .symtab SYMTAB 00000000 007e08 001140 10 10 209 4
[10] .strtab STRTAB 00000000 008f48 0012c5 00 0 0 1
[11] .shstrtab STRTAB 00000000 00a20d 000068 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
y (purecode), p (processor specific)
But for some reason the flash_configuration section ends up on the top of the binary, in the first 128 bits:

Instead of in the 0x400 region:
Here is the link to the repo with the code if you want to take a look.
Ok, I understand. In the lab01.elf.txt file that you've linked at the end of your first message there is no .flash_protect section, that is why I thought you don't have it. Now I see that everything is working as it should. If you look at documentation for objcopy command you can see this text:
The memory dump will start at the load address of the lowest section copied into the output file.
Your first section is located at address 0x400 so your .bin file also starts at 0x400. That's why you see your values as first bytes in the file. This is intended behavior.
But why do you need a bin file? If you want to use it for flashing your chip, please consider using elf or hex formats instead, because they do preserve such address information.
Thanks for the help so far. The lowest section would be the interrupts which go from 0x0 to 0x400, would it now?
VECTORS (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400
#[link_section = ".vector_table.interrupts"]
#[used]
static INTERRUPTS: [extern "C" fn(); 20] = [default_handler; 20];
extern "C" fn default_handler() {
asm::bkpt();
}
I can't flash an ELF file. I'm using the "drag and drop" method, which allows me to just drag and drop the file to the board mounted as an USB mass storage device. However, it only takes bin files. Also all the examples I could find use bin files, such as https://os.mbed.com/platforms/KL25Z/#downloading-a-program .
I'm using this method because it is the easiest (or so I thought haha) and prevents me from flashing a bin file setting the flash_security bits (the bits at 0x400). Setting security bits could make the flash impossible to erase (and so bricking the board).
I took a lot of inspiration from https://github.com/0xc0170/frdm-kl25z-rust .
I didn't manage to compile that project, but the Makefile there uses arm-none-eabi-objcopy the same way I'm using.
Have you tried to use _stext? I know that some people have it for the purpose of not flashing the Flash memory that's located right after the vector table (some uCs store configuration stuff in that section).
Hello japaric.
I looked into it, but I do need to flash that memory with the right bits, I can't skip them. If I don't it's going to be filled with 0s and that is going to be interpreted as setting the security bits to 0, which could brick the board.
The lowest section would be the interrupts which go from 0x0 to 0x400, would it now?
Well, here is your problem. If you look closely at this table:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 2] .vector_table PROGBITS 00000410 000410 000090 00 A 0 0 4
You can see that your vectors are placed at address 410 and not at 0. This happens because default liker script is using region FLASH for both vectors and code, and you've placed the FLASH region at address 410.
But this is easy to fix, just place the FLASH region at address 0, and use _stext symbol to move the code, as @japaric suggested. Your memory.x file should look like this:
MEMORY
{
FLASH : ORIGIN = 0x00000000, LENGTH = 128K
RAM : ORIGIN = 0x1FFFF0C0, LENGTH = 16K - 0xC0
}
SECTIONS
{
.flash_protect 0x400 :
{
LONG(0xFFFFFFFF);
LONG(0xFFFFFFFF);
LONG(0xFFFFFFFF);
LONG(0xFFFFFFFE);
} > FLASH
}
_stext = 0x410;
It worked!! Awesome!!
Thank you very much for the help!
Sorry for reviving an old issue but was trying out above suggestion and got:
error: linking with `rust-lld` failed: exit status: 1
|
...
= note: rust-lld: error: unable to place section .vector_table at file offset [0xFFFFFFFFFFFFFCF4, 0xFFFFFFFFFFFFFDB3]; check your linker script for overflows
rust-lld: error: unable to place section .text at file offset [0xFFFFFFFFFFFFFDB4, 0x5B]; check your linker script for overflows
rust-lld: error: section .rodata file range overlaps with .flash_protect
>>> .rodata range is [0x5C, 0x1A3]
>>> .flash_protect range is [0xF4, 0x103]
rust-lld: error: section .rodata virtual address range overlaps with .flash_protect
>>> .rodata range is [0x368, 0x4AF]
>>> .flash_protect range is [0x400, 0x40F]
rust-lld: error: section .rodata load address range overlaps with .flash_protect
>>> .rodata range is [0x368, 0x4AF]
>>> .flash_protect range is [0x400, 0x40F]
error: could not compile `pinscape-rust` (bin "pinscape-rust") due to previous error
Any hints on solving this?
@francisdb please share your full memory.x file, it's hard to tell from an error message
MEMORY
{
FLASH : ORIGIN = 0x00000000, LENGTH = 128K
RAM : ORIGIN = 0x1FFFF0C0, LENGTH = 16K - 0xC0
}
SECTIONS
{
.flash_protect 0x400 :
{
LONG(0xFFFFFFFF);
LONG(0xFFFFFFFF);
LONG(0xFFFFFFFF);
LONG(0xFFFFFFFE);
} > FLASH
}
_stext = 0x410;
@francisdb I just took this repo, cloned it, put your code in the memory.x and compiled and there is no issue. Can you please clarify any additional configuration I should do to reproduce this ?
Thanks @pftbest for looking into this
This issue happens only when switching .cargo/config.toml to
target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+As I understood the FRDM-KL25Z runs an Arm® Cortex®-M0+ Core
@francisdb Ok, so what I found out is that lld really doesn't like gaps between the sections. On v7m the .vector table ends at 0x400 so there is no gap, but on v6m it ends at 0xC0 instead, there is a gap from 0xC0 to 0x400. To work around this you can start your section at 0xC0 and then manually move the dot within that section to 0x400. This should do the trick:
SECTIONS
{
.flash_protect 0xC0 :
{
. = 0x400;
LONG(0xFFFFFFFF);
LONG(0xFFFFFFFF);
LONG(0xFFFFFFFF);
LONG(0xFFFFFFFE);
} > FLASH
}Thanks, confirming that fixes it!

