Martin L Roth has submitted this change. ( https://review.coreboot.org/c/coreboot/+/76383?usp=email )
Change subject: Documentation/rmodules.md: Add rmodule Documentation ......................................................................
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 --- A Documentation/rmodules.md 1 file changed, 81 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Martin L Roth: Looks good to me, approved
diff --git a/Documentation/rmodules.md b/Documentation/rmodules.md new file mode 100644 index 0000000..520d184 --- /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.