Reputation: 2734
According to the GNU documentation for ld
, a NOLOAD
section works as following:
The `(NOLOAD)' directive will mark a section to not be loaded at run time. The linker will process the section normally, but will mark it so that a program loader will not load it into memory.
Now, regarding to the program loader, accordign to wikipedia:
Embedded systems typically do not have loaders, and instead, the code executes directly from ROM. In order to load the operating system itself, as part of booting, a specialized boot loader is used.
Then, what exactly a NOLOAD
section does for FW / embedded software?
Upvotes: 10
Views: 15132
Reputation: 2734
I have done several experiments, so I will add an answer in the specific context of embedded software, in particular in absence of loaders (included flash tools with such functionality). This is my understanding after the experiments I have done, but if anything is wrong I will be more than happy to edit the answer.
It's true that NOLOAD
will mark a section so that 'the loader' knows that it must not load it into memory. Something similar will happen for flashing tools that receive an .elf
file as an input, therefore, to some extent, act as loaders.
However, there are many cases in embedded software in which a loader is not present, for instance if the target device allows to update the firmware only with raw binary files, and it just copies the raw data at a particular address and nothing else. In this cases, NOLOAD
will be useful to avoid making the raw binary file unnecessarily big: it will prevent a section to be added to the final binary file when it's not desirable.
Use cases in which it would not be desirable:
.bss
, but it's not .bss
, in which case NOLOAD
will need to be set explicitly. Of course, this will need to be initialized to 0 or whatever constant value by the startup script.Notice that the NOLOAD
section will still be present in the .elf
file (it won't be marked as LOAD
though), but it should be removed by objcopy
when generating the raw binary file. There is one exception to this though: objcopy
cannot 'remove' a section in between another two because it needs to keep the memory map somehow. For instance, having sections A B C, NOLOAD
won't work on B, because objcopy
will need to fill B
with zeros to keep the offset of section C
as expected. However, if C
is NOLOAD
and it's the last (potentially loadable) section, then it can be removed from the final binary image.
Another special case I have observed is the .bss
section. This section is always treated (at least by my version of riscv64-uknown-elf
toolchain) as NOLOAD
, regardless if the linker script specifies it or not.
In summary, the uses of NOLOAD
for embedded systems that do not use a loader are: to keep raw binary images smaller, or to not overwrite memory regions (usually flash) that one wants to leave with the value they had before the firmware update process started.
What NOLOAD
cannot do if no loader is present, a.k.a. FW is updated as raw binary files, is to avoid a section to be put in a raw binary file if that section is in between another two that do need to be loaded. In such case, all the the NOLOAD
sections will need to be moved to the end of the loadable memory.
As a side note, for the case of avoiding to overwrite memory, as far as I can see that could be worked out by not declaring that section at all. If symbols in that section need to be referenced from the source code, just declare those symbols at the right addresses.
Upvotes: 4
Reputation: 2718
The NOLOAD
section defines a section that is required to link the program properly but must not be loaded to memory. For example you may need to link your program with some code located in ROM, so you tell the linker to mark the code in ROM as NOLOAD
. Then the tool that will load the program (a debugger, an OS or whatever) will not load this part of the code.
Upvotes: 8