summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaximilian Brune <maximilian.brune@9elements.com>2023-07-08 18:15:28 +0200
committerMartin L Roth <gaumless@gmail.com>2023-09-05 16:08:42 +0000
commit7285c375fca1e16a9dececd375e5a3853a222042 (patch)
tree93ee492d61a02f8f49e8e144abd7a2cafa9e11de
parentc5c293cad118b4ef62a63e966701e04f2e0ebc04 (diff)
Documentation/rmodules.md: Add rmodule Documentation
Signed-off-by: Maximilian Brune <maximilian.brune@9elements.com> Change-Id: I97cd3030cd660a86295257caf723c9f517bed146 Reviewed-on: https://review.coreboot.org/c/coreboot/+/76383 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin L Roth <gaumless@gmail.com>
-rw-r--r--Documentation/rmodules.md81
1 files changed, 81 insertions, 0 deletions
diff --git a/Documentation/rmodules.md b/Documentation/rmodules.md
new file mode 100644
index 0000000000..520d184ddc
--- /dev/null
+++ b/Documentation/rmodules.md
@@ -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.