2021-01-14 03:19 AM
(since I am getting "Error while parsing Rich Text Content" in the saved post all the time, even though in the EDITOR everything renders just fine, I dumped the text in there without nice formatting)
-------------------------------------------------------------
I have a bootloader and app project in one CubeIDE workspace, for a STM32F0 target.
I added a linker script section (see below, ".buildinfo") to put some info into, also including the CRC and size of the firmware app image, so that the bootloader can check it when it's in flash.
I am also trying to get this to flash all in one go (loader, app with info section) for debugging from CubeIDE, which is why I am now trying to go the .elf route and ditch my previous "tack header onto .bin file" approach.
So I would manipulate the ELF file as post build step, and re-generate the .bin, too, with a call to objcopy on the modified elf.
I am using a library (ELFIO) to parse the .elf file, and I see the sections further below.
While I looked for information about what parts of the .elf go into the .bin, I alas found no single document that describes exactly that. I found some scattered info, like that linked below, and drew some, possibly erroneous, conclusions.
Now, to determine the size of the wouldbe .bin file from only info out of the .elf file, I am summing this:
This results in the same size as the currently generated .bin has.
But: Is this correct?.
This was all a bit of guesswork, and I especially don't know why e.g. the .data section's address is given as out of the flash range (that's why I check for addr!=0 instead of "outside flash range"). Oh, and I also don't know why there are even sections with address=0.
References:
ELF sections
https://www.tortall.net/projects/yasm/manual/html/objfmt-elf-section.html
ARM specific sectrions, p. 22, s. 5.3.2
https://static.docs.arm.com/ihi0044/g/aaelf32.pdf
Section Headers:
[ Nr ] Type Addr Size ES Flg Lk Inf Al Name
[ 0] NULL 00000000 00000000 00 00 000 00
[ 1] PROGBITS 08008080 000000bc 00 A 00 000 01 .isr_vector
[ 2] PROGBITS 0800813c 00000040 00 A 00 000 04 .buildinfo
[ 3] PROGBITS 0800817c 00013268 00 AX 00 000 04 .text
[ 4] PROGBITS 0801b3e4 00004c44 00 A 00 000 04 .rodata
[ 5] PROGBITS 08020028 00000000 00 W 00 000 01 .ARM.extab
[ 6] ? (0x70000001) 08020028 00000008 00 A 03 000 04 .ARM
[ 7] PREINIT_ARRAY 08020030 00000000 04 WA 00 000 01 .preinit_array
[ 8] INIT_ARRAY 08020030 00000020 04 WA 00 000 04 .init_array
[ 9] FINI_ARRAY 08020050 0000000c 04 WA 00 000 04 .fini_array
[ 10] PROGBITS 200000c0 00000134 00 WA 00 000 04 .data
[ 11] NOBITS 200001f8 000018e0 00 WA 00 000 08 .bss
[ 12] NOBITS 20001ad8 00000600 00 WA 00 000 01 ._user_heap_stack
[ 13] ? (0x70000003) 00000000 00000028 00 00 000 01 .ARM.attributes
[ 14] PROGBITS 00000000 0006e259 00 00 000 01 .debug_info
[ 15] PROGBITS 00000000 00011f5e 00 00 000 01 .debug_abbrev
[ 16] PROGBITS 00000000 00002ab8 00 00 000 08 .debug_aranges
[ 17] PROGBITS 00000000 000027d0 00 00 000 08 .debug_ranges
[ 18] PROGBITS 00000000 00023d0c 00 00 000 01 .debug_macro
[ 19] PROGBITS 00000000 00030c90 00 00 000 01 .debug_line
[ 20] PROGBITS 00000000 00094f6e 01 00 000 01 .debug_str
[ 21] PROGBITS 00000000 00000053 01 00 000 01 .comment
[ 22] PROGBITS 00000000 0000a680 00 00 000 04 .debug_frame
[ 23] SYMTAB 00000000 0000c5d0 10 18 970 04 .symtab
[ 24] STRTAB 00000000 0000bdca 00 00 000 01 .strtab
[ 25] STRTAB 00000000 00000115 00 00 000 01 .shstrtab
2021-01-14 03:49 AM
TEST:
List:
Okay.
Why is the letter combination of S, H, T replaced with asterisks?
Are we a bit over zealous with language policing, ST?
But that's apparently not what caused the parsing error.
I also tried to improve the formatting again and it is similar to where I started from, but now it works. Funny.
2021-01-14 05:36 AM
You can extract explicitly sections from .elf into .bin in that particular step, ie. using -j switch. Read objcopy/binutils manual. You may need to extract the "usual" parts, then the additional ones, and then merge them. It's better to work with .hex rather than .bit; the former can then be post-processed e.g. using srecord.
JW
2021-01-14 08:28 AM
Since I need to put a CRC of the image into the .elf file, which is required to use also for upload/debug, it seems to make sense to modify my program that calculates the CRC to now do it on the .elf instead on the .bin, and insert that info back into the .elf.
I just wasn't sure which sections exactly, and how, go into the .bin file (the naked file that e.g. also the STLink util writes as-is to the flash).
I have now written a file where I put all the sections I listed above after another, in the sequence they appeared, and compared it with the toolchain-generated .bin file in a hex editor. They match. So it looks good so far.
But I don't know that what I do is formally correct, and whether, maybe, if any part of the project setup ever changes, my process stops producing correct files because some case is not covered in my program.
2021-01-14 02:45 PM
@Community member Bin files are very easy to patch and hack. It is easier to add your CRC and stuff to .bin files after conversion than to .elf files.
You probably wish the latter so that you can debug in the IDE.
My solution for this is having a "debug" version of bootloader that allows "raw" images, right as the debugger loads them.
With this approach I don't care about structure of elf files at all, and do not need extra post-build steps which can go wrong.
> I especially don't know why e.g. the .data section's address is given as out of the flash range
Ah. The GNU link script and startup code are cleverly designed so that a typical program image is one continuous chunk in ROM (flash),
This results in small .bin files even if .data is in RAM and its address is far away from code address.
Initialized data is stored next to code in the image. The startup routine copies it from flash to its runtime address in RAM.
Other compiles (Keil, IAR...) do a similar thing.
-- pa
2021-01-14 03:04 PM
I use the Program Header PT_LOAD records to determine what's loaded, ie real PROGBITS rather than assorted noise.
If you have multiple memory regions you'll need/want to sum or sign them separately.
ELFArm Copyright (C) C Turvey 1997-2011
N25Q128A_STM32F746G-DISCO.stldr
e_type 0002 (ET_EXEC)
e_machine 0028 (EM_ARM)
e_version 00000001
e_entry 200012B5
e_phoff 00025C20
e_shoff 00025C60
e_flags 05000016 (EF_ARM_EABI_VER5)
e_ehsize 0034
e_phentsize 0020
e_phnum 0002
e_shentsize 0028
e_shnum 0011
e_shstrndx 0001
Program Header #0
p_type 00000001 (PT_LOAD)
p_offset 00000034
p_vaddr 20000004
p_paddr 20000004
p_filesz 00001C51
p_memsz 00001C51
p_flags 00000007 (RWX)
p_align 00000004
Program Header #1
p_type 00000001 (PT_LOAD)
p_offset 00001C88
p_vaddr 20001C58
p_paddr 20001C58
p_filesz 000000C8
p_memsz 000000C8
p_flags 00000004 (R--)
p_align 00000004
Section Header #0
sh_name 00000000 ()
sh_type 00000000 (***_NULL)
sh_flags 00000000 (---)
sh_addr 00000000
sh_offset 00020E2C
sh_size 00000000
sh_link 00000000
sh_info 00000000
sh_addralign 00000004
sh_entsize 00000000
Section Header #1
sh_name 00000001 (.shstrtab)
sh_type 00000003 (***_STRTAB)
sh_flags 00000000 (---)
sh_addr 00000000
sh_offset 00020E2C
sh_size 000000BB
sh_link 00000000
sh_info 00000000
sh_addralign 00000004
sh_entsize 00000000
Section Header #2
sh_name 0000000B (.strtab)
sh_type 00000003 (***_STRTAB)
sh_flags 00000000 (---)
sh_addr 00000000
sh_offset 00020EE8
sh_size 00002898
sh_link 00000000
sh_info 00000000
sh_addralign 00000004
sh_entsize 00000000
Section Header #3
sh_name 00000013 (.symtab)
sh_type 00000002 (***_SYMTAB)
sh_flags 00000000 (---)
sh_addr 00000000
sh_offset 00023780
sh_size 000024A0
sh_link 00000002
sh_info 000001C1
sh_addralign 00000004
sh_entsize 00000010
Section Header #4
sh_name 0000001B (P1 ro)
sh_type 00000001 (***_PROGBITS)
sh_flags 00000007 (WAX)
sh_addr 20000004
sh_offset 00000034
sh_size 00001C51
sh_link 00000000
sh_info 00000000
sh_addralign 00000004
sh_entsize 00000001
Section Header #5
sh_name 00000021 (P2 ro)
sh_type 00000001 (***_PROGBITS)
sh_flags 00000002 (-A-)
sh_addr 20001C58
sh_offset 00001C88
sh_size 000000C8
sh_link 00000000
sh_info 00000000
sh_addralign 00000004
sh_entsize 00000001
Section Header #6
sh_name 00000027 (.debug_abbrev)
sh_type 00000001 (***_PROGBITS)
sh_flags 00000000 (---)
sh_addr 00000000
sh_offset 00001D50
sh_size 000005F0
sh_link 00000000
sh_info 00000000
sh_addralign 00000000
sh_entsize 00000001
...