forked from coreboot/coreboot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Documentation/rmodules.md: Add rmodule Documentation
Signed-off-by: Maximilian Brune <[email protected]> Change-Id: I97cd3030cd660a86295257caf723c9f517bed146 Reviewed-on: https://review.coreboot.org/c/coreboot/+/76383 Tested-by: build bot (Jenkins) <[email protected]> Reviewed-by: Martin L Roth <[email protected]>
- Loading branch information
1 parent
c5c293c
commit 7285c37
Showing
1 changed file
with
81 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# Relocatable Modules (rmodules) | ||
|
||
Relocatable modules are currently only used on x86. Relocatable | ||
modules are executables. Exectuables which can be executed anywhere in | ||
memory. Anywhere means that the module does not need to be executed | ||
at a defined memory address which is known at build/link time. For | ||
coreboot stages like bootblock and romstage it is known at build | ||
time at which addresses they are executed. For some exectuables it | ||
is however not known at which specific address they are executed in | ||
runtime (for example postcar and ramstage). Relocateable modules | ||
usually allocate the space for the modules just before they are | ||
supposed to be executed. After enough space is allocated, CBMEM will | ||
return the location of the allocated space. Now the relocation can be | ||
done by fixing up all relocation entries in the relocatable module | ||
based on the location of the binary (which was returned by CBMEM | ||
at runtime). | ||
|
||
# Implementation Details | ||
|
||
## build time | ||
|
||
At build time the rmodtool (util/cbfstool/rmodtool.c) is used to | ||
create relocatable modules. The rmodtool basically takes an ELF | ||
file as an input and writes an ELF as output. It basically does | ||
a simple conversion from one ELF file to another slighty changed | ||
ELF file. First the tool makes sure that the ELF file fits a few | ||
requirements. For example there can only be one segment (loadable | ||
program header) in the input ELF file. After that it goes through | ||
the ELF relocation table and takes any entry that applies to the one | ||
segment we want to load at runtime. The rmodtool will then write all | ||
these relocation entires in a new ELF section called ".reloc". After | ||
that the ELF relocation table will be cleared. | ||
|
||
One can split the rmodules in two different kinds: | ||
1. coreboot stages (postcar, ramstage) | ||
2. simple binaries (smm, smmstub, sipi\_vector) | ||
|
||
They are actually handled the same by the build system and only differ | ||
in the fact, that they are either coreboot stages or they are not. | ||
|
||
In the end the ELF files will have three different ELF sections, | ||
which are all created by the rmodtool. | ||
1. relocation header (.header) | ||
2. program (.program) | ||
3. relocation entries (.relocs) | ||
|
||
## runtime | ||
|
||
Either rmodule\_load (lib/rmodule.c) is used directly or through the | ||
rmodule\_stage\_load (lib/rmodule.c) wrapper. It is used to load the | ||
stages (postcar and ramstage) or small programs like (sipi\_vector, | ||
smm, smmstub) into memory before jumping to them. In the case of a | ||
coreboot stage, CBMEM is used to allocate space for the stage in memory | ||
via the rmodule\_cbfs\_allocater (lib/rmodule.c). At this point the | ||
location of the stage in memory is known and all relocation (address | ||
fixups) need to be done now. This is basically just a simple loop that | ||
goes through each relocation entry. Each relocation entry is just an | ||
address pointing to a location that needs relocation. The relocation | ||
itself is just a simple addition, that adds an offset from where the | ||
image was "supposed" to be at link time, to where it is now relocated. | ||
|
||
## module\_parameters | ||
|
||
module\_parameters is a section inside the rmodule ELF file. Its | ||
basically a way to pass runtime information to an rmodule | ||
before jumping to it. The caller will use rmodule\_parameters() | ||
(lib/rmodule.c) to get the runtime address of the module\_parameters | ||
and the callee (the rmodule itself) usually appends the section to | ||
specific types via compiler attributes. For example: | ||
``` | ||
static const | ||
volatile __attribute((aligned(4), __section__(".module_parameters"))) | ||
struct smm_runtime smm_runtime; | ||
``` | ||
|
||
# x86 why rmodules | ||
//TODO | ||
x86: postcar and ramstage cannot conflict with payload regarding | ||
memory placement. Therefore payload location is usually fixed and | ||
postcar/ramstage can be placed at a location in memory that is | ||
figured out at runtime. |