RFC: generating a header using the linker (ASCII, ASCIZ commands)
Ulf Samuelsson
binutils@emagii.com
Mon Feb 13 16:04:31 GMT 2023
Den 2023-02-13 kl. 15:11, skrev Nick Clifton:
> Hi Ulf,
>
>>> From the sound of what you have written below it would be
>>> easier to use the assembler to create the header
>
>> One of the problems is time of build.
>> The header should contain the time when things are linked together,
>> not when things are compiled.
>>
>> Another is that one of the fields is the size of the application
>> which is only known at link time.
>>
>> Doing things in the linker seems to be the cleanest way.
>>
>> We would probably have the header is in a separate file which is
>> included in the linker script.
>
> If you need to compute information in the header based upon the
> actual linked executable then you will not be able to do so from
> inside a linker script. (Well not without modifying the linker,
> and I am trying to avoid that).
>
> But - what you can do is post-process the linked file to extract
> the information you want, create a separate file containing the
> header constructed from this information, and then insert the
> header into the executable, without relinking it. (I am thinking
> of objcopy's --add-section command line option here).
>
> Alternatively you could link with a dummy header that is basically
> empty and then use a tool like GNU Poke[1] to insert the necessary
> bytes and strings afterwards.
This is what a typical header looks like:
header:
QUAD(TAG1) // 0
ECC: QUAD(ECC(SYNDROME, START_OF_ECC, .end_of_text)) // 8
START_OFF_ECC:
BUILDTIME:
QUAD(SECONDS_SINCE_1970) // 16
ENTRY: LONG(program_entry) // 24
SIZE: LONG(.end_of_text - .start_of_text) // 28
BYTE(VERSION1) // 32
BYTE(VERSION2) // 33
BYTE(VERSION3) // 34
BYTE(VERSION3) // 35
LONG(0) // 36
LONG(0) // 40
LONG(0) // 44
APPLICATION:
ASCII 16, "MyApp" // 48
ASCII 32, "A special app" // 64
ASCII 32, "With Info" // 96
HELP
ASCII 120 "No help available" // 120
QUAD(TAG2) // 248
Total Size = 265 byte
Most of the header info is part of the linker file.
The linker needs to compute:
ECC:
BUILDTIME:
ENTRY:
SIZE:
===
We already discussed ideas for ECC.
For buildtime, we currently added an include file which we create during
the linking process.
To have a BUILDTIME directive that generates a 64-bit word with "seconds
since 1970-01-01 00:00"
does not seem to be very difficult - at least on linux.
Parse the call and get the |__time64_t |seconds from the OS.
ENTRY and SIZE is supported right now in the linker.
Best Regards
Ulf Samuelsson
>
> [1] http://www.jemarch.net/poke
>
>
>> Assume you have the following flash sectors.
>>
>> * 64kB (65536 bytes)
>> * 64kB (65536 bytes)
>> * 128kB
>> * n x 256kB
>>
>> The bootloader resides in the first 64 kB sector and the application
>> starts in the second 64kB sector.
>>
>> If the application <= 65536 bytes, the section should be 64kB and
>> should be filled with a FILL value
>>
>> If the application is 65540 bytes, the section should be 64kB+128kB
>> and should be filled with a FILL value
>
> Ah yes. This is a known problem for the linker. It does not have a
> mechanism
> to distribute section(s) across multiple memory regions, using one
> until it is full
> and then switching to another.
I don't think we need to distribute sections amongs multiple regions.
I just need to say that the PC should be aligned to the next 64kB
boundary and it
should be filled with my fill value.
Then I need to check the PC and if it is not at the end of a flash segment,
I want to add an additional BYTE(0xFF) and again align to the next segment.
The following would handle application up to 512kB.
. = ALIGN(64kB)
if (. == 0x30000)
BYTE(0xFF)
. = ALIGN(64kB)
end if
if (. == 0x50000)
BYTE(0xFF)
. = ALIGN(64kB)
end if
if (. == 0x60000)
BYTE(0xFF)
. = ALIGN(64kB)
end if
if (. == 0x70000)
BYTE(0xFF)
. = ALIGN(64kB)
end if
>
> I am sorry, but I do not have an easy workaround for you. If you are
> able to try
> multiple links, you could start with one that just uses the smallest
> memory configuration
> first, and if that fails move up to bigger configurations, possibly
> with different
> assignments of sections to memory regions afterwards.
>
>
>> Would you consider adding ielftools to binutils?
>
> I would prefer to leave it as a separate project for now. I am worried
> about bringing in a tool that will only be of use to a very small
> audience
> (maybe just you ?) and having to maintain it. Of course if you can
> persuade
> more people to request that the sources be integrated then I can take
> abother
> look at the issue...
>
>> Note that if the linker can call an external tool to compute the CRC
>> based on the extracted text segment, and insert that into the
>> resulting ELF file.
>> then this is superior to running a utility afterwards.
>
> Actually -- there might be a way to do this: A linker plugin. The
> linker already
> has the architecture to support plugins, and you could create a new
> one which would
> scan the text section, compute a CRC and then insert the value into a
> header in the
> linked image...
>
OK, tell me more!
> Cheers
> Nick
>
>
More information about the Binutils
mailing list